From b2ce6db229c4bdc1aeee29f5ade9c7aae54dfded Mon Sep 17 00:00:00 2001 From: zhengbli Date: Thu, 9 Jul 2015 14:45:39 -0700 Subject: [PATCH 1/8] Add API for project level GetErr --- src/server/editorServices.ts | 2 +- src/server/protocol.d.ts | 27 ++++++++++++++++- src/server/session.ts | 59 ++++++++++++++++++++++++++++++++++-- 3 files changed, 83 insertions(+), 5 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 91d400ff263..1b9ea292357 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -304,7 +304,7 @@ namespace ts.server { return this.projectService.openFile(filename, false); } - getFileNameList() { + getFileNames() { let sourceFiles = this.program.getSourceFiles(); return sourceFiles.map(sourceFile => sourceFile.fileName); } diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index 017a8c1d81a..a40ca1f1318 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -116,7 +116,7 @@ declare namespace ts.server.protocol { /** * The list of normalized file name in the project, including 'lib.d.ts' */ - fileNameList?: string[]; + fileNames?: string[]; } /** @@ -854,6 +854,31 @@ declare namespace ts.server.protocol { export interface SignatureHelpResponse extends Response { body?: SignatureHelpItems; } + + /** + * Arguments for geterrForProject request. + */ + export interface GeterrForProjectRequestArgs { + /** + * the file requesting project error list + */ + file: string; + + /** + * Delay in milliseconds to wait before starting to compute + * errors for the files in the file list + */ + delay: number; + } + + /** + * GeterrForProjectRequest request; value of command field is + * "geterrForProject". It works similarly with 'Geterr', only + * it request for every file in this project. + */ + export interface GeterrForProjectRequest extends Request { + arguments: GeterrForProjectRequestArgs + } /** * Arguments for geterr messages. diff --git a/src/server/session.ts b/src/server/session.ts index c95b1a7cc1b..c35cdedffe9 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -86,6 +86,7 @@ namespace ts.server { export const Format = "format"; export const Formatonkey = "formatonkey"; export const Geterr = "geterr"; + export const GeterrForProject = "geterrForProject"; export const NavBar = "navbar"; export const Navto = "navto"; export const Occurrences = "occurrences"; @@ -344,15 +345,15 @@ namespace ts.server { } getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo { - fileName = ts.normalizePath(fileName) - let project = this.projectService.getProjectForFile(fileName) + fileName = ts.normalizePath(fileName); + let project = this.projectService.getProjectForFile(fileName); let projectInfo: protocol.ProjectInfo = { configFileName: project.projectFilename } if (needFileNameList) { - projectInfo.fileNameList = project.getFileNameList(); + projectInfo.fileNames = project.getFileNames(); } return projectInfo; @@ -836,6 +837,51 @@ namespace ts.server { })); } + getDiagnosticsForProject(delay: number, fileName: string) { + let { configFileName, fileNames: fileNamesInProject } = this.getProjectInfo(fileName, true); + // No need to analyze lib.d.ts + fileNamesInProject = fileNamesInProject.filter((value, index, array) => value.indexOf("lib.d.ts") < 0); + + // Sort the file name list to make the recently touched files come first + let highPriorityFiles: string[] = []; + let mediumPriorityFiles: string[] = []; + let lowPriorityFiles: string[] = []; + let veryLowPriorityFiles: string[] = []; + let normalizedFileName = ts.normalizePath(fileName); + let project = this.projectService.getProjectForFile(normalizedFileName); + for (let fileNameInProject of fileNamesInProject) { + if (this.getCanonicalFileName(fileNameInProject) == this.getCanonicalFileName(fileName)) + highPriorityFiles.push(fileNameInProject); + else { + let info = this.projectService.getScriptInfo(fileNameInProject); + if (!info || !info.isOpen) { + if (fileNameInProject.indexOf(".d.ts") > 0) + veryLowPriorityFiles.push(fileNameInProject); + else + lowPriorityFiles.push(fileNameInProject); + } + else + mediumPriorityFiles.push(fileNameInProject); + } + } + + fileNamesInProject = highPriorityFiles.concat(mediumPriorityFiles).concat(lowPriorityFiles).concat(veryLowPriorityFiles); + + if (fileNamesInProject.length > 0) { + let checkList = fileNamesInProject.map((fileName: string) => { + let normalizedFileName = ts.normalizePath(fileName); + return { fileName: normalizedFileName, project }; + }); + this.updateErrorCheck(checkList, this.changeSeq, (n) => n == this.changeSeq, delay); + } + } + + getCanonicalFileName(fileName: string) { + let name = this.host.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(); + this.logger.info(ts.normalizePath(name)); + return ts.normalizePath(name); + } + exit() { } @@ -919,6 +965,13 @@ namespace ts.server { responseRequired = false; break; } + case CommandNames.GeterrForProject: { + this.logger.info(request.arguments); + let { file, delay } = request.arguments; + response = this.getDiagnosticsForProject(delay, file); + responseRequired = false; + break; + } case CommandNames.Change: { var changeArgs = request.arguments; this.change(changeArgs.line, changeArgs.offset, changeArgs.endLine, changeArgs.endOffset, From bbf1105c4657db4062c1267e85aafd55c5574d41 Mon Sep 17 00:00:00 2001 From: Zhengbo Li Date: Mon, 13 Jul 2015 14:01:03 -0700 Subject: [PATCH 2/8] Remove log statements --- src/server/protocol.d.ts | 2 +- src/server/session.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index a40ca1f1318..a68ffe79864 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -856,7 +856,7 @@ declare namespace ts.server.protocol { } /** - * Arguments for geterrForProject request. + * Arguments for GeterrForProject request. */ export interface GeterrForProjectRequestArgs { /** diff --git a/src/server/session.ts b/src/server/session.ts index c35cdedffe9..0df154eadf1 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -878,7 +878,6 @@ namespace ts.server { getCanonicalFileName(fileName: string) { let name = this.host.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(); - this.logger.info(ts.normalizePath(name)); return ts.normalizePath(name); } From 6ae543bf5451dcbba61836fe3147a6014095a20d Mon Sep 17 00:00:00 2001 From: Zhengbo Li Date: Mon, 13 Jul 2015 15:50:06 -0700 Subject: [PATCH 3/8] Remove unnecessary checking --- src/server/session.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/session.ts b/src/server/session.ts index 0df154eadf1..2efe75ee53f 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -854,7 +854,7 @@ namespace ts.server { highPriorityFiles.push(fileNameInProject); else { let info = this.projectService.getScriptInfo(fileNameInProject); - if (!info || !info.isOpen) { + if (!info.isOpen) { if (fileNameInProject.indexOf(".d.ts") > 0) veryLowPriorityFiles.push(fileNameInProject); else From 8f30ad17ed6654053118a9fc031deced3296fe13 Mon Sep 17 00:00:00 2001 From: Zhengbo Li Date: Mon, 13 Jul 2015 16:26:19 -0700 Subject: [PATCH 4/8] Fix tests --- src/harness/fourslash.ts | 2 +- src/server/client.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index c374f8add60..0d03f7d6236 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1882,7 +1882,7 @@ module FourSlash { ); assert.equal( expected.join(","), - actual.fileNameList.map( file => { + actual.fileNames.map( file => { return file.replace(this.basePath + "/", "") }).join(",") ); diff --git a/src/server/client.ts b/src/server/client.ts index e4a524dd210..9a6fbaa3a77 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -183,7 +183,7 @@ namespace ts.server { return { configFileName: response.body.configFileName, - fileNameList: response.body.fileNameList + fileNames: response.body.fileNames }; } From 418369a13c0e9ee0add658cf4460935cb22edba6 Mon Sep 17 00:00:00 2001 From: Zhengbo Li Date: Mon, 13 Jul 2015 16:38:13 -0700 Subject: [PATCH 5/8] incorporate changes in master --- src/compiler/sys.ts | 16 ++- src/server/session.ts | 269 ++++++++++++++++++--------------------- src/services/services.ts | 1 + 3 files changed, 140 insertions(+), 146 deletions(-) diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 443c1c4789c..228b9516de1 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -29,6 +29,9 @@ namespace ts { declare var process: any; declare var global: any; declare var __filename: string; + declare var Buffer: { + new (str: string, encoding ?: string): any; + } declare class Enumerator { public atEnd(): boolean; @@ -267,10 +270,17 @@ namespace ts { args: process.argv.slice(2), newLine: _os.EOL, useCaseSensitiveFileNames: useCaseSensitiveFileNames, - write(s: string): void { + write(s: string): void { + var buffer = new Buffer(s, 'utf8'); + var offset: number = 0; + var toWrite: number = buffer.length; + var written = 0; // 1 is a standard descriptor for stdout - _fs.writeSync(1, s); - }, + while ((written = _fs.writeSync(1, buffer, offset, toWrite)) < toWrite) { + offset += written; + toWrite -= written; + } + }, readFile, writeFile, watchFile: (fileName, callback) => { diff --git a/src/server/session.ts b/src/server/session.ts index 2efe75ee53f..5873958d613 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -884,6 +884,131 @@ namespace ts.server { exit() { } + private handlers : Map<(request: protocol.Request) => {response?: any, responseRequired?: boolean}> = { + [CommandNames.Exit]: () => { + this.exit(); + return {}; + }, + [CommandNames.Definition]: (request: protocol.Request) => { + var defArgs = request.arguments; + return {response: this.getDefinition(defArgs.line, defArgs.offset, defArgs.file)}; + }, + [CommandNames.TypeDefinition]: (request: protocol.Request) => { + var defArgs = request.arguments; + return {response: this.getTypeDefinition(defArgs.line, defArgs.offset, defArgs.file)}; + }, + [CommandNames.References]: (request: protocol.Request) => { + var defArgs = request.arguments; + return {response: this.getReferences(defArgs.line, defArgs.offset, defArgs.file)}; + }, + [CommandNames.Rename]: (request: protocol.Request) => { + var renameArgs = request.arguments; + return {response: this.getRenameLocations(renameArgs.line, renameArgs.offset, renameArgs.file, renameArgs.findInComments, renameArgs.findInStrings)} + }, + [CommandNames.Open]: (request: protocol.Request) => { + var openArgs = request.arguments; + this.openClientFile(openArgs.file); + return {} + }, + [CommandNames.Quickinfo]: (request: protocol.Request) => { + var quickinfoArgs = request.arguments; + return {response: this.getQuickInfo(quickinfoArgs.line, quickinfoArgs.offset, quickinfoArgs.file)}; + }, + [CommandNames.Format]: (request: protocol.Request) => { + var formatArgs = request.arguments; + return {response: this.getFormattingEditsForRange(formatArgs.line, formatArgs.offset, formatArgs.endLine, formatArgs.endOffset, formatArgs.file)}; + }, + [CommandNames.Formatonkey]: (request: protocol.Request) => { + var formatOnKeyArgs = request.arguments; + return {response: this.getFormattingEditsAfterKeystroke(formatOnKeyArgs.line, formatOnKeyArgs.offset, formatOnKeyArgs.key, formatOnKeyArgs.file)}; + }, + [CommandNames.Completions]: (request: protocol.Request) => { + var completionsArgs = request.arguments; + return {response: this.getCompletions(completionsArgs.line, completionsArgs.offset, completionsArgs.prefix, completionsArgs.file)} + }, + [CommandNames.CompletionDetails]: (request: protocol.Request) => { + var completionDetailsArgs = request.arguments; + return {response: this.getCompletionEntryDetails(completionDetailsArgs.line,completionDetailsArgs.offset, + completionDetailsArgs.entryNames,completionDetailsArgs.file)} + }, + [CommandNames.SignatureHelp]: (request: protocol.Request) => { + var signatureHelpArgs = request.arguments; + return {response: this.getSignatureHelpItems(signatureHelpArgs.line, signatureHelpArgs.offset, signatureHelpArgs.file)} + }, + [CommandNames.Geterr]: (request: protocol.Request) => { + var geterrArgs = request.arguments; + return {response: this.getDiagnostics(geterrArgs.delay, geterrArgs.files), responseRequired: false}; + }, + [CommandNames.GeterrForProject]: (request: protocol.Request) => { + let { file, delay } = request.arguments; + return {response: this.getDiagnosticsForProject(delay, file), responseRequired: false}; + }, + [CommandNames.Change]: (request: protocol.Request) => { + var changeArgs = request.arguments; + this.change(changeArgs.line, changeArgs.offset, changeArgs.endLine, changeArgs.endOffset, + changeArgs.insertString, changeArgs.file); + return {responseRequired: false} + }, + [CommandNames.Configure]: (request: protocol.Request) => { + var configureArgs = request.arguments; + this.projectService.setHostConfiguration(configureArgs); + this.output(undefined, CommandNames.Configure, request.seq); + return {responseRequired: false} + }, + [CommandNames.Reload]: (request: protocol.Request) => { + var reloadArgs = request.arguments; + this.reload(reloadArgs.file, reloadArgs.tmpfile, request.seq); + return {responseRequired: false} + }, + [CommandNames.Saveto]: (request: protocol.Request) => { + var savetoArgs = request.arguments; + this.saveToTmp(savetoArgs.file, savetoArgs.tmpfile); + return {responseRequired: false} + }, + [CommandNames.Close]: (request: protocol.Request) => { + var closeArgs = request.arguments; + this.closeClientFile(closeArgs.file); + return {responseRequired: false}; + }, + [CommandNames.Navto]: (request: protocol.Request) => { + var navtoArgs = request.arguments; + return {response: this.getNavigateToItems(navtoArgs.searchValue, navtoArgs.file, navtoArgs.maxResultCount)}; + }, + [CommandNames.Brace]: (request: protocol.Request) => { + var braceArguments = request.arguments; + return {response: this.getBraceMatching(braceArguments.line, braceArguments.offset, braceArguments.file)}; + }, + [CommandNames.NavBar]: (request: protocol.Request) => { + var navBarArgs = request.arguments; + return {response: this.getNavigationBarItems(navBarArgs.file)}; + }, + [CommandNames.Occurrences]: (request: protocol.Request) => { + var { line, offset, file: fileName } = request.arguments; + return {response: this.getOccurrences(line, offset, fileName)}; + }, + [CommandNames.ProjectInfo]: (request: protocol.Request) => { + var { file, needFileNameList } = request.arguments; + return {response: this.getProjectInfo(file, needFileNameList)}; + }, + }; + addProtocolHandler(command: string, handler: (request: protocol.Request) => {response?: any, responseRequired: boolean}) { + if (this.handlers[command]) { + throw new Error(`Protocol handler already exists for command "${command}"`); + } + this.handlers[command] = handler; + } + + executeCommand(request: protocol.Request) : {response?: any, responseRequired?: boolean} { + var handler = this.handlers[request.command]; + if (handler) { + return handler(request); + } else { + this.projectService.log("Unrecognized JSON command: " + JSON.stringify(request)); + this.output(undefined, CommandNames.Unknown, request.seq, "Unrecognized JSON command: " + request.command); + return {responseRequired: false}; + } + } + onMessage(message: string) { if (this.logger.isVerbose()) { this.logger.info("request: " + message); @@ -891,149 +1016,7 @@ namespace ts.server { } try { var request = JSON.parse(message); - var response: any; - var errorMessage: string; - var responseRequired = true; - switch (request.command) { - case CommandNames.Exit: { - this.exit(); - responseRequired = false; - break; - } - case CommandNames.Definition: { - var defArgs = request.arguments; - response = this.getDefinition(defArgs.line, defArgs.offset, defArgs.file); - break; - } - case CommandNames.TypeDefinition: { - var defArgs = request.arguments; - response = this.getTypeDefinition(defArgs.line, defArgs.offset, defArgs.file); - break; - } - case CommandNames.References: { - var refArgs = request.arguments; - response = this.getReferences(refArgs.line, refArgs.offset, refArgs.file); - break; - } - case CommandNames.Rename: { - var renameArgs = request.arguments; - response = this.getRenameLocations(renameArgs.line, renameArgs.offset, renameArgs.file, renameArgs.findInComments, renameArgs.findInStrings); - break; - } - case CommandNames.Open: { - var openArgs = request.arguments; - this.openClientFile(openArgs.file); - responseRequired = false; - break; - } - case CommandNames.Quickinfo: { - var quickinfoArgs = request.arguments; - response = this.getQuickInfo(quickinfoArgs.line, quickinfoArgs.offset, quickinfoArgs.file); - break; - } - case CommandNames.Format: { - var formatArgs = request.arguments; - response = this.getFormattingEditsForRange(formatArgs.line, formatArgs.offset, formatArgs.endLine, formatArgs.endOffset, formatArgs.file); - break; - } - case CommandNames.Formatonkey: { - var formatOnKeyArgs = request.arguments; - response = this.getFormattingEditsAfterKeystroke(formatOnKeyArgs.line, formatOnKeyArgs.offset, formatOnKeyArgs.key, formatOnKeyArgs.file); - break; - } - case CommandNames.Completions: { - var completionsArgs = request.arguments; - response = this.getCompletions(completionsArgs.line, completionsArgs.offset, completionsArgs.prefix, completionsArgs.file); - break; - } - case CommandNames.CompletionDetails: { - var completionDetailsArgs = request.arguments; - response = - this.getCompletionEntryDetails(completionDetailsArgs.line,completionDetailsArgs.offset, - completionDetailsArgs.entryNames,completionDetailsArgs.file); - break; - } - case CommandNames.SignatureHelp: { - var signatureHelpArgs = request.arguments; - response = this.getSignatureHelpItems(signatureHelpArgs.line, signatureHelpArgs.offset, signatureHelpArgs.file); - break; - } - case CommandNames.Geterr: { - var geterrArgs = request.arguments; - response = this.getDiagnostics(geterrArgs.delay, geterrArgs.files); - responseRequired = false; - break; - } - case CommandNames.GeterrForProject: { - this.logger.info(request.arguments); - let { file, delay } = request.arguments; - response = this.getDiagnosticsForProject(delay, file); - responseRequired = false; - break; - } - case CommandNames.Change: { - var changeArgs = request.arguments; - this.change(changeArgs.line, changeArgs.offset, changeArgs.endLine, changeArgs.endOffset, - changeArgs.insertString, changeArgs.file); - responseRequired = false; - break; - } - case CommandNames.Configure: { - var configureArgs = request.arguments; - this.projectService.setHostConfiguration(configureArgs); - this.output(undefined, CommandNames.Configure, request.seq); - responseRequired = false; - break; - } - case CommandNames.Reload: { - var reloadArgs = request.arguments; - this.reload(reloadArgs.file, reloadArgs.tmpfile, request.seq); - responseRequired = false; - break; - } - case CommandNames.Saveto: { - var savetoArgs = request.arguments; - this.saveToTmp(savetoArgs.file, savetoArgs.tmpfile); - responseRequired = false; - break; - } - case CommandNames.Close: { - var closeArgs = request.arguments; - this.closeClientFile(closeArgs.file); - responseRequired = false; - break; - } - case CommandNames.Navto: { - var navtoArgs = request.arguments; - response = this.getNavigateToItems(navtoArgs.searchValue, navtoArgs.file, navtoArgs.maxResultCount); - break; - } - case CommandNames.Brace: { - var braceArguments = request.arguments; - response = this.getBraceMatching(braceArguments.line, braceArguments.offset, braceArguments.file); - break; - } - case CommandNames.NavBar: { - var navBarArgs = request.arguments; - response = this.getNavigationBarItems(navBarArgs.file); - break; - } - case CommandNames.Occurrences: { - var { line, offset, file: fileName } = request.arguments; - response = this.getOccurrences(line, offset, fileName); - break; - } - case CommandNames.ProjectInfo: { - var { file, needFileNameList } = request.arguments; - response = this.getProjectInfo(file, needFileNameList); - break; - } - default: { - this.projectService.log("Unrecognized JSON command: " + message); - this.output(undefined, CommandNames.Unknown, request.seq, "Unrecognized JSON command: " + request.command); - break; - } - } + var {response, responseRequired} = this.executeCommand(request); if (this.logger.isVerbose()) { var elapsed = this.hrtime(start); diff --git a/src/services/services.ts b/src/services/services.ts index 10e38f98613..c85c10dc411 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -4546,6 +4546,7 @@ namespace ts { if (hasKind(node.parent, SyntaxKind.GetAccessor) || hasKind(node.parent, SyntaxKind.SetAccessor)) { return getGetAndSetOccurrences(node.parent); } + break; default: if (isModifier(node.kind) && node.parent && (isDeclaration(node.parent) || node.parent.kind === SyntaxKind.VariableStatement)) { From efef7b30c10902a97109af90ac6224a071d171fa Mon Sep 17 00:00:00 2001 From: zhengbli Date: Thu, 16 Jul 2015 15:45:31 -0700 Subject: [PATCH 6/8] Update updateErrorCheck function --- src/server/session.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/server/session.ts b/src/server/session.ts index 5873958d613..3eea095d9d5 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -235,7 +235,7 @@ namespace ts.server { } updateErrorCheck(checkList: PendingErrorCheck[], seq: number, - matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200) { + matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200, requireOpen = true) { if (followMs > ms) { followMs = ms; } @@ -250,7 +250,7 @@ namespace ts.server { var checkOne = () => { if (matchSeq(seq)) { var checkSpec = checkList[index++]; - if (checkSpec.project.getSourceFileFromName(checkSpec.fileName, true)) { + if (checkSpec.project.getSourceFileFromName(checkSpec.fileName, requireOpen)) { this.syntacticCheck(checkSpec.fileName, checkSpec.project); this.immediateId = setImmediate(() => { this.semanticCheck(checkSpec.fileName, checkSpec.project); @@ -872,7 +872,7 @@ namespace ts.server { let normalizedFileName = ts.normalizePath(fileName); return { fileName: normalizedFileName, project }; }); - this.updateErrorCheck(checkList, this.changeSeq, (n) => n == this.changeSeq, delay); + this.updateErrorCheck(checkList, this.changeSeq, (n) => n == this.changeSeq, delay, 200, false); } } From b1e688c0567dec2bf16a63e0ff6df12c44ec9f66 Mon Sep 17 00:00:00 2001 From: zhengbli Date: Thu, 16 Jul 2015 16:05:29 -0700 Subject: [PATCH 7/8] Merge branch 'master' of https://github.com/Microsoft/TypeScript into errorlist --- Jakefile.js | 21 +- bin/tsc.js | 126 ++- bin/tsserver.js | 558 +++++++------ bin/typescript.d.ts | 2 + bin/typescript.js | 372 ++++++--- bin/typescriptServices.d.ts | 2 + bin/typescriptServices.js | 372 ++++++--- package.json | 1 + src/compiler/checker.ts | 129 +-- src/compiler/emitter.ts | 7 +- src/compiler/parser.ts | 9 +- src/compiler/utilities.ts | 2 +- src/harness/compilerRunner.ts | 129 +-- src/harness/fourslash.ts | 738 +++++++++--------- src/harness/fourslashRunner.ts | 120 +-- src/harness/harness.ts | 345 ++++---- src/harness/harnessLanguageService.ts | 64 +- src/harness/loggedIO.ts | 38 +- src/harness/projectsRunner.ts | 265 ++++--- src/harness/runner.ts | 22 +- src/harness/runnerbase.ts | 8 +- src/harness/rwcRunner.ts | 53 +- src/harness/sourceMapRecorder.ts | 107 +-- src/harness/test262Runner.ts | 28 +- src/harness/typeWriter.ts | 22 +- src/server/session.ts | 34 +- src/services/services.ts | 230 ++++-- src/services/shims.ts | 34 +- .../arrowFunctionExpressions.symbols | 2 + .../declarationEmitDestructuring1.symbols | 1 + ...tionEmitDestructuringArrayPattern2.symbols | 1 + ...tDestructuringObjectLiteralPattern.symbols | 9 + ...DestructuringObjectLiteralPattern1.symbols | 4 + ...DestructuringObjectLiteralPattern2.symbols | 5 + ...ectBindingPatternAndAssignment1ES5.symbols | 2 + ...ectBindingPatternAndAssignment1ES6.symbols | 2 + ...cturingParameterDeclaration1ES5.errors.txt | 20 +- ...structuringVariableDeclaration1ES5.symbols | 6 + ...structuringVariableDeclaration1ES6.symbols | 6 + .../reference/downlevelLetConst12.symbols | 2 + .../reference/downlevelLetConst13.symbols | 4 + .../reference/downlevelLetConst14.symbols | 4 + .../reference/downlevelLetConst15.symbols | 6 + .../reference/emitArrowFunctionES6.symbols | 2 + ...owFunctionWhenUsingArguments18_ES6.symbols | 1 + ...ationWithModuleSpecifierNameOnNextLine1.js | 34 + ...WithModuleSpecifierNameOnNextLine1.symbols | 28 + ...onWithModuleSpecifierNameOnNextLine1.types | 29 + tests/baselines/reference/for-of41.symbols | 2 + tests/baselines/reference/for-of42.symbols | 2 + ...initializePropertiesWithRenamedLet.symbols | 1 + .../reference/letInNonStrictMode.symbols | 1 + ...BindingPatternKeywordIdentifiers06.symbols | 1 + .../reference/strictModeInConstructor.js | 2 +- .../reference/superSymbolIndexedAccess1.js | 27 + .../superSymbolIndexedAccess1.symbols | 29 + .../reference/superSymbolIndexedAccess1.types | 34 + .../reference/superSymbolIndexedAccess2.js | 25 + .../superSymbolIndexedAccess2.symbols | 30 + .../reference/superSymbolIndexedAccess2.types | 33 + .../superSymbolIndexedAccess3.errors.txt | 19 + .../reference/superSymbolIndexedAccess3.js | 27 + .../superSymbolIndexedAccess4.errors.txt | 13 + .../reference/superSymbolIndexedAccess4.js | 16 + .../reference/superSymbolIndexedAccess5.js | 40 + .../superSymbolIndexedAccess5.symbols | 26 + .../reference/superSymbolIndexedAccess5.types | 29 + .../reference/superSymbolIndexedAccess6.js | 40 + .../superSymbolIndexedAccess6.symbols | 26 + .../reference/superSymbolIndexedAccess6.types | 29 + .../reference/systemModule13.symbols | 3 + .../baselines/reference/systemModule8.symbols | 3 + .../typeArgumentInferenceApparentType1.js | 12 + ...typeArgumentInferenceApparentType1.symbols | 16 + .../typeArgumentInferenceApparentType1.types | 18 + .../typeArgumentInferenceApparentType2.js | 17 + ...typeArgumentInferenceApparentType2.symbols | 27 + .../typeArgumentInferenceApparentType2.types | 28 + .../unclosedExportClause01.errors.txt | 44 ++ .../reference/unclosedExportClause01.js | 30 + .../unclosedExportClause02.errors.txt | 57 ++ .../reference/unclosedExportClause02.js | 32 + tests/baselines/reference/wideningTuples1.js | 9 + .../reference/wideningTuples1.symbols | 16 + .../baselines/reference/wideningTuples1.types | 21 + tests/baselines/reference/wideningTuples2.js | 13 + .../reference/wideningTuples2.symbols | 16 + .../baselines/reference/wideningTuples2.types | 22 + .../reference/wideningTuples3.errors.txt | 9 + tests/baselines/reference/wideningTuples3.js | 8 + tests/baselines/reference/wideningTuples4.js | 10 + .../reference/wideningTuples4.symbols | 12 + .../baselines/reference/wideningTuples4.types | 19 + .../reference/wideningTuples5.errors.txt | 10 + tests/baselines/reference/wideningTuples5.js | 5 + tests/baselines/reference/wideningTuples6.js | 9 + .../reference/wideningTuples6.symbols | 12 + .../baselines/reference/wideningTuples6.types | 18 + .../reference/wideningTuples7.errors.txt | 10 + tests/baselines/reference/wideningTuples7.js | 11 + ...ationWithModuleSpecifierNameOnNextLine1.ts | 20 + .../typeArgumentInferenceApparentType1.ts | 6 + .../typeArgumentInferenceApparentType2.ts | 8 + .../cases/compiler/unclosedExportClause01.ts | 16 + .../cases/compiler/unclosedExportClause02.ts | 20 + .../superSymbolIndexedAccess1.ts | 14 + .../superSymbolIndexedAccess2.ts | 13 + .../superSymbolIndexedAccess3.ts | 14 + .../superSymbolIndexedAccess4.ts | 8 + .../superSymbolIndexedAccess5.ts | 14 + .../superSymbolIndexedAccess6.ts | 14 + .../types/tuple/wideningTuples1.ts | 5 + .../types/tuple/wideningTuples2.ts | 6 + .../types/tuple/wideningTuples3.ts | 4 + .../types/tuple/wideningTuples4.ts | 4 + .../types/tuple/wideningTuples5.ts | 2 + .../types/tuple/wideningTuples6.ts | 3 + .../types/tuple/wideningTuples7.ts | 5 + ...tifierDefinitionLocations_destructuring.ts | 2 +- .../completionListInExportClause01.ts | 40 + .../completionListInExportClause02.ts | 14 + .../completionListInExportClause03.ts | 16 + .../completionListInImportClause01.ts | 1 + .../completionListInNamespaceImportName01.ts | 11 + ...lRefsObjectBindingElementPropertyName01.ts | 19 + ...lRefsObjectBindingElementPropertyName02.ts | 19 + ...lRefsObjectBindingElementPropertyName03.ts | 19 + ...lRefsObjectBindingElementPropertyName04.ts | 23 + ...lRefsObjectBindingElementPropertyName05.ts | 13 + ...lRefsObjectBindingElementPropertyName06.ts | 30 + ...lRefsObjectBindingElementPropertyName07.ts | 15 + ...lRefsObjectBindingElementPropertyName09.ts | 23 + ...lRefsObjectBindingElementPropertyName10.ts | 19 + .../fourslash/getOccurrencesAbstract01.ts | 24 + .../fourslash/getOccurrencesAbstract02.ts | 29 + ...etOccurrencesClassExpressionConstructor.ts | 23 + .../getOccurrencesClassExpressionPrivate.ts | 27 + .../getOccurrencesClassExpressionPublic.ts | 27 + .../getOccurrencesClassExpressionStatic.ts | 29 + ...itionObjectBindingElementPropertyName01.ts | 14 + .../quickInfoForObjectBindingElementName01.ts | 12 + .../quickInfoForObjectBindingElementName02.ts | 12 + ...foForObjectBindingElementPropertyName01.ts | 12 + ...foForObjectBindingElementPropertyName02.ts | 12 + ...foForObjectBindingElementPropertyName03.ts | 14 + ...foForObjectBindingElementPropertyName04.ts | 17 + ...enameObjectBindingElementPropertyName01.ts | 14 + .../shims/getSyntacticClassifications.ts | 4 +- .../syntacticClassificationWithErrors.ts | 4 +- .../fourslash/syntacticClassifications1.ts | 4 +- ...yntacticClassificationsConflictMarkers1.ts | 4 +- ...yntacticClassificationsConflictMarkers2.ts | 2 +- .../syntacticClassificationsDocComment1.ts | 2 +- .../syntacticClassificationsDocComment2.ts | 4 +- .../syntacticClassificationsDocComment3.ts | 2 +- .../syntacticClassificationsForOfKeyword.ts | 4 +- .../syntacticClassificationsForOfKeyword2.ts | 4 +- .../syntacticClassificationsForOfKeyword3.ts | 6 +- ...cticClassificationsFunctionWithComments.ts | 4 +- .../syntacticClassificationsObjectLiteral.ts | 18 +- .../syntacticClassificationsTemplates1.ts | 8 +- .../syntacticClassificationsTemplates2.ts | 2 +- 162 files changed, 4015 insertions(+), 1738 deletions(-) create mode 100644 tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.js create mode 100644 tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.symbols create mode 100644 tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.types create mode 100644 tests/baselines/reference/superSymbolIndexedAccess1.js create mode 100644 tests/baselines/reference/superSymbolIndexedAccess1.symbols create mode 100644 tests/baselines/reference/superSymbolIndexedAccess1.types create mode 100644 tests/baselines/reference/superSymbolIndexedAccess2.js create mode 100644 tests/baselines/reference/superSymbolIndexedAccess2.symbols create mode 100644 tests/baselines/reference/superSymbolIndexedAccess2.types create mode 100644 tests/baselines/reference/superSymbolIndexedAccess3.errors.txt create mode 100644 tests/baselines/reference/superSymbolIndexedAccess3.js create mode 100644 tests/baselines/reference/superSymbolIndexedAccess4.errors.txt create mode 100644 tests/baselines/reference/superSymbolIndexedAccess4.js create mode 100644 tests/baselines/reference/superSymbolIndexedAccess5.js create mode 100644 tests/baselines/reference/superSymbolIndexedAccess5.symbols create mode 100644 tests/baselines/reference/superSymbolIndexedAccess5.types create mode 100644 tests/baselines/reference/superSymbolIndexedAccess6.js create mode 100644 tests/baselines/reference/superSymbolIndexedAccess6.symbols create mode 100644 tests/baselines/reference/superSymbolIndexedAccess6.types create mode 100644 tests/baselines/reference/typeArgumentInferenceApparentType1.js create mode 100644 tests/baselines/reference/typeArgumentInferenceApparentType1.symbols create mode 100644 tests/baselines/reference/typeArgumentInferenceApparentType1.types create mode 100644 tests/baselines/reference/typeArgumentInferenceApparentType2.js create mode 100644 tests/baselines/reference/typeArgumentInferenceApparentType2.symbols create mode 100644 tests/baselines/reference/typeArgumentInferenceApparentType2.types create mode 100644 tests/baselines/reference/unclosedExportClause01.errors.txt create mode 100644 tests/baselines/reference/unclosedExportClause01.js create mode 100644 tests/baselines/reference/unclosedExportClause02.errors.txt create mode 100644 tests/baselines/reference/unclosedExportClause02.js create mode 100644 tests/baselines/reference/wideningTuples1.js create mode 100644 tests/baselines/reference/wideningTuples1.symbols create mode 100644 tests/baselines/reference/wideningTuples1.types create mode 100644 tests/baselines/reference/wideningTuples2.js create mode 100644 tests/baselines/reference/wideningTuples2.symbols create mode 100644 tests/baselines/reference/wideningTuples2.types create mode 100644 tests/baselines/reference/wideningTuples3.errors.txt create mode 100644 tests/baselines/reference/wideningTuples3.js create mode 100644 tests/baselines/reference/wideningTuples4.js create mode 100644 tests/baselines/reference/wideningTuples4.symbols create mode 100644 tests/baselines/reference/wideningTuples4.types create mode 100644 tests/baselines/reference/wideningTuples5.errors.txt create mode 100644 tests/baselines/reference/wideningTuples5.js create mode 100644 tests/baselines/reference/wideningTuples6.js create mode 100644 tests/baselines/reference/wideningTuples6.symbols create mode 100644 tests/baselines/reference/wideningTuples6.types create mode 100644 tests/baselines/reference/wideningTuples7.errors.txt create mode 100644 tests/baselines/reference/wideningTuples7.js create mode 100644 tests/cases/compiler/exportDeclarationWithModuleSpecifierNameOnNextLine1.ts create mode 100644 tests/cases/compiler/typeArgumentInferenceApparentType1.ts create mode 100644 tests/cases/compiler/typeArgumentInferenceApparentType2.ts create mode 100644 tests/cases/compiler/unclosedExportClause01.ts create mode 100644 tests/cases/compiler/unclosedExportClause02.ts create mode 100644 tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess1.ts create mode 100644 tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess2.ts create mode 100644 tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess3.ts create mode 100644 tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess4.ts create mode 100644 tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess5.ts create mode 100644 tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess6.ts create mode 100644 tests/cases/conformance/types/tuple/wideningTuples1.ts create mode 100644 tests/cases/conformance/types/tuple/wideningTuples2.ts create mode 100644 tests/cases/conformance/types/tuple/wideningTuples3.ts create mode 100644 tests/cases/conformance/types/tuple/wideningTuples4.ts create mode 100644 tests/cases/conformance/types/tuple/wideningTuples5.ts create mode 100644 tests/cases/conformance/types/tuple/wideningTuples6.ts create mode 100644 tests/cases/conformance/types/tuple/wideningTuples7.ts create mode 100644 tests/cases/fourslash/completionListInExportClause01.ts create mode 100644 tests/cases/fourslash/completionListInExportClause02.ts create mode 100644 tests/cases/fourslash/completionListInExportClause03.ts create mode 100644 tests/cases/fourslash/completionListInNamespaceImportName01.ts create mode 100644 tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName01.ts create mode 100644 tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName02.ts create mode 100644 tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName03.ts create mode 100644 tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName04.ts create mode 100644 tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName05.ts create mode 100644 tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts create mode 100644 tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts create mode 100644 tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName09.ts create mode 100644 tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName10.ts create mode 100644 tests/cases/fourslash/getOccurrencesAbstract01.ts create mode 100644 tests/cases/fourslash/getOccurrencesAbstract02.ts create mode 100644 tests/cases/fourslash/getOccurrencesClassExpressionConstructor.ts create mode 100644 tests/cases/fourslash/getOccurrencesClassExpressionPrivate.ts create mode 100644 tests/cases/fourslash/getOccurrencesClassExpressionPublic.ts create mode 100644 tests/cases/fourslash/getOccurrencesClassExpressionStatic.ts create mode 100644 tests/cases/fourslash/goToDefinitionObjectBindingElementPropertyName01.ts create mode 100644 tests/cases/fourslash/quickInfoForObjectBindingElementName01.ts create mode 100644 tests/cases/fourslash/quickInfoForObjectBindingElementName02.ts create mode 100644 tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName01.ts create mode 100644 tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName02.ts create mode 100644 tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName03.ts create mode 100644 tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName04.ts create mode 100644 tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts diff --git a/Jakefile.js b/Jakefile.js index 33ad46c8b58..bd5074b43d6 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -113,7 +113,7 @@ var languageServiceLibrarySources = [ return path.join(serverDirectory, f); }).concat(servicesSources); -var harnessSources = [ +var harnessCoreSources = [ "harness.ts", "sourceMapRecorder.ts", "harnessLanguageService.ts", @@ -129,7 +129,9 @@ var harnessSources = [ "runner.ts" ].map(function (f) { return path.join(harnessDirectory, f); -}).concat([ +}); + +var harnessSources = harnessCoreSources.concat([ "incrementalParser.ts", "jsDocParsing.ts", "services/colorization.ts", @@ -566,7 +568,7 @@ task("runtests", ["tests", builtLocalDirectory], function() { colors = process.env.colors || process.env.color colors = colors ? ' --no-colors ' : ' --colors '; tests = tests ? ' -g ' + tests : ''; - reporter = process.env.reporter || process.env.r || 'dot'; + reporter = process.env.reporter || process.env.r || 'mocha-fivemat-progress-reporter'; // timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally // default timeout is 2sec which really should be enough, but maybe we just need a small amount longer var cmd = host + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run; @@ -730,12 +732,13 @@ task("update-sublime", ["local", serverFile], function() { // run this task automatically desc("Runs tslint on the compiler sources"); task("lint", [], function() { - for(var i in compilerSources) { - var f = compilerSources[i]; + function success(f) { return function() { console.log('SUCCESS: No linter errors in ' + f + '\n'); }}; + function failure(f) { return function() { console.log('FAILURE: Please fix linting errors in ' + f + '\n') }}; + + var lintTargets = compilerSources.concat(harnessCoreSources); + for(var i in lintTargets) { + var f = lintTargets[i]; var cmd = 'tslint -f ' + f; - exec(cmd, - function() { console.log('SUCCESS: No linter errors'); }, - function() { console.log('FAILURE: Please fix linting errors in ' + f + '\n'); - }); + exec(cmd, success(f), failure(f)); } }, { async: true }); diff --git a/bin/tsc.js b/bin/tsc.js index f5a780a390d..185aca1ef44 100644 --- a/bin/tsc.js +++ b/bin/tsc.js @@ -933,7 +933,14 @@ var ts; newLine: _os.EOL, useCaseSensitiveFileNames: useCaseSensitiveFileNames, write: function (s) { - _fs.writeSync(1, s); + var buffer = new Buffer(s, 'utf8'); + var offset = 0; + var toWrite = buffer.length; + var written = 0; + while ((written = _fs.writeSync(1, buffer, offset, toWrite)) < toWrite) { + offset += written; + toWrite -= written; + } }, readFile: readFile, writeFile: writeFile, @@ -1401,7 +1408,7 @@ var ts; Classes_containing_abstract_methods_must_be_marked_abstract: { code: 2514, category: ts.DiagnosticCategory.Error, key: "Classes containing abstract methods must be marked abstract." }, Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2: { code: 2515, category: ts.DiagnosticCategory.Error, key: "Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'." }, All_declarations_of_an_abstract_method_must_be_consecutive: { code: 2516, category: ts.DiagnosticCategory.Error, key: "All declarations of an abstract method must be consecutive." }, - Constructor_objects_of_abstract_type_cannot_be_assigned_to_constructor_objects_of_non_abstract_type: { code: 2517, category: ts.DiagnosticCategory.Error, key: "Constructor objects of abstract type cannot be assigned to constructor objects of non-abstract type" }, + Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type: { code: 2517, category: ts.DiagnosticCategory.Error, key: "Cannot assign an abstract constructor type to a non-abstract constructor type." }, Only_an_ambient_class_can_be_merged_with_an_interface: { code: 2518, category: ts.DiagnosticCategory.Error, key: "Only an ambient class can be merged with an interface." }, Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions: { code: 2520, category: ts.DiagnosticCategory.Error, key: "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions." }, Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions: { code: 2521, category: ts.DiagnosticCategory.Error, key: "Expression resolves to variable declaration '{0}' that compiler uses to support async functions." }, @@ -9187,7 +9194,8 @@ var ts; } else { node.exportClause = parseNamedImportsOrExports(226); - if (parseOptional(130)) { + if (token === 130 || (token === 8 && !scanner.hasPrecedingLineBreak())) { + parseExpected(130); node.moduleSpecifier = parseModuleSpecifier(); } } @@ -13263,7 +13271,7 @@ var ts; var id = getTypeListId(elementTypes); var type = tupleTypes[id]; if (!type) { - type = tupleTypes[id] = createObjectType(8192); + type = tupleTypes[id] = createObjectType(8192 | getWideningFlagsOfTypes(elementTypes)); type.elementTypes = elementTypes; } return type; @@ -14084,10 +14092,29 @@ var ts; var targetSignatures = getSignaturesOfType(target, kind); var result = -1; var saveErrorInfo = errorInfo; + var sourceSig = sourceSignatures[0]; + var targetSig = targetSignatures[0]; + if (sourceSig && targetSig) { + var sourceErasedSignature = getErasedSignature(sourceSig); + var targetErasedSignature = getErasedSignature(targetSig); + var sourceReturnType = sourceErasedSignature && getReturnTypeOfSignature(sourceErasedSignature); + var targetReturnType = targetErasedSignature && getReturnTypeOfSignature(targetErasedSignature); + var sourceReturnDecl = sourceReturnType && sourceReturnType.symbol && ts.getDeclarationOfKind(sourceReturnType.symbol, 211); + var targetReturnDecl = targetReturnType && targetReturnType.symbol && ts.getDeclarationOfKind(targetReturnType.symbol, 211); + var sourceIsAbstract = sourceReturnDecl && sourceReturnDecl.flags & 256; + var targetIsAbstract = targetReturnDecl && targetReturnDecl.flags & 256; + if (sourceIsAbstract && !targetIsAbstract) { + if (reportErrors) { + reportError(ts.Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type); + } + return 0; + } + } outer: for (var _i = 0; _i < targetSignatures.length; _i++) { var t = targetSignatures[_i]; if (!t.hasStringLiterals || target.flags & 262144) { var localErrors = reportErrors; + var checkedAbstractAssignability = false; for (var _a = 0; _a < sourceSignatures.length; _a++) { var s = sourceSignatures[_a]; if (!s.hasStringLiterals || source.flags & 262144) { @@ -14135,12 +14162,12 @@ var ts; target = getErasedSignature(target); var result = -1; for (var i = 0; i < checkCount; i++) { - var s_1 = i < sourceMax ? getTypeOfSymbol(source.parameters[i]) : getRestTypeOfSignature(source); - var t_1 = i < targetMax ? getTypeOfSymbol(target.parameters[i]) : getRestTypeOfSignature(target); + var s = i < sourceMax ? getTypeOfSymbol(source.parameters[i]) : getRestTypeOfSignature(source); + var t = i < targetMax ? getTypeOfSymbol(target.parameters[i]) : getRestTypeOfSignature(target); var saveErrorInfo = errorInfo; - var related = isRelatedTo(s_1, t_1, reportErrors); + var related = isRelatedTo(s, t, reportErrors); if (!related) { - related = isRelatedTo(t_1, s_1, false); + related = isRelatedTo(t, s, false); if (!related) { if (reportErrors) { reportError(ts.Diagnostics.Types_of_parameters_0_and_1_are_incompatible, source.parameters[i < sourceMax ? i : sourceMax].name, target.parameters[i < targetMax ? i : targetMax].name); @@ -14178,11 +14205,11 @@ var ts; } return 0; } - var t = getReturnTypeOfSignature(target); - if (t === voidType) + var targetReturnType = getReturnTypeOfSignature(target); + if (targetReturnType === voidType) return result; - var s = getReturnTypeOfSignature(source); - return result & isRelatedTo(s, t, reportErrors); + var sourceReturnType = getReturnTypeOfSignature(source); + return result & isRelatedTo(sourceReturnType, targetReturnType, reportErrors); } function signaturesIdenticalTo(source, target, kind) { var sourceSignatures = getSignaturesOfType(source, kind); @@ -14395,7 +14422,7 @@ var ts; return !!getPropertyOfType(type, "0"); } function isTupleType(type) { - return (type.flags & 8192) && !!type.elementTypes; + return !!(type.flags & 8192); } function getWidenedTypeOfObjectLiteral(type) { var properties = getPropertiesOfObjectType(type); @@ -14437,25 +14464,36 @@ var ts; if (isArrayType(type)) { return createArrayType(getWidenedType(type.typeArguments[0])); } + if (isTupleType(type)) { + return createTupleType(ts.map(type.elementTypes, getWidenedType)); + } } return type; } function reportWideningErrorsInType(type) { + var errorReported = false; if (type.flags & 16384) { - var errorReported = false; - ts.forEach(type.types, function (t) { + for (var _i = 0, _a = type.types; _i < _a.length; _i++) { + var t = _a[_i]; if (reportWideningErrorsInType(t)) { errorReported = true; } - }); - return errorReported; + } } if (isArrayType(type)) { return reportWideningErrorsInType(type.typeArguments[0]); } + if (isTupleType(type)) { + for (var _b = 0, _c = type.elementTypes; _b < _c.length; _b++) { + var t = _c[_b]; + if (reportWideningErrorsInType(t)) { + errorReported = true; + } + } + } if (type.flags & 524288) { - var errorReported = false; - ts.forEach(getPropertiesOfObjectType(type), function (p) { + for (var _d = 0, _e = getPropertiesOfObjectType(type); _d < _e.length; _d++) { + var p = _e[_d]; var t = getTypeOfSymbol(p); if (t.flags & 1048576) { if (!reportWideningErrorsInType(t)) { @@ -14463,10 +14501,9 @@ var ts; } errorReported = true; } - }); - return errorReported; + } } - return false; + return errorReported; } function reportImplicitAnyError(declaration, type) { var typeAsString = typeToString(getWidenedType(type)); @@ -14614,28 +14651,31 @@ var ts; inferFromTypes(sourceType, target); } } - else if (source.flags & 80896 && (target.flags & (4096 | 8192) || - (target.flags & 65536) && target.symbol && target.symbol.flags & (8192 | 2048 | 32))) { - if (isInProcess(source, target)) { - return; + else { + source = getApparentType(source); + if (source.flags & 80896 && (target.flags & (4096 | 8192) || + (target.flags & 65536) && target.symbol && target.symbol.flags & (8192 | 2048 | 32))) { + if (isInProcess(source, target)) { + return; + } + if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) { + return; + } + if (depth === 0) { + sourceStack = []; + targetStack = []; + } + sourceStack[depth] = source; + targetStack[depth] = target; + depth++; + inferFromProperties(source, target); + inferFromSignatures(source, target, 0); + inferFromSignatures(source, target, 1); + inferFromIndexTypes(source, target, 0, 0); + inferFromIndexTypes(source, target, 1, 1); + inferFromIndexTypes(source, target, 0, 1); + depth--; } - if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) { - return; - } - if (depth === 0) { - sourceStack = []; - targetStack = []; - } - sourceStack[depth] = source; - targetStack[depth] = target; - depth++; - inferFromProperties(source, target); - inferFromSignatures(source, target, 0); - inferFromSignatures(source, target, 1); - inferFromIndexTypes(source, target, 0, 0); - inferFromIndexTypes(source, target, 1, 1); - inferFromIndexTypes(source, target, 0, 1); - depth--; } } function inferFromProperties(source, target) { diff --git a/bin/tsserver.js b/bin/tsserver.js index abc95f7a760..9d582485e2f 100644 --- a/bin/tsserver.js +++ b/bin/tsserver.js @@ -933,7 +933,14 @@ var ts; newLine: _os.EOL, useCaseSensitiveFileNames: useCaseSensitiveFileNames, write: function (s) { - _fs.writeSync(1, s); + var buffer = new Buffer(s, 'utf8'); + var offset = 0; + var toWrite = buffer.length; + var written = 0; + while ((written = _fs.writeSync(1, buffer, offset, toWrite)) < toWrite) { + offset += written; + toWrite -= written; + } }, readFile: readFile, writeFile: writeFile, @@ -1401,7 +1408,7 @@ var ts; Classes_containing_abstract_methods_must_be_marked_abstract: { code: 2514, category: ts.DiagnosticCategory.Error, key: "Classes containing abstract methods must be marked abstract." }, Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2: { code: 2515, category: ts.DiagnosticCategory.Error, key: "Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'." }, All_declarations_of_an_abstract_method_must_be_consecutive: { code: 2516, category: ts.DiagnosticCategory.Error, key: "All declarations of an abstract method must be consecutive." }, - Constructor_objects_of_abstract_type_cannot_be_assigned_to_constructor_objects_of_non_abstract_type: { code: 2517, category: ts.DiagnosticCategory.Error, key: "Constructor objects of abstract type cannot be assigned to constructor objects of non-abstract type" }, + Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type: { code: 2517, category: ts.DiagnosticCategory.Error, key: "Cannot assign an abstract constructor type to a non-abstract constructor type." }, Only_an_ambient_class_can_be_merged_with_an_interface: { code: 2518, category: ts.DiagnosticCategory.Error, key: "Only an ambient class can be merged with an interface." }, Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions: { code: 2520, category: ts.DiagnosticCategory.Error, key: "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions." }, Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions: { code: 2521, category: ts.DiagnosticCategory.Error, key: "Expression resolves to variable declaration '{0}' that compiler uses to support async functions." }, @@ -8904,7 +8911,8 @@ var ts; } else { node.exportClause = parseNamedImportsOrExports(226); - if (parseOptional(130)) { + if (token === 130 || (token === 8 && !scanner.hasPrecedingLineBreak())) { + parseExpected(130); node.moduleSpecifier = parseModuleSpecifier(); } } @@ -13686,7 +13694,7 @@ var ts; var id = getTypeListId(elementTypes); var type = tupleTypes[id]; if (!type) { - type = tupleTypes[id] = createObjectType(8192); + type = tupleTypes[id] = createObjectType(8192 | getWideningFlagsOfTypes(elementTypes)); type.elementTypes = elementTypes; } return type; @@ -14507,10 +14515,29 @@ var ts; var targetSignatures = getSignaturesOfType(target, kind); var result = -1; var saveErrorInfo = errorInfo; + var sourceSig = sourceSignatures[0]; + var targetSig = targetSignatures[0]; + if (sourceSig && targetSig) { + var sourceErasedSignature = getErasedSignature(sourceSig); + var targetErasedSignature = getErasedSignature(targetSig); + var sourceReturnType = sourceErasedSignature && getReturnTypeOfSignature(sourceErasedSignature); + var targetReturnType = targetErasedSignature && getReturnTypeOfSignature(targetErasedSignature); + var sourceReturnDecl = sourceReturnType && sourceReturnType.symbol && ts.getDeclarationOfKind(sourceReturnType.symbol, 211); + var targetReturnDecl = targetReturnType && targetReturnType.symbol && ts.getDeclarationOfKind(targetReturnType.symbol, 211); + var sourceIsAbstract = sourceReturnDecl && sourceReturnDecl.flags & 256; + var targetIsAbstract = targetReturnDecl && targetReturnDecl.flags & 256; + if (sourceIsAbstract && !targetIsAbstract) { + if (reportErrors) { + reportError(ts.Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type); + } + return 0; + } + } outer: for (var _i = 0; _i < targetSignatures.length; _i++) { var t = targetSignatures[_i]; if (!t.hasStringLiterals || target.flags & 262144) { var localErrors = reportErrors; + var checkedAbstractAssignability = false; for (var _a = 0; _a < sourceSignatures.length; _a++) { var s = sourceSignatures[_a]; if (!s.hasStringLiterals || source.flags & 262144) { @@ -14558,12 +14585,12 @@ var ts; target = getErasedSignature(target); var result = -1; for (var i = 0; i < checkCount; i++) { - var s_1 = i < sourceMax ? getTypeOfSymbol(source.parameters[i]) : getRestTypeOfSignature(source); - var t_1 = i < targetMax ? getTypeOfSymbol(target.parameters[i]) : getRestTypeOfSignature(target); + var s = i < sourceMax ? getTypeOfSymbol(source.parameters[i]) : getRestTypeOfSignature(source); + var t = i < targetMax ? getTypeOfSymbol(target.parameters[i]) : getRestTypeOfSignature(target); var saveErrorInfo = errorInfo; - var related = isRelatedTo(s_1, t_1, reportErrors); + var related = isRelatedTo(s, t, reportErrors); if (!related) { - related = isRelatedTo(t_1, s_1, false); + related = isRelatedTo(t, s, false); if (!related) { if (reportErrors) { reportError(ts.Diagnostics.Types_of_parameters_0_and_1_are_incompatible, source.parameters[i < sourceMax ? i : sourceMax].name, target.parameters[i < targetMax ? i : targetMax].name); @@ -14601,11 +14628,11 @@ var ts; } return 0; } - var t = getReturnTypeOfSignature(target); - if (t === voidType) + var targetReturnType = getReturnTypeOfSignature(target); + if (targetReturnType === voidType) return result; - var s = getReturnTypeOfSignature(source); - return result & isRelatedTo(s, t, reportErrors); + var sourceReturnType = getReturnTypeOfSignature(source); + return result & isRelatedTo(sourceReturnType, targetReturnType, reportErrors); } function signaturesIdenticalTo(source, target, kind) { var sourceSignatures = getSignaturesOfType(source, kind); @@ -14818,7 +14845,7 @@ var ts; return !!getPropertyOfType(type, "0"); } function isTupleType(type) { - return (type.flags & 8192) && !!type.elementTypes; + return !!(type.flags & 8192); } function getWidenedTypeOfObjectLiteral(type) { var properties = getPropertiesOfObjectType(type); @@ -14860,25 +14887,36 @@ var ts; if (isArrayType(type)) { return createArrayType(getWidenedType(type.typeArguments[0])); } + if (isTupleType(type)) { + return createTupleType(ts.map(type.elementTypes, getWidenedType)); + } } return type; } function reportWideningErrorsInType(type) { + var errorReported = false; if (type.flags & 16384) { - var errorReported = false; - ts.forEach(type.types, function (t) { + for (var _i = 0, _a = type.types; _i < _a.length; _i++) { + var t = _a[_i]; if (reportWideningErrorsInType(t)) { errorReported = true; } - }); - return errorReported; + } } if (isArrayType(type)) { return reportWideningErrorsInType(type.typeArguments[0]); } + if (isTupleType(type)) { + for (var _b = 0, _c = type.elementTypes; _b < _c.length; _b++) { + var t = _c[_b]; + if (reportWideningErrorsInType(t)) { + errorReported = true; + } + } + } if (type.flags & 524288) { - var errorReported = false; - ts.forEach(getPropertiesOfObjectType(type), function (p) { + for (var _d = 0, _e = getPropertiesOfObjectType(type); _d < _e.length; _d++) { + var p = _e[_d]; var t = getTypeOfSymbol(p); if (t.flags & 1048576) { if (!reportWideningErrorsInType(t)) { @@ -14886,10 +14924,9 @@ var ts; } errorReported = true; } - }); - return errorReported; + } } - return false; + return errorReported; } function reportImplicitAnyError(declaration, type) { var typeAsString = typeToString(getWidenedType(type)); @@ -15037,28 +15074,31 @@ var ts; inferFromTypes(sourceType, target); } } - else if (source.flags & 80896 && (target.flags & (4096 | 8192) || - (target.flags & 65536) && target.symbol && target.symbol.flags & (8192 | 2048 | 32))) { - if (isInProcess(source, target)) { - return; + else { + source = getApparentType(source); + if (source.flags & 80896 && (target.flags & (4096 | 8192) || + (target.flags & 65536) && target.symbol && target.symbol.flags & (8192 | 2048 | 32))) { + if (isInProcess(source, target)) { + return; + } + if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) { + return; + } + if (depth === 0) { + sourceStack = []; + targetStack = []; + } + sourceStack[depth] = source; + targetStack[depth] = target; + depth++; + inferFromProperties(source, target); + inferFromSignatures(source, target, 0); + inferFromSignatures(source, target, 1); + inferFromIndexTypes(source, target, 0, 0); + inferFromIndexTypes(source, target, 1, 1); + inferFromIndexTypes(source, target, 0, 1); + depth--; } - if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) { - return; - } - if (depth === 0) { - sourceStack = []; - targetStack = []; - } - sourceStack[depth] = source; - targetStack[depth] = target; - depth++; - inferFromProperties(source, target); - inferFromSignatures(source, target, 0); - inferFromSignatures(source, target, 1); - inferFromIndexTypes(source, target, 0, 0); - inferFromIndexTypes(source, target, 1, 1); - inferFromIndexTypes(source, target, 0, 1); - depth--; } } function inferFromProperties(source, target) { @@ -31937,15 +31977,15 @@ var ts; var t; var pos = scanner.getStartPos(); while (pos < endPos) { - var t_2 = scanner.getToken(); - if (!ts.isTrivia(t_2)) { + var t_1 = scanner.getToken(); + if (!ts.isTrivia(t_1)) { break; } scanner.scan(); var item = { pos: pos, end: scanner.getStartPos(), - kind: t_2 + kind: t_1 }; pos = scanner.getStartPos(); if (!leadingTrivia) { @@ -33289,6 +33329,8 @@ var ts; case 15: case 18: case 19: + case 16: + case 17: case 77: case 101: case 53: @@ -33390,7 +33432,7 @@ var ts; } else if (tokenInfo.token.kind === listStartToken) { startLine = sourceFile.getLineAndCharacterOfPosition(tokenInfo.token.pos).line; - var indentation_1 = computeIndentation(tokenInfo.token, startLine, -1, parent, parentDynamicIndentation, startLine); + var indentation_1 = computeIndentation(tokenInfo.token, startLine, -1, parent, parentDynamicIndentation, parentStartLine); listDynamicIndentation = getDynamicIndentation(parent, parentStartLine, indentation_1.indentation, indentation_1.delta); consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation); } @@ -35052,6 +35094,12 @@ var ts; var newSourceFile = ts.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); setSourceFileFields(newSourceFile, scriptSnapshot, version); newSourceFile.nameTable = undefined; + if (sourceFile !== newSourceFile && sourceFile.scriptSnapshot) { + if (sourceFile.scriptSnapshot.dispose) { + sourceFile.scriptSnapshot.dispose(); + } + sourceFile.scriptSnapshot = undefined; + } return newSourceFile; } } @@ -35908,20 +35956,20 @@ var ts; } function tryGetGlobalSymbols() { var objectLikeContainer; - var importClause; + var namedImportsOrExports; var jsxContainer; if (objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken)) { return tryGetObjectLikeCompletionSymbols(objectLikeContainer); } - if (importClause = ts.getAncestor(contextToken, 220)) { - return tryGetImportClauseCompletionSymbols(importClause); + if (namedImportsOrExports = tryGetNamedImportsOrExportsForCompletion(contextToken)) { + return tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports); } if (jsxContainer = tryGetContainingJsxElement(contextToken)) { var attrsType; if ((jsxContainer.kind === 231) || (jsxContainer.kind === 232)) { attrsType = typeChecker.getJsxElementAttributesType(jsxContainer); if (attrsType) { - symbols = filterJsxAttributes(jsxContainer.attributes, typeChecker.getPropertiesOfType(attrsType)); + symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), jsxContainer.attributes); isMemberCompletion = true; isNewIdentifierLocation = false; return true; @@ -35951,19 +35999,11 @@ var ts; function isCompletionListBlocker(contextToken) { var start = new Date().getTime(); var result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) || - isIdentifierDefinitionLocation(contextToken) || + isSolelyIdentifierDefinitionLocation(contextToken) || isDotOfNumericLiteral(contextToken); log("getCompletionsAtPosition: isCompletionListBlocker: " + (new Date().getTime() - start)); return result; } - function shouldShowCompletionsInImportsClause(node) { - if (node) { - if (node.kind === 14 || node.kind === 23) { - return node.parent.kind === 222; - } - } - return false; - } function isNewIdentifierDefinitionLocation(previousToken) { if (previousToken) { var containingNodeKind = previousToken.parent.kind; @@ -36055,23 +36095,23 @@ var ts; } return true; } - function tryGetImportClauseCompletionSymbols(importClause) { - if (shouldShowCompletionsInImportsClause(contextToken)) { - isMemberCompletion = true; - isNewIdentifierLocation = false; - var importDeclaration = importClause.parent; - ts.Debug.assert(importDeclaration !== undefined && importDeclaration.kind === 219); - var exports_2; - var moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importDeclaration.moduleSpecifier); - if (moduleSpecifierSymbol) { - exports_2 = typeChecker.getExportsOfModule(moduleSpecifierSymbol); - } - symbols = exports_2 ? filterModuleExports(exports_2, importDeclaration) : emptyArray; + function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports) { + var declarationKind = namedImportsOrExports.kind === 222 ? + 219 : + 225; + var importOrExportDeclaration = ts.getAncestor(namedImportsOrExports, declarationKind); + var moduleSpecifier = importOrExportDeclaration.moduleSpecifier; + if (!moduleSpecifier) { + return false; } - else { - isMemberCompletion = false; - isNewIdentifierLocation = true; + isMemberCompletion = true; + isNewIdentifierLocation = false; + var exports; + var moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier); + if (moduleSpecifierSymbol) { + exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol); } + symbols = exports ? filterNamedImportOrExportCompletionItems(exports, namedImportsOrExports.elements) : emptyArray; return true; } function tryGetObjectLikeCompletionContainer(contextToken) { @@ -36088,6 +36128,20 @@ var ts; } return undefined; } + function tryGetNamedImportsOrExportsForCompletion(contextToken) { + if (contextToken) { + switch (contextToken.kind) { + case 14: + case 23: + switch (contextToken.parent.kind) { + case 222: + case 226: + return contextToken.parent; + } + } + } + return undefined; + } function tryGetContainingJsxElement(contextToken) { if (contextToken) { var parent_12 = contextToken.parent; @@ -36127,7 +36181,7 @@ var ts; } return false; } - function isIdentifierDefinitionLocation(contextToken) { + function isSolelyIdentifierDefinitionLocation(contextToken) { var containingNodeKind = contextToken.parent.kind; switch (contextToken.kind) { case 23: @@ -36173,6 +36227,10 @@ var ts; case 107: case 108: return containingNodeKind === 135; + case 113: + containingNodeKind === 223 || + containingNodeKind === 227 || + containingNodeKind === 221; case 70: case 78: case 104: @@ -36208,25 +36266,20 @@ var ts; } return false; } - function filterModuleExports(exports, importDeclaration) { - var exisingImports = {}; - if (!importDeclaration.importClause) { - return exports; + function filterNamedImportOrExportCompletionItems(exportsOfModule, namedImportsOrExports) { + var exisingImportsOrExports = {}; + for (var _i = 0; _i < namedImportsOrExports.length; _i++) { + var element = namedImportsOrExports[_i]; + if (element.getStart() <= position && position <= element.getEnd()) { + continue; + } + var name_31 = element.propertyName || element.name; + exisingImportsOrExports[name_31.text] = true; } - if (importDeclaration.importClause.namedBindings && - importDeclaration.importClause.namedBindings.kind === 222) { - ts.forEach(importDeclaration.importClause.namedBindings.elements, function (el) { - if (el.getStart() <= position && position <= el.getEnd()) { - return; - } - var name = el.propertyName || el.name; - exisingImports[name.text] = true; - }); + if (ts.isEmpty(exisingImportsOrExports)) { + return exportsOfModule; } - if (ts.isEmpty(exisingImports)) { - return exports; - } - return ts.filter(exports, function (e) { return !ts.lookUp(exisingImports, e.name); }); + return ts.filter(exportsOfModule, function (e) { return !ts.lookUp(exisingImportsOrExports, e.name); }); } function filterObjectMembersList(contextualMemberSymbols, existingMembers) { if (!existingMembers || existingMembers.length === 0) { @@ -36252,15 +36305,9 @@ var ts; } existingMemberNames[existingName] = true; } - var filteredMembers = []; - ts.forEach(contextualMemberSymbols, function (s) { - if (!existingMemberNames[s.name]) { - filteredMembers.push(s); - } - }); - return filteredMembers; + return ts.filter(contextualMemberSymbols, function (m) { return !ts.lookUp(existingMemberNames, m.name); }); } - function filterJsxAttributes(attributes, symbols) { + function filterJsxAttributes(symbols, attributes) { var seenNames = {}; for (var _i = 0; _i < attributes.length; _i++) { var attr = attributes[_i]; @@ -36271,14 +36318,7 @@ var ts; seenNames[attr.name.text] = true; } } - var result = []; - for (var _a = 0; _a < symbols.length; _a++) { - var sym = symbols[_a]; - if (!seenNames[sym.name]) { - result.push(sym); - } - } - return result; + return ts.filter(symbols, function (a) { return !ts.lookUp(seenNames, a.name); }); } } function getCompletionsAtPosition(fileName, position) { @@ -36310,10 +36350,10 @@ var ts; for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { var sourceFile = _a[_i]; var nameTable = getNameTable(sourceFile); - for (var name_31 in nameTable) { - if (!allNames[name_31]) { - allNames[name_31] = name_31; - var displayName = getCompletionEntryDisplayName(name_31, target, true); + for (var name_32 in nameTable) { + if (!allNames[name_32]) { + allNames[name_32] = name_32; + var displayName = getCompletionEntryDisplayName(name_32, target, true); if (displayName) { var entry = { name: displayName, @@ -37117,6 +37157,7 @@ var ts; if (hasKind(node.parent, 142) || hasKind(node.parent, 143)) { return getGetAndSetOccurrences(node.parent); } + break; default: if (ts.isModifier(node.kind) && node.parent && (ts.isDeclaration(node.parent) || node.parent.kind === 190)) { @@ -37216,12 +37257,13 @@ var ts; var container = declaration.parent; if (ts.isAccessibilityModifier(modifier)) { if (!(container.kind === 211 || + container.kind === 183 || (declaration.kind === 135 && hasKind(container, 141)))) { return undefined; } } else if (modifier === 110) { - if (container.kind !== 211) { + if (!(container.kind === 211 || container.kind === 183)) { return undefined; } } @@ -37230,6 +37272,11 @@ var ts; return undefined; } } + else if (modifier === 112) { + if (!(container.kind === 211 || declaration.kind === 211)) { + return undefined; + } + } else { return undefined; } @@ -37239,12 +37286,18 @@ var ts; switch (container.kind) { case 216: case 245: - nodes = container.statements; + if (modifierFlag & 256) { + nodes = declaration.members.concat(declaration); + } + else { + nodes = container.statements; + } break; case 141: nodes = container.parameters.concat(container.parent.members); break; case 211: + case 183: nodes = container.members; if (modifierFlag & 112) { var constructor = ts.forEach(container.members, function (member) { @@ -37254,6 +37307,9 @@ var ts; nodes = nodes.concat(constructor.parameters); } } + else if (modifierFlag & 256) { + nodes = nodes.concat(container); + } break; default: ts.Debug.fail("Invalid container kind."); @@ -37278,6 +37334,8 @@ var ts; return 1; case 119: return 2; + case 112: + return 256; default: ts.Debug.fail(); } @@ -37975,17 +38033,17 @@ var ts; if (isNameOfPropertyAssignment(node)) { var objectLiteral = node.parent.parent; var contextualType = typeChecker.getContextualType(objectLiteral); - var name_32 = node.text; + var name_33 = node.text; if (contextualType) { if (contextualType.flags & 16384) { - var unionProperty = contextualType.getProperty(name_32); + var unionProperty = contextualType.getProperty(name_33); if (unionProperty) { return [unionProperty]; } else { var result_4 = []; ts.forEach(contextualType.types, function (t) { - var symbol = t.getProperty(name_32); + var symbol = t.getProperty(name_33); if (symbol) { result_4.push(symbol); } @@ -37994,7 +38052,7 @@ var ts; } } else { - var symbol_1 = contextualType.getProperty(name_32); + var symbol_1 = contextualType.getProperty(name_33); if (symbol_1) { return [symbol_1]; } @@ -38593,7 +38651,7 @@ var ts; return; } } - return 9; + return 2; } } function processElement(element) { @@ -39337,10 +39395,113 @@ var ts; this.fileHash = {}; this.nextFileId = 1; this.changeSeq = 0; + this.handlers = (_a = {}, + _a[CommandNames.Exit] = function () { + _this.exit(); + return {}; + }, + _a[CommandNames.Definition] = function (request) { + var defArgs = request.arguments; + return { response: _this.getDefinition(defArgs.line, defArgs.offset, defArgs.file) }; + }, + _a[CommandNames.TypeDefinition] = function (request) { + var defArgs = request.arguments; + return { response: _this.getTypeDefinition(defArgs.line, defArgs.offset, defArgs.file) }; + }, + _a[CommandNames.References] = function (request) { + var defArgs = request.arguments; + return { response: _this.getReferences(defArgs.line, defArgs.offset, defArgs.file) }; + }, + _a[CommandNames.Rename] = function (request) { + var renameArgs = request.arguments; + return { response: _this.getRenameLocations(renameArgs.line, renameArgs.offset, renameArgs.file, renameArgs.findInComments, renameArgs.findInStrings) }; + }, + _a[CommandNames.Open] = function (request) { + var openArgs = request.arguments; + _this.openClientFile(openArgs.file); + return {}; + }, + _a[CommandNames.Quickinfo] = function (request) { + var quickinfoArgs = request.arguments; + return { response: _this.getQuickInfo(quickinfoArgs.line, quickinfoArgs.offset, quickinfoArgs.file) }; + }, + _a[CommandNames.Format] = function (request) { + var formatArgs = request.arguments; + return { response: _this.getFormattingEditsForRange(formatArgs.line, formatArgs.offset, formatArgs.endLine, formatArgs.endOffset, formatArgs.file) }; + }, + _a[CommandNames.Formatonkey] = function (request) { + var formatOnKeyArgs = request.arguments; + return { response: _this.getFormattingEditsAfterKeystroke(formatOnKeyArgs.line, formatOnKeyArgs.offset, formatOnKeyArgs.key, formatOnKeyArgs.file) }; + }, + _a[CommandNames.Completions] = function (request) { + var completionsArgs = request.arguments; + return { response: _this.getCompletions(completionsArgs.line, completionsArgs.offset, completionsArgs.prefix, completionsArgs.file) }; + }, + _a[CommandNames.CompletionDetails] = function (request) { + var completionDetailsArgs = request.arguments; + return { response: _this.getCompletionEntryDetails(completionDetailsArgs.line, completionDetailsArgs.offset, completionDetailsArgs.entryNames, completionDetailsArgs.file) }; + }, + _a[CommandNames.SignatureHelp] = function (request) { + var signatureHelpArgs = request.arguments; + return { response: _this.getSignatureHelpItems(signatureHelpArgs.line, signatureHelpArgs.offset, signatureHelpArgs.file) }; + }, + _a[CommandNames.Geterr] = function (request) { + var geterrArgs = request.arguments; + return { response: _this.getDiagnostics(geterrArgs.delay, geterrArgs.files), responseRequired: false }; + }, + _a[CommandNames.Change] = function (request) { + var changeArgs = request.arguments; + _this.change(changeArgs.line, changeArgs.offset, changeArgs.endLine, changeArgs.endOffset, changeArgs.insertString, changeArgs.file); + return { responseRequired: false }; + }, + _a[CommandNames.Configure] = function (request) { + var configureArgs = request.arguments; + _this.projectService.setHostConfiguration(configureArgs); + _this.output(undefined, CommandNames.Configure, request.seq); + return { responseRequired: false }; + }, + _a[CommandNames.Reload] = function (request) { + var reloadArgs = request.arguments; + _this.reload(reloadArgs.file, reloadArgs.tmpfile, request.seq); + return { responseRequired: false }; + }, + _a[CommandNames.Saveto] = function (request) { + var savetoArgs = request.arguments; + _this.saveToTmp(savetoArgs.file, savetoArgs.tmpfile); + return { responseRequired: false }; + }, + _a[CommandNames.Close] = function (request) { + var closeArgs = request.arguments; + _this.closeClientFile(closeArgs.file); + return { responseRequired: false }; + }, + _a[CommandNames.Navto] = function (request) { + var navtoArgs = request.arguments; + return { response: _this.getNavigateToItems(navtoArgs.searchValue, navtoArgs.file, navtoArgs.maxResultCount) }; + }, + _a[CommandNames.Brace] = function (request) { + var braceArguments = request.arguments; + return { response: _this.getBraceMatching(braceArguments.line, braceArguments.offset, braceArguments.file) }; + }, + _a[CommandNames.NavBar] = function (request) { + var navBarArgs = request.arguments; + return { response: _this.getNavigationBarItems(navBarArgs.file) }; + }, + _a[CommandNames.Occurrences] = function (request) { + var _a = request.arguments, line = _a.line, offset = _a.offset, fileName = _a.file; + return { response: _this.getOccurrences(line, offset, fileName) }; + }, + _a[CommandNames.ProjectInfo] = function (request) { + var _a = request.arguments, file = _a.file, needFileNameList = _a.needFileNameList; + return { response: _this.getProjectInfo(file, needFileNameList) }; + }, + _a + ); this.projectService = new server.ProjectService(host, logger, function (eventName, project, fileName) { _this.handleEvent(eventName, project, fileName); }); + var _a; } Session.prototype.handleEvent = function (eventName, project, fileName) { var _this = this; @@ -39957,6 +40118,23 @@ var ts; }; Session.prototype.exit = function () { }; + Session.prototype.addProtocolHandler = function (command, handler) { + if (this.handlers[command]) { + throw new Error("Protocol handler already exists for command \"" + command + "\""); + } + this.handlers[command] = handler; + }; + Session.prototype.executeCommand = function (request) { + var handler = this.handlers[request.command]; + if (handler) { + return handler(request); + } + else { + this.projectService.log("Unrecognized JSON command: " + JSON.stringify(request)); + this.output(undefined, CommandNames.Unknown, request.seq, "Unrecognized JSON command: " + request.command); + return { responseRequired: false }; + } + }; Session.prototype.onMessage = function (message) { if (this.logger.isVerbose()) { this.logger.info("request: " + message); @@ -39964,140 +40142,7 @@ var ts; } try { var request = JSON.parse(message); - var response; - var errorMessage; - var responseRequired = true; - switch (request.command) { - case CommandNames.Exit: { - this.exit(); - responseRequired = false; - break; - } - case CommandNames.Definition: { - var defArgs = request.arguments; - response = this.getDefinition(defArgs.line, defArgs.offset, defArgs.file); - break; - } - case CommandNames.TypeDefinition: { - var defArgs = request.arguments; - response = this.getTypeDefinition(defArgs.line, defArgs.offset, defArgs.file); - break; - } - case CommandNames.References: { - var refArgs = request.arguments; - response = this.getReferences(refArgs.line, refArgs.offset, refArgs.file); - break; - } - case CommandNames.Rename: { - var renameArgs = request.arguments; - response = this.getRenameLocations(renameArgs.line, renameArgs.offset, renameArgs.file, renameArgs.findInComments, renameArgs.findInStrings); - break; - } - case CommandNames.Open: { - var openArgs = request.arguments; - this.openClientFile(openArgs.file); - responseRequired = false; - break; - } - case CommandNames.Quickinfo: { - var quickinfoArgs = request.arguments; - response = this.getQuickInfo(quickinfoArgs.line, quickinfoArgs.offset, quickinfoArgs.file); - break; - } - case CommandNames.Format: { - var formatArgs = request.arguments; - response = this.getFormattingEditsForRange(formatArgs.line, formatArgs.offset, formatArgs.endLine, formatArgs.endOffset, formatArgs.file); - break; - } - case CommandNames.Formatonkey: { - var formatOnKeyArgs = request.arguments; - response = this.getFormattingEditsAfterKeystroke(formatOnKeyArgs.line, formatOnKeyArgs.offset, formatOnKeyArgs.key, formatOnKeyArgs.file); - break; - } - case CommandNames.Completions: { - var completionsArgs = request.arguments; - response = this.getCompletions(completionsArgs.line, completionsArgs.offset, completionsArgs.prefix, completionsArgs.file); - break; - } - case CommandNames.CompletionDetails: { - var completionDetailsArgs = request.arguments; - response = - this.getCompletionEntryDetails(completionDetailsArgs.line, completionDetailsArgs.offset, completionDetailsArgs.entryNames, completionDetailsArgs.file); - break; - } - case CommandNames.SignatureHelp: { - var signatureHelpArgs = request.arguments; - response = this.getSignatureHelpItems(signatureHelpArgs.line, signatureHelpArgs.offset, signatureHelpArgs.file); - break; - } - case CommandNames.Geterr: { - var geterrArgs = request.arguments; - response = this.getDiagnostics(geterrArgs.delay, geterrArgs.files); - responseRequired = false; - break; - } - case CommandNames.Change: { - var changeArgs = request.arguments; - this.change(changeArgs.line, changeArgs.offset, changeArgs.endLine, changeArgs.endOffset, changeArgs.insertString, changeArgs.file); - responseRequired = false; - break; - } - case CommandNames.Configure: { - var configureArgs = request.arguments; - this.projectService.setHostConfiguration(configureArgs); - this.output(undefined, CommandNames.Configure, request.seq); - responseRequired = false; - break; - } - case CommandNames.Reload: { - var reloadArgs = request.arguments; - this.reload(reloadArgs.file, reloadArgs.tmpfile, request.seq); - responseRequired = false; - break; - } - case CommandNames.Saveto: { - var savetoArgs = request.arguments; - this.saveToTmp(savetoArgs.file, savetoArgs.tmpfile); - responseRequired = false; - break; - } - case CommandNames.Close: { - var closeArgs = request.arguments; - this.closeClientFile(closeArgs.file); - responseRequired = false; - break; - } - case CommandNames.Navto: { - var navtoArgs = request.arguments; - response = this.getNavigateToItems(navtoArgs.searchValue, navtoArgs.file, navtoArgs.maxResultCount); - break; - } - case CommandNames.Brace: { - var braceArguments = request.arguments; - response = this.getBraceMatching(braceArguments.line, braceArguments.offset, braceArguments.file); - break; - } - case CommandNames.NavBar: { - var navBarArgs = request.arguments; - response = this.getNavigationBarItems(navBarArgs.file); - break; - } - case CommandNames.Occurrences: { - var _a = request.arguments, line = _a.line, offset = _a.offset, fileName = _a.file; - response = this.getOccurrences(line, offset, fileName); - break; - } - case CommandNames.ProjectInfo: { - var _b = request.arguments, file = _b.file, needFileNameList = _b.needFileNameList; - response = this.getProjectInfo(file, needFileNameList); - break; - } - default: { - this.projectService.log("Unrecognized JSON command: " + message); - this.output(undefined, CommandNames.Unknown, request.seq, "Unrecognized JSON command: " + request.command); - break; - } - } + var _a = this.executeCommand(request), response = _a.response, responseRequired = _a.responseRequired; if (this.logger.isVerbose()) { var elapsed = this.hrtime(start); var seconds = elapsed[0]; @@ -42027,6 +42072,11 @@ var ts; var decoded = JSON.parse(encoded); return ts.createTextChangeRange(ts.createTextSpan(decoded.span.start, decoded.span.length), decoded.newLength); }; + ScriptSnapshotShimAdapter.prototype.dispose = function () { + if ("dispose" in this.scriptSnapshotShim) { + this.scriptSnapshotShim.dispose(); + } + }; return ScriptSnapshotShimAdapter; })(); var LanguageServiceShimHostAdapter = (function () { diff --git a/bin/typescript.d.ts b/bin/typescript.d.ts index 869fbb32d98..ee69b9ca909 100644 --- a/bin/typescript.d.ts +++ b/bin/typescript.d.ts @@ -1591,6 +1591,8 @@ declare module "typescript" { * not happen and the entire document will be re - parsed. */ getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange; + /** Releases all resources held by this script snapshot */ + dispose?(): void; } module ScriptSnapshot { function fromString(text: string): IScriptSnapshot; diff --git a/bin/typescript.js b/bin/typescript.js index 219a0b3924f..6035d71fa2b 100644 --- a/bin/typescript.js +++ b/bin/typescript.js @@ -1775,8 +1775,15 @@ var ts; newLine: _os.EOL, useCaseSensitiveFileNames: useCaseSensitiveFileNames, write: function (s) { + var buffer = new Buffer(s, 'utf8'); + var offset = 0; + var toWrite = buffer.length; + var written = 0; // 1 is a standard descriptor for stdout - _fs.writeSync(1, s); + while ((written = _fs.writeSync(1, buffer, offset, toWrite)) < toWrite) { + offset += written; + toWrite -= written; + } }, readFile: readFile, writeFile: writeFile, @@ -2247,7 +2254,7 @@ var ts; Classes_containing_abstract_methods_must_be_marked_abstract: { code: 2514, category: ts.DiagnosticCategory.Error, key: "Classes containing abstract methods must be marked abstract." }, Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2: { code: 2515, category: ts.DiagnosticCategory.Error, key: "Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'." }, All_declarations_of_an_abstract_method_must_be_consecutive: { code: 2516, category: ts.DiagnosticCategory.Error, key: "All declarations of an abstract method must be consecutive." }, - Constructor_objects_of_abstract_type_cannot_be_assigned_to_constructor_objects_of_non_abstract_type: { code: 2517, category: ts.DiagnosticCategory.Error, key: "Constructor objects of abstract type cannot be assigned to constructor objects of non-abstract type" }, + Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type: { code: 2517, category: ts.DiagnosticCategory.Error, key: "Cannot assign an abstract constructor type to a non-abstract constructor type." }, Only_an_ambient_class_can_be_merged_with_an_interface: { code: 2518, category: ts.DiagnosticCategory.Error, key: "Only an ambient class can be merged with an interface." }, Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions: { code: 2520, category: ts.DiagnosticCategory.Error, key: "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions." }, Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions: { code: 2521, category: ts.DiagnosticCategory.Error, key: "Expression resolves to variable declaration '{0}' that compiler uses to support async functions." }, @@ -11517,7 +11524,11 @@ var ts; } else { node.exportClause = parseNamedImportsOrExports(226 /* NamedExports */); - if (parseOptional(130 /* FromKeyword */)) { + // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios, + // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`) + // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect. + if (token === 130 /* FromKeyword */ || (token === 8 /* StringLiteral */ && !scanner.hasPrecedingLineBreak())) { + parseExpected(130 /* FromKeyword */); node.moduleSpecifier = parseModuleSpecifier(); } } @@ -16299,7 +16310,7 @@ var ts; var id = getTypeListId(elementTypes); var type = tupleTypes[id]; if (!type) { - type = tupleTypes[id] = createObjectType(8192 /* Tuple */); + type = tupleTypes[id] = createObjectType(8192 /* Tuple */ | getWideningFlagsOfTypes(elementTypes)); type.elementTypes = elementTypes; } return type; @@ -17200,10 +17211,33 @@ var ts; var targetSignatures = getSignaturesOfType(target, kind); var result = -1 /* True */; var saveErrorInfo = errorInfo; + // Because the "abstractness" of a class is the same across all construct signatures + // (internally we are checking the corresponding declaration), it is enough to perform + // the check and report an error once over all pairs of source and target construct signatures. + var sourceSig = sourceSignatures[0]; + // Note that in an extends-clause, targetSignatures is stripped, so the check never proceeds. + var targetSig = targetSignatures[0]; + if (sourceSig && targetSig) { + var sourceErasedSignature = getErasedSignature(sourceSig); + var targetErasedSignature = getErasedSignature(targetSig); + var sourceReturnType = sourceErasedSignature && getReturnTypeOfSignature(sourceErasedSignature); + var targetReturnType = targetErasedSignature && getReturnTypeOfSignature(targetErasedSignature); + var sourceReturnDecl = sourceReturnType && sourceReturnType.symbol && ts.getDeclarationOfKind(sourceReturnType.symbol, 211 /* ClassDeclaration */); + var targetReturnDecl = targetReturnType && targetReturnType.symbol && ts.getDeclarationOfKind(targetReturnType.symbol, 211 /* ClassDeclaration */); + var sourceIsAbstract = sourceReturnDecl && sourceReturnDecl.flags & 256 /* Abstract */; + var targetIsAbstract = targetReturnDecl && targetReturnDecl.flags & 256 /* Abstract */; + if (sourceIsAbstract && !targetIsAbstract) { + if (reportErrors) { + reportError(ts.Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type); + } + return 0 /* False */; + } + } outer: for (var _i = 0; _i < targetSignatures.length; _i++) { var t = targetSignatures[_i]; if (!t.hasStringLiterals || target.flags & 262144 /* FromSignature */) { var localErrors = reportErrors; + var checkedAbstractAssignability = false; for (var _a = 0; _a < sourceSignatures.length; _a++) { var s = sourceSignatures[_a]; if (!s.hasStringLiterals || source.flags & 262144 /* FromSignature */) { @@ -17254,12 +17288,12 @@ var ts; target = getErasedSignature(target); var result = -1 /* True */; for (var i = 0; i < checkCount; i++) { - var s_1 = i < sourceMax ? getTypeOfSymbol(source.parameters[i]) : getRestTypeOfSignature(source); - var t_1 = i < targetMax ? getTypeOfSymbol(target.parameters[i]) : getRestTypeOfSignature(target); + var s = i < sourceMax ? getTypeOfSymbol(source.parameters[i]) : getRestTypeOfSignature(source); + var t = i < targetMax ? getTypeOfSymbol(target.parameters[i]) : getRestTypeOfSignature(target); var saveErrorInfo = errorInfo; - var related = isRelatedTo(s_1, t_1, reportErrors); + var related = isRelatedTo(s, t, reportErrors); if (!related) { - related = isRelatedTo(t_1, s_1, false); + related = isRelatedTo(t, s, false); if (!related) { if (reportErrors) { reportError(ts.Diagnostics.Types_of_parameters_0_and_1_are_incompatible, source.parameters[i < sourceMax ? i : sourceMax].name, target.parameters[i < targetMax ? i : targetMax].name); @@ -17297,11 +17331,11 @@ var ts; } return 0 /* False */; } - var t = getReturnTypeOfSignature(target); - if (t === voidType) + var targetReturnType = getReturnTypeOfSignature(target); + if (targetReturnType === voidType) return result; - var s = getReturnTypeOfSignature(source); - return result & isRelatedTo(s, t, reportErrors); + var sourceReturnType = getReturnTypeOfSignature(source); + return result & isRelatedTo(sourceReturnType, targetReturnType, reportErrors); } function signaturesIdenticalTo(source, target, kind) { var sourceSignatures = getSignaturesOfType(source, kind); @@ -17537,7 +17571,7 @@ var ts; * Prefer using isTupleLikeType() unless the use of `elementTypes` is required. */ function isTupleType(type) { - return (type.flags & 8192 /* Tuple */) && !!type.elementTypes; + return !!(type.flags & 8192 /* Tuple */); } function getWidenedTypeOfObjectLiteral(type) { var properties = getPropertiesOfObjectType(type); @@ -17579,25 +17613,47 @@ var ts; if (isArrayType(type)) { return createArrayType(getWidenedType(type.typeArguments[0])); } + if (isTupleType(type)) { + return createTupleType(ts.map(type.elementTypes, getWidenedType)); + } } return type; } + /** + * Reports implicit any errors that occur as a result of widening 'null' and 'undefined' + * to 'any'. A call to reportWideningErrorsInType is normally accompanied by a call to + * getWidenedType. But in some cases getWidenedType is called without reporting errors + * (type argument inference is an example). + * + * The return value indicates whether an error was in fact reported. The particular circumstances + * are on a best effort basis. Currently, if the null or undefined that causes widening is inside + * an object literal property (arbitrarily deeply), this function reports an error. If no error is + * reported, reportImplicitAnyError is a suitable fallback to report a general error. + */ function reportWideningErrorsInType(type) { + var errorReported = false; if (type.flags & 16384 /* Union */) { - var errorReported = false; - ts.forEach(type.types, function (t) { + for (var _i = 0, _a = type.types; _i < _a.length; _i++) { + var t = _a[_i]; if (reportWideningErrorsInType(t)) { errorReported = true; } - }); - return errorReported; + } } if (isArrayType(type)) { return reportWideningErrorsInType(type.typeArguments[0]); } + if (isTupleType(type)) { + for (var _b = 0, _c = type.elementTypes; _b < _c.length; _b++) { + var t = _c[_b]; + if (reportWideningErrorsInType(t)) { + errorReported = true; + } + } + } if (type.flags & 524288 /* ObjectLiteral */) { - var errorReported = false; - ts.forEach(getPropertiesOfObjectType(type), function (p) { + for (var _d = 0, _e = getPropertiesOfObjectType(type); _d < _e.length; _d++) { + var p = _e[_d]; var t = getTypeOfSymbol(p); if (t.flags & 1048576 /* ContainsUndefinedOrNull */) { if (!reportWideningErrorsInType(t)) { @@ -17605,10 +17661,9 @@ var ts; } errorReported = true; } - }); - return errorReported; + } } - return false; + return errorReported; } function reportImplicitAnyError(declaration, type) { var typeAsString = typeToString(getWidenedType(type)); @@ -17771,29 +17826,32 @@ var ts; inferFromTypes(sourceType, target); } } - else if (source.flags & 80896 /* ObjectType */ && (target.flags & (4096 /* Reference */ | 8192 /* Tuple */) || - (target.flags & 65536 /* Anonymous */) && target.symbol && target.symbol.flags & (8192 /* Method */ | 2048 /* TypeLiteral */ | 32 /* Class */))) { - // If source is an object type, and target is a type reference, a tuple type, the type of a method, or a type literal, infer from members - if (isInProcess(source, target)) { - return; + else { + source = getApparentType(source); + if (source.flags & 80896 /* ObjectType */ && (target.flags & (4096 /* Reference */ | 8192 /* Tuple */) || + (target.flags & 65536 /* Anonymous */) && target.symbol && target.symbol.flags & (8192 /* Method */ | 2048 /* TypeLiteral */ | 32 /* Class */))) { + // If source is an object type, and target is a type reference, a tuple type, the type of a method, or a type literal, infer from members + if (isInProcess(source, target)) { + return; + } + if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) { + return; + } + if (depth === 0) { + sourceStack = []; + targetStack = []; + } + sourceStack[depth] = source; + targetStack[depth] = target; + depth++; + inferFromProperties(source, target); + inferFromSignatures(source, target, 0 /* Call */); + inferFromSignatures(source, target, 1 /* Construct */); + inferFromIndexTypes(source, target, 0 /* String */, 0 /* String */); + inferFromIndexTypes(source, target, 1 /* Number */, 1 /* Number */); + inferFromIndexTypes(source, target, 0 /* String */, 1 /* Number */); + depth--; } - if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) { - return; - } - if (depth === 0) { - sourceStack = []; - targetStack = []; - } - sourceStack[depth] = source; - targetStack[depth] = target; - depth++; - inferFromProperties(source, target); - inferFromSignatures(source, target, 0 /* Call */); - inferFromSignatures(source, target, 1 /* Construct */); - inferFromIndexTypes(source, target, 0 /* String */, 0 /* String */); - inferFromIndexTypes(source, target, 1 /* Number */, 1 /* Number */); - inferFromIndexTypes(source, target, 0 /* String */, 1 /* Number */); - depth--; } } function inferFromProperties(source, target) { @@ -37768,8 +37826,8 @@ var ts; var pos = scanner.getStartPos(); // Read leading trivia and token while (pos < endPos) { - var t_2 = scanner.getToken(); - if (!ts.isTrivia(t_2)) { + var t_1 = scanner.getToken(); + if (!ts.isTrivia(t_1)) { break; } // consume leading trivia @@ -37777,7 +37835,7 @@ var ts; var item = { pos: pos, end: scanner.getStartPos(), - kind: t_2 + kind: t_1 }; pos = scanner.getStartPos(); if (!leadingTrivia) { @@ -39359,6 +39417,8 @@ var ts; case 15 /* CloseBraceToken */: case 18 /* OpenBracketToken */: case 19 /* CloseBracketToken */: + case 16 /* OpenParenToken */: + case 17 /* CloseParenToken */: case 77 /* ElseKeyword */: case 101 /* WhileKeyword */: case 53 /* AtToken */: @@ -39483,7 +39543,7 @@ var ts; else if (tokenInfo.token.kind === listStartToken) { // consume list start token startLine = sourceFile.getLineAndCharacterOfPosition(tokenInfo.token.pos).line; - var indentation_1 = computeIndentation(tokenInfo.token, startLine, -1 /* Unknown */, parent, parentDynamicIndentation, startLine); + var indentation_1 = computeIndentation(tokenInfo.token, startLine, -1 /* Unknown */, parent, parentDynamicIndentation, parentStartLine); listDynamicIndentation = getDynamicIndentation(parent, parentStartLine, indentation_1.indentation, indentation_1.delta); consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation); } @@ -41389,6 +41449,13 @@ var ts; // after incremental parsing nameTable might not be up-to-date // drop it so it can be lazily recreated later newSourceFile.nameTable = undefined; + // dispose all resources held by old script snapshot + if (sourceFile !== newSourceFile && sourceFile.scriptSnapshot) { + if (sourceFile.scriptSnapshot.dispose) { + sourceFile.scriptSnapshot.dispose(); + } + sourceFile.scriptSnapshot = undefined; + } return newSourceFile; } } @@ -42410,15 +42477,15 @@ var ts; } function tryGetGlobalSymbols() { var objectLikeContainer; - var importClause; + var namedImportsOrExports; var jsxContainer; if (objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken)) { return tryGetObjectLikeCompletionSymbols(objectLikeContainer); } - if (importClause = ts.getAncestor(contextToken, 220 /* ImportClause */)) { + if (namedImportsOrExports = tryGetNamedImportsOrExportsForCompletion(contextToken)) { // cursor is in an import clause // try to show exported member for imported module - return tryGetImportClauseCompletionSymbols(importClause); + return tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports); } if (jsxContainer = tryGetContainingJsxElement(contextToken)) { var attrsType; @@ -42426,7 +42493,7 @@ var ts; // Cursor is inside a JSX self-closing element or opening element attrsType = typeChecker.getJsxElementAttributesType(jsxContainer); if (attrsType) { - symbols = filterJsxAttributes(jsxContainer.attributes, typeChecker.getPropertiesOfType(attrsType)); + symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), jsxContainer.attributes); isMemberCompletion = true; isNewIdentifierLocation = false; return true; @@ -42487,21 +42554,11 @@ var ts; function isCompletionListBlocker(contextToken) { var start = new Date().getTime(); var result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) || - isIdentifierDefinitionLocation(contextToken) || + isSolelyIdentifierDefinitionLocation(contextToken) || isDotOfNumericLiteral(contextToken); log("getCompletionsAtPosition: isCompletionListBlocker: " + (new Date().getTime() - start)); return result; } - function shouldShowCompletionsInImportsClause(node) { - if (node) { - // import {| - // import {a,| - if (node.kind === 14 /* OpenBraceToken */ || node.kind === 23 /* CommaToken */) { - return node.parent.kind === 222 /* NamedImports */; - } - } - return false; - } function isNewIdentifierDefinitionLocation(previousToken) { if (previousToken) { var containingNodeKind = previousToken.parent.kind; @@ -42610,34 +42667,37 @@ var ts; return true; } /** - * Aggregates relevant symbols for completion in import clauses; for instance, + * Aggregates relevant symbols for completion in import clauses and export clauses + * whose declarations have a module specifier; for instance, symbols will be aggregated for * - * import { $ } from "moduleName"; + * import { | } from "moduleName"; + * export { a as foo, | } from "moduleName"; + * + * but not for + * + * export { | }; * * Relevant symbols are stored in the captured 'symbols' variable. * * @returns true if 'symbols' was successfully populated; false otherwise. */ - function tryGetImportClauseCompletionSymbols(importClause) { - // cursor is in import clause - // try to show exported member for imported module - if (shouldShowCompletionsInImportsClause(contextToken)) { - isMemberCompletion = true; - isNewIdentifierLocation = false; - var importDeclaration = importClause.parent; - ts.Debug.assert(importDeclaration !== undefined && importDeclaration.kind === 219 /* ImportDeclaration */); - var exports; - var moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importDeclaration.moduleSpecifier); - if (moduleSpecifierSymbol) { - exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol); - } - //let exports = typeInfoResolver.getExportsOfImportDeclaration(importDeclaration); - symbols = exports ? filterModuleExports(exports, importDeclaration) : emptyArray; + function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports) { + var declarationKind = namedImportsOrExports.kind === 222 /* NamedImports */ ? + 219 /* ImportDeclaration */ : + 225 /* ExportDeclaration */; + var importOrExportDeclaration = ts.getAncestor(namedImportsOrExports, declarationKind); + var moduleSpecifier = importOrExportDeclaration.moduleSpecifier; + if (!moduleSpecifier) { + return false; } - else { - isMemberCompletion = false; - isNewIdentifierLocation = true; + isMemberCompletion = true; + isNewIdentifierLocation = false; + var exports; + var moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier); + if (moduleSpecifierSymbol) { + exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol); } + symbols = exports ? filterNamedImportOrExportCompletionItems(exports, namedImportsOrExports.elements) : emptyArray; return true; } /** @@ -42658,6 +42718,24 @@ var ts; } return undefined; } + /** + * Returns the containing list of named imports or exports of a context token, + * on the condition that one exists and that the context implies completion should be given. + */ + function tryGetNamedImportsOrExportsForCompletion(contextToken) { + if (contextToken) { + switch (contextToken.kind) { + case 14 /* OpenBraceToken */: // import { | + case 23 /* CommaToken */: + switch (contextToken.parent.kind) { + case 222 /* NamedImports */: + case 226 /* NamedExports */: + return contextToken.parent; + } + } + } + return undefined; + } function tryGetContainingJsxElement(contextToken) { if (contextToken) { var parent_12 = contextToken.parent; @@ -42700,7 +42778,10 @@ var ts; } return false; } - function isIdentifierDefinitionLocation(contextToken) { + /** + * @returns true if we are certain that the currently edited location must define a new location; false otherwise. + */ + function isSolelyIdentifierDefinitionLocation(contextToken) { var containingNodeKind = contextToken.parent.kind; switch (contextToken.kind) { case 23 /* CommaToken */: @@ -42746,6 +42827,10 @@ var ts; case 107 /* PrivateKeyword */: case 108 /* ProtectedKeyword */: return containingNodeKind === 135 /* Parameter */; + case 113 /* AsKeyword */: + containingNodeKind === 223 /* ImportSpecifier */ || + containingNodeKind === 227 /* ExportSpecifier */ || + containingNodeKind === 221 /* NamespaceImport */; case 70 /* ClassKeyword */: case 78 /* EnumKeyword */: case 104 /* InterfaceKeyword */: @@ -42782,27 +42867,37 @@ var ts; } return false; } - function filterModuleExports(exports, importDeclaration) { - var exisingImports = {}; - if (!importDeclaration.importClause) { - return exports; + /** + * Filters out completion suggestions for named imports or exports. + * + * @param exportsOfModule The list of symbols which a module exposes. + * @param namedImportsOrExports The list of existing import/export specifiers in the import/export clause. + * + * @returns Symbols to be suggested at an import/export clause, barring those whose named imports/exports + * do not occur at the current position and have not otherwise been typed. + */ + function filterNamedImportOrExportCompletionItems(exportsOfModule, namedImportsOrExports) { + var exisingImportsOrExports = {}; + for (var _i = 0; _i < namedImportsOrExports.length; _i++) { + var element = namedImportsOrExports[_i]; + // If this is the current item we are editing right now, do not filter it out + if (element.getStart() <= position && position <= element.getEnd()) { + continue; + } + var name_31 = element.propertyName || element.name; + exisingImportsOrExports[name_31.text] = true; } - if (importDeclaration.importClause.namedBindings && - importDeclaration.importClause.namedBindings.kind === 222 /* NamedImports */) { - ts.forEach(importDeclaration.importClause.namedBindings.elements, function (el) { - // If this is the current item we are editing right now, do not filter it out - if (el.getStart() <= position && position <= el.getEnd()) { - return; - } - var name = el.propertyName || el.name; - exisingImports[name.text] = true; - }); + if (ts.isEmpty(exisingImportsOrExports)) { + return exportsOfModule; } - if (ts.isEmpty(exisingImports)) { - return exports; - } - return ts.filter(exports, function (e) { return !ts.lookUp(exisingImports, e.name); }); + return ts.filter(exportsOfModule, function (e) { return !ts.lookUp(exisingImportsOrExports, e.name); }); } + /** + * Filters out completion suggestions for named imports or exports. + * + * @returns Symbols to be suggested in an object binding pattern or object literal expression, barring those whose declarations + * do not occur at the current position and have not otherwise been typed. + */ function filterObjectMembersList(contextualMemberSymbols, existingMembers) { if (!existingMembers || existingMembers.length === 0) { return contextualMemberSymbols; @@ -42832,15 +42927,15 @@ var ts; } existingMemberNames[existingName] = true; } - var filteredMembers = []; - ts.forEach(contextualMemberSymbols, function (s) { - if (!existingMemberNames[s.name]) { - filteredMembers.push(s); - } - }); - return filteredMembers; + return ts.filter(contextualMemberSymbols, function (m) { return !ts.lookUp(existingMemberNames, m.name); }); } - function filterJsxAttributes(attributes, symbols) { + /** + * Filters out completion suggestions from 'symbols' according to existing JSX attributes. + * + * @returns Symbols to be suggested in a JSX element, barring those whose attributes + * do not occur at the current position and have not otherwise been typed. + */ + function filterJsxAttributes(symbols, attributes) { var seenNames = {}; for (var _i = 0; _i < attributes.length; _i++) { var attr = attributes[_i]; @@ -42852,14 +42947,7 @@ var ts; seenNames[attr.name.text] = true; } } - var result = []; - for (var _a = 0; _a < symbols.length; _a++) { - var sym = symbols[_a]; - if (!seenNames[sym.name]) { - result.push(sym); - } - } - return result; + return ts.filter(symbols, function (a) { return !ts.lookUp(seenNames, a.name); }); } } function getCompletionsAtPosition(fileName, position) { @@ -42892,10 +42980,10 @@ var ts; for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { var sourceFile = _a[_i]; var nameTable = getNameTable(sourceFile); - for (var name_31 in nameTable) { - if (!allNames[name_31]) { - allNames[name_31] = name_31; - var displayName = getCompletionEntryDisplayName(name_31, target, true); + for (var name_32 in nameTable) { + if (!allNames[name_32]) { + allNames[name_32] = name_32; + var displayName = getCompletionEntryDisplayName(name_32, target, true); if (displayName) { var entry = { name: displayName, @@ -43764,6 +43852,7 @@ var ts; if (hasKind(node.parent, 142 /* GetAccessor */) || hasKind(node.parent, 143 /* SetAccessor */)) { return getGetAndSetOccurrences(node.parent); } + break; default: if (ts.isModifier(node.kind) && node.parent && (ts.isDeclaration(node.parent) || node.parent.kind === 190 /* VariableStatement */)) { @@ -43879,12 +43968,13 @@ var ts; // Make sure we only highlight the keyword when it makes sense to do so. if (ts.isAccessibilityModifier(modifier)) { if (!(container.kind === 211 /* ClassDeclaration */ || + container.kind === 183 /* ClassExpression */ || (declaration.kind === 135 /* Parameter */ && hasKind(container, 141 /* Constructor */)))) { return undefined; } } else if (modifier === 110 /* StaticKeyword */) { - if (container.kind !== 211 /* ClassDeclaration */) { + if (!(container.kind === 211 /* ClassDeclaration */ || container.kind === 183 /* ClassExpression */)) { return undefined; } } @@ -43893,6 +43983,11 @@ var ts; return undefined; } } + else if (modifier === 112 /* AbstractKeyword */) { + if (!(container.kind === 211 /* ClassDeclaration */ || declaration.kind === 211 /* ClassDeclaration */)) { + return undefined; + } + } else { // unsupported modifier return undefined; @@ -43903,12 +43998,19 @@ var ts; switch (container.kind) { case 216 /* ModuleBlock */: case 245 /* SourceFile */: - nodes = container.statements; + // Container is either a class declaration or the declaration is a classDeclaration + if (modifierFlag & 256 /* Abstract */) { + nodes = declaration.members.concat(declaration); + } + else { + nodes = container.statements; + } break; case 141 /* Constructor */: nodes = container.parameters.concat(container.parent.members); break; case 211 /* ClassDeclaration */: + case 183 /* ClassExpression */: nodes = container.members; // If we're an accessibility modifier, we're in an instance member and should search // the constructor's parameter list for instance members as well. @@ -43920,6 +44022,9 @@ var ts; nodes = nodes.concat(constructor.parameters); } } + else if (modifierFlag & 256 /* Abstract */) { + nodes = nodes.concat(container); + } break; default: ts.Debug.fail("Invalid container kind."); @@ -43944,6 +44049,8 @@ var ts; return 1 /* Export */; case 119 /* DeclareKeyword */: return 2 /* Ambient */; + case 112 /* AbstractKeyword */: + return 256 /* Abstract */; default: ts.Debug.fail(); } @@ -44761,19 +44868,19 @@ var ts; if (isNameOfPropertyAssignment(node)) { var objectLiteral = node.parent.parent; var contextualType = typeChecker.getContextualType(objectLiteral); - var name_32 = node.text; + var name_33 = node.text; if (contextualType) { if (contextualType.flags & 16384 /* Union */) { // This is a union type, first see if the property we are looking for is a union property (i.e. exists in all types) // if not, search the constituent types for the property - var unionProperty = contextualType.getProperty(name_32); + var unionProperty = contextualType.getProperty(name_33); if (unionProperty) { return [unionProperty]; } else { var result_4 = []; ts.forEach(contextualType.types, function (t) { - var symbol = t.getProperty(name_32); + var symbol = t.getProperty(name_33); if (symbol) { result_4.push(symbol); } @@ -44782,7 +44889,7 @@ var ts; } } else { - var symbol_1 = contextualType.getProperty(name_32); + var symbol_1 = contextualType.getProperty(name_33); if (symbol_1) { return [symbol_1]; } @@ -45464,7 +45571,7 @@ var ts; return; } } - return 9 /* text */; + return 2 /* identifier */; } } function processElement(element) { @@ -46760,6 +46867,13 @@ var ts; var decoded = JSON.parse(encoded); return ts.createTextChangeRange(ts.createTextSpan(decoded.span.start, decoded.span.length), decoded.newLength); }; + ScriptSnapshotShimAdapter.prototype.dispose = function () { + // if scriptSnapshotShim is a COM object then property check becomes method call with no arguments + // 'in' does not have this effect + if ("dispose" in this.scriptSnapshotShim) { + this.scriptSnapshotShim.dispose(); + } + }; return ScriptSnapshotShimAdapter; })(); var LanguageServiceShimHostAdapter = (function () { diff --git a/bin/typescriptServices.d.ts b/bin/typescriptServices.d.ts index cea8225468b..9840a5e688f 100644 --- a/bin/typescriptServices.d.ts +++ b/bin/typescriptServices.d.ts @@ -1591,6 +1591,8 @@ declare namespace ts { * not happen and the entire document will be re - parsed. */ getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange; + /** Releases all resources held by this script snapshot */ + dispose?(): void; } module ScriptSnapshot { function fromString(text: string): IScriptSnapshot; diff --git a/bin/typescriptServices.js b/bin/typescriptServices.js index 219a0b3924f..6035d71fa2b 100644 --- a/bin/typescriptServices.js +++ b/bin/typescriptServices.js @@ -1775,8 +1775,15 @@ var ts; newLine: _os.EOL, useCaseSensitiveFileNames: useCaseSensitiveFileNames, write: function (s) { + var buffer = new Buffer(s, 'utf8'); + var offset = 0; + var toWrite = buffer.length; + var written = 0; // 1 is a standard descriptor for stdout - _fs.writeSync(1, s); + while ((written = _fs.writeSync(1, buffer, offset, toWrite)) < toWrite) { + offset += written; + toWrite -= written; + } }, readFile: readFile, writeFile: writeFile, @@ -2247,7 +2254,7 @@ var ts; Classes_containing_abstract_methods_must_be_marked_abstract: { code: 2514, category: ts.DiagnosticCategory.Error, key: "Classes containing abstract methods must be marked abstract." }, Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2: { code: 2515, category: ts.DiagnosticCategory.Error, key: "Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'." }, All_declarations_of_an_abstract_method_must_be_consecutive: { code: 2516, category: ts.DiagnosticCategory.Error, key: "All declarations of an abstract method must be consecutive." }, - Constructor_objects_of_abstract_type_cannot_be_assigned_to_constructor_objects_of_non_abstract_type: { code: 2517, category: ts.DiagnosticCategory.Error, key: "Constructor objects of abstract type cannot be assigned to constructor objects of non-abstract type" }, + Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type: { code: 2517, category: ts.DiagnosticCategory.Error, key: "Cannot assign an abstract constructor type to a non-abstract constructor type." }, Only_an_ambient_class_can_be_merged_with_an_interface: { code: 2518, category: ts.DiagnosticCategory.Error, key: "Only an ambient class can be merged with an interface." }, Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions: { code: 2520, category: ts.DiagnosticCategory.Error, key: "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions." }, Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions: { code: 2521, category: ts.DiagnosticCategory.Error, key: "Expression resolves to variable declaration '{0}' that compiler uses to support async functions." }, @@ -11517,7 +11524,11 @@ var ts; } else { node.exportClause = parseNamedImportsOrExports(226 /* NamedExports */); - if (parseOptional(130 /* FromKeyword */)) { + // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios, + // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`) + // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect. + if (token === 130 /* FromKeyword */ || (token === 8 /* StringLiteral */ && !scanner.hasPrecedingLineBreak())) { + parseExpected(130 /* FromKeyword */); node.moduleSpecifier = parseModuleSpecifier(); } } @@ -16299,7 +16310,7 @@ var ts; var id = getTypeListId(elementTypes); var type = tupleTypes[id]; if (!type) { - type = tupleTypes[id] = createObjectType(8192 /* Tuple */); + type = tupleTypes[id] = createObjectType(8192 /* Tuple */ | getWideningFlagsOfTypes(elementTypes)); type.elementTypes = elementTypes; } return type; @@ -17200,10 +17211,33 @@ var ts; var targetSignatures = getSignaturesOfType(target, kind); var result = -1 /* True */; var saveErrorInfo = errorInfo; + // Because the "abstractness" of a class is the same across all construct signatures + // (internally we are checking the corresponding declaration), it is enough to perform + // the check and report an error once over all pairs of source and target construct signatures. + var sourceSig = sourceSignatures[0]; + // Note that in an extends-clause, targetSignatures is stripped, so the check never proceeds. + var targetSig = targetSignatures[0]; + if (sourceSig && targetSig) { + var sourceErasedSignature = getErasedSignature(sourceSig); + var targetErasedSignature = getErasedSignature(targetSig); + var sourceReturnType = sourceErasedSignature && getReturnTypeOfSignature(sourceErasedSignature); + var targetReturnType = targetErasedSignature && getReturnTypeOfSignature(targetErasedSignature); + var sourceReturnDecl = sourceReturnType && sourceReturnType.symbol && ts.getDeclarationOfKind(sourceReturnType.symbol, 211 /* ClassDeclaration */); + var targetReturnDecl = targetReturnType && targetReturnType.symbol && ts.getDeclarationOfKind(targetReturnType.symbol, 211 /* ClassDeclaration */); + var sourceIsAbstract = sourceReturnDecl && sourceReturnDecl.flags & 256 /* Abstract */; + var targetIsAbstract = targetReturnDecl && targetReturnDecl.flags & 256 /* Abstract */; + if (sourceIsAbstract && !targetIsAbstract) { + if (reportErrors) { + reportError(ts.Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type); + } + return 0 /* False */; + } + } outer: for (var _i = 0; _i < targetSignatures.length; _i++) { var t = targetSignatures[_i]; if (!t.hasStringLiterals || target.flags & 262144 /* FromSignature */) { var localErrors = reportErrors; + var checkedAbstractAssignability = false; for (var _a = 0; _a < sourceSignatures.length; _a++) { var s = sourceSignatures[_a]; if (!s.hasStringLiterals || source.flags & 262144 /* FromSignature */) { @@ -17254,12 +17288,12 @@ var ts; target = getErasedSignature(target); var result = -1 /* True */; for (var i = 0; i < checkCount; i++) { - var s_1 = i < sourceMax ? getTypeOfSymbol(source.parameters[i]) : getRestTypeOfSignature(source); - var t_1 = i < targetMax ? getTypeOfSymbol(target.parameters[i]) : getRestTypeOfSignature(target); + var s = i < sourceMax ? getTypeOfSymbol(source.parameters[i]) : getRestTypeOfSignature(source); + var t = i < targetMax ? getTypeOfSymbol(target.parameters[i]) : getRestTypeOfSignature(target); var saveErrorInfo = errorInfo; - var related = isRelatedTo(s_1, t_1, reportErrors); + var related = isRelatedTo(s, t, reportErrors); if (!related) { - related = isRelatedTo(t_1, s_1, false); + related = isRelatedTo(t, s, false); if (!related) { if (reportErrors) { reportError(ts.Diagnostics.Types_of_parameters_0_and_1_are_incompatible, source.parameters[i < sourceMax ? i : sourceMax].name, target.parameters[i < targetMax ? i : targetMax].name); @@ -17297,11 +17331,11 @@ var ts; } return 0 /* False */; } - var t = getReturnTypeOfSignature(target); - if (t === voidType) + var targetReturnType = getReturnTypeOfSignature(target); + if (targetReturnType === voidType) return result; - var s = getReturnTypeOfSignature(source); - return result & isRelatedTo(s, t, reportErrors); + var sourceReturnType = getReturnTypeOfSignature(source); + return result & isRelatedTo(sourceReturnType, targetReturnType, reportErrors); } function signaturesIdenticalTo(source, target, kind) { var sourceSignatures = getSignaturesOfType(source, kind); @@ -17537,7 +17571,7 @@ var ts; * Prefer using isTupleLikeType() unless the use of `elementTypes` is required. */ function isTupleType(type) { - return (type.flags & 8192 /* Tuple */) && !!type.elementTypes; + return !!(type.flags & 8192 /* Tuple */); } function getWidenedTypeOfObjectLiteral(type) { var properties = getPropertiesOfObjectType(type); @@ -17579,25 +17613,47 @@ var ts; if (isArrayType(type)) { return createArrayType(getWidenedType(type.typeArguments[0])); } + if (isTupleType(type)) { + return createTupleType(ts.map(type.elementTypes, getWidenedType)); + } } return type; } + /** + * Reports implicit any errors that occur as a result of widening 'null' and 'undefined' + * to 'any'. A call to reportWideningErrorsInType is normally accompanied by a call to + * getWidenedType. But in some cases getWidenedType is called without reporting errors + * (type argument inference is an example). + * + * The return value indicates whether an error was in fact reported. The particular circumstances + * are on a best effort basis. Currently, if the null or undefined that causes widening is inside + * an object literal property (arbitrarily deeply), this function reports an error. If no error is + * reported, reportImplicitAnyError is a suitable fallback to report a general error. + */ function reportWideningErrorsInType(type) { + var errorReported = false; if (type.flags & 16384 /* Union */) { - var errorReported = false; - ts.forEach(type.types, function (t) { + for (var _i = 0, _a = type.types; _i < _a.length; _i++) { + var t = _a[_i]; if (reportWideningErrorsInType(t)) { errorReported = true; } - }); - return errorReported; + } } if (isArrayType(type)) { return reportWideningErrorsInType(type.typeArguments[0]); } + if (isTupleType(type)) { + for (var _b = 0, _c = type.elementTypes; _b < _c.length; _b++) { + var t = _c[_b]; + if (reportWideningErrorsInType(t)) { + errorReported = true; + } + } + } if (type.flags & 524288 /* ObjectLiteral */) { - var errorReported = false; - ts.forEach(getPropertiesOfObjectType(type), function (p) { + for (var _d = 0, _e = getPropertiesOfObjectType(type); _d < _e.length; _d++) { + var p = _e[_d]; var t = getTypeOfSymbol(p); if (t.flags & 1048576 /* ContainsUndefinedOrNull */) { if (!reportWideningErrorsInType(t)) { @@ -17605,10 +17661,9 @@ var ts; } errorReported = true; } - }); - return errorReported; + } } - return false; + return errorReported; } function reportImplicitAnyError(declaration, type) { var typeAsString = typeToString(getWidenedType(type)); @@ -17771,29 +17826,32 @@ var ts; inferFromTypes(sourceType, target); } } - else if (source.flags & 80896 /* ObjectType */ && (target.flags & (4096 /* Reference */ | 8192 /* Tuple */) || - (target.flags & 65536 /* Anonymous */) && target.symbol && target.symbol.flags & (8192 /* Method */ | 2048 /* TypeLiteral */ | 32 /* Class */))) { - // If source is an object type, and target is a type reference, a tuple type, the type of a method, or a type literal, infer from members - if (isInProcess(source, target)) { - return; + else { + source = getApparentType(source); + if (source.flags & 80896 /* ObjectType */ && (target.flags & (4096 /* Reference */ | 8192 /* Tuple */) || + (target.flags & 65536 /* Anonymous */) && target.symbol && target.symbol.flags & (8192 /* Method */ | 2048 /* TypeLiteral */ | 32 /* Class */))) { + // If source is an object type, and target is a type reference, a tuple type, the type of a method, or a type literal, infer from members + if (isInProcess(source, target)) { + return; + } + if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) { + return; + } + if (depth === 0) { + sourceStack = []; + targetStack = []; + } + sourceStack[depth] = source; + targetStack[depth] = target; + depth++; + inferFromProperties(source, target); + inferFromSignatures(source, target, 0 /* Call */); + inferFromSignatures(source, target, 1 /* Construct */); + inferFromIndexTypes(source, target, 0 /* String */, 0 /* String */); + inferFromIndexTypes(source, target, 1 /* Number */, 1 /* Number */); + inferFromIndexTypes(source, target, 0 /* String */, 1 /* Number */); + depth--; } - if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) { - return; - } - if (depth === 0) { - sourceStack = []; - targetStack = []; - } - sourceStack[depth] = source; - targetStack[depth] = target; - depth++; - inferFromProperties(source, target); - inferFromSignatures(source, target, 0 /* Call */); - inferFromSignatures(source, target, 1 /* Construct */); - inferFromIndexTypes(source, target, 0 /* String */, 0 /* String */); - inferFromIndexTypes(source, target, 1 /* Number */, 1 /* Number */); - inferFromIndexTypes(source, target, 0 /* String */, 1 /* Number */); - depth--; } } function inferFromProperties(source, target) { @@ -37768,8 +37826,8 @@ var ts; var pos = scanner.getStartPos(); // Read leading trivia and token while (pos < endPos) { - var t_2 = scanner.getToken(); - if (!ts.isTrivia(t_2)) { + var t_1 = scanner.getToken(); + if (!ts.isTrivia(t_1)) { break; } // consume leading trivia @@ -37777,7 +37835,7 @@ var ts; var item = { pos: pos, end: scanner.getStartPos(), - kind: t_2 + kind: t_1 }; pos = scanner.getStartPos(); if (!leadingTrivia) { @@ -39359,6 +39417,8 @@ var ts; case 15 /* CloseBraceToken */: case 18 /* OpenBracketToken */: case 19 /* CloseBracketToken */: + case 16 /* OpenParenToken */: + case 17 /* CloseParenToken */: case 77 /* ElseKeyword */: case 101 /* WhileKeyword */: case 53 /* AtToken */: @@ -39483,7 +39543,7 @@ var ts; else if (tokenInfo.token.kind === listStartToken) { // consume list start token startLine = sourceFile.getLineAndCharacterOfPosition(tokenInfo.token.pos).line; - var indentation_1 = computeIndentation(tokenInfo.token, startLine, -1 /* Unknown */, parent, parentDynamicIndentation, startLine); + var indentation_1 = computeIndentation(tokenInfo.token, startLine, -1 /* Unknown */, parent, parentDynamicIndentation, parentStartLine); listDynamicIndentation = getDynamicIndentation(parent, parentStartLine, indentation_1.indentation, indentation_1.delta); consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation); } @@ -41389,6 +41449,13 @@ var ts; // after incremental parsing nameTable might not be up-to-date // drop it so it can be lazily recreated later newSourceFile.nameTable = undefined; + // dispose all resources held by old script snapshot + if (sourceFile !== newSourceFile && sourceFile.scriptSnapshot) { + if (sourceFile.scriptSnapshot.dispose) { + sourceFile.scriptSnapshot.dispose(); + } + sourceFile.scriptSnapshot = undefined; + } return newSourceFile; } } @@ -42410,15 +42477,15 @@ var ts; } function tryGetGlobalSymbols() { var objectLikeContainer; - var importClause; + var namedImportsOrExports; var jsxContainer; if (objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken)) { return tryGetObjectLikeCompletionSymbols(objectLikeContainer); } - if (importClause = ts.getAncestor(contextToken, 220 /* ImportClause */)) { + if (namedImportsOrExports = tryGetNamedImportsOrExportsForCompletion(contextToken)) { // cursor is in an import clause // try to show exported member for imported module - return tryGetImportClauseCompletionSymbols(importClause); + return tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports); } if (jsxContainer = tryGetContainingJsxElement(contextToken)) { var attrsType; @@ -42426,7 +42493,7 @@ var ts; // Cursor is inside a JSX self-closing element or opening element attrsType = typeChecker.getJsxElementAttributesType(jsxContainer); if (attrsType) { - symbols = filterJsxAttributes(jsxContainer.attributes, typeChecker.getPropertiesOfType(attrsType)); + symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), jsxContainer.attributes); isMemberCompletion = true; isNewIdentifierLocation = false; return true; @@ -42487,21 +42554,11 @@ var ts; function isCompletionListBlocker(contextToken) { var start = new Date().getTime(); var result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) || - isIdentifierDefinitionLocation(contextToken) || + isSolelyIdentifierDefinitionLocation(contextToken) || isDotOfNumericLiteral(contextToken); log("getCompletionsAtPosition: isCompletionListBlocker: " + (new Date().getTime() - start)); return result; } - function shouldShowCompletionsInImportsClause(node) { - if (node) { - // import {| - // import {a,| - if (node.kind === 14 /* OpenBraceToken */ || node.kind === 23 /* CommaToken */) { - return node.parent.kind === 222 /* NamedImports */; - } - } - return false; - } function isNewIdentifierDefinitionLocation(previousToken) { if (previousToken) { var containingNodeKind = previousToken.parent.kind; @@ -42610,34 +42667,37 @@ var ts; return true; } /** - * Aggregates relevant symbols for completion in import clauses; for instance, + * Aggregates relevant symbols for completion in import clauses and export clauses + * whose declarations have a module specifier; for instance, symbols will be aggregated for * - * import { $ } from "moduleName"; + * import { | } from "moduleName"; + * export { a as foo, | } from "moduleName"; + * + * but not for + * + * export { | }; * * Relevant symbols are stored in the captured 'symbols' variable. * * @returns true if 'symbols' was successfully populated; false otherwise. */ - function tryGetImportClauseCompletionSymbols(importClause) { - // cursor is in import clause - // try to show exported member for imported module - if (shouldShowCompletionsInImportsClause(contextToken)) { - isMemberCompletion = true; - isNewIdentifierLocation = false; - var importDeclaration = importClause.parent; - ts.Debug.assert(importDeclaration !== undefined && importDeclaration.kind === 219 /* ImportDeclaration */); - var exports; - var moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importDeclaration.moduleSpecifier); - if (moduleSpecifierSymbol) { - exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol); - } - //let exports = typeInfoResolver.getExportsOfImportDeclaration(importDeclaration); - symbols = exports ? filterModuleExports(exports, importDeclaration) : emptyArray; + function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports) { + var declarationKind = namedImportsOrExports.kind === 222 /* NamedImports */ ? + 219 /* ImportDeclaration */ : + 225 /* ExportDeclaration */; + var importOrExportDeclaration = ts.getAncestor(namedImportsOrExports, declarationKind); + var moduleSpecifier = importOrExportDeclaration.moduleSpecifier; + if (!moduleSpecifier) { + return false; } - else { - isMemberCompletion = false; - isNewIdentifierLocation = true; + isMemberCompletion = true; + isNewIdentifierLocation = false; + var exports; + var moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier); + if (moduleSpecifierSymbol) { + exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol); } + symbols = exports ? filterNamedImportOrExportCompletionItems(exports, namedImportsOrExports.elements) : emptyArray; return true; } /** @@ -42658,6 +42718,24 @@ var ts; } return undefined; } + /** + * Returns the containing list of named imports or exports of a context token, + * on the condition that one exists and that the context implies completion should be given. + */ + function tryGetNamedImportsOrExportsForCompletion(contextToken) { + if (contextToken) { + switch (contextToken.kind) { + case 14 /* OpenBraceToken */: // import { | + case 23 /* CommaToken */: + switch (contextToken.parent.kind) { + case 222 /* NamedImports */: + case 226 /* NamedExports */: + return contextToken.parent; + } + } + } + return undefined; + } function tryGetContainingJsxElement(contextToken) { if (contextToken) { var parent_12 = contextToken.parent; @@ -42700,7 +42778,10 @@ var ts; } return false; } - function isIdentifierDefinitionLocation(contextToken) { + /** + * @returns true if we are certain that the currently edited location must define a new location; false otherwise. + */ + function isSolelyIdentifierDefinitionLocation(contextToken) { var containingNodeKind = contextToken.parent.kind; switch (contextToken.kind) { case 23 /* CommaToken */: @@ -42746,6 +42827,10 @@ var ts; case 107 /* PrivateKeyword */: case 108 /* ProtectedKeyword */: return containingNodeKind === 135 /* Parameter */; + case 113 /* AsKeyword */: + containingNodeKind === 223 /* ImportSpecifier */ || + containingNodeKind === 227 /* ExportSpecifier */ || + containingNodeKind === 221 /* NamespaceImport */; case 70 /* ClassKeyword */: case 78 /* EnumKeyword */: case 104 /* InterfaceKeyword */: @@ -42782,27 +42867,37 @@ var ts; } return false; } - function filterModuleExports(exports, importDeclaration) { - var exisingImports = {}; - if (!importDeclaration.importClause) { - return exports; + /** + * Filters out completion suggestions for named imports or exports. + * + * @param exportsOfModule The list of symbols which a module exposes. + * @param namedImportsOrExports The list of existing import/export specifiers in the import/export clause. + * + * @returns Symbols to be suggested at an import/export clause, barring those whose named imports/exports + * do not occur at the current position and have not otherwise been typed. + */ + function filterNamedImportOrExportCompletionItems(exportsOfModule, namedImportsOrExports) { + var exisingImportsOrExports = {}; + for (var _i = 0; _i < namedImportsOrExports.length; _i++) { + var element = namedImportsOrExports[_i]; + // If this is the current item we are editing right now, do not filter it out + if (element.getStart() <= position && position <= element.getEnd()) { + continue; + } + var name_31 = element.propertyName || element.name; + exisingImportsOrExports[name_31.text] = true; } - if (importDeclaration.importClause.namedBindings && - importDeclaration.importClause.namedBindings.kind === 222 /* NamedImports */) { - ts.forEach(importDeclaration.importClause.namedBindings.elements, function (el) { - // If this is the current item we are editing right now, do not filter it out - if (el.getStart() <= position && position <= el.getEnd()) { - return; - } - var name = el.propertyName || el.name; - exisingImports[name.text] = true; - }); + if (ts.isEmpty(exisingImportsOrExports)) { + return exportsOfModule; } - if (ts.isEmpty(exisingImports)) { - return exports; - } - return ts.filter(exports, function (e) { return !ts.lookUp(exisingImports, e.name); }); + return ts.filter(exportsOfModule, function (e) { return !ts.lookUp(exisingImportsOrExports, e.name); }); } + /** + * Filters out completion suggestions for named imports or exports. + * + * @returns Symbols to be suggested in an object binding pattern or object literal expression, barring those whose declarations + * do not occur at the current position and have not otherwise been typed. + */ function filterObjectMembersList(contextualMemberSymbols, existingMembers) { if (!existingMembers || existingMembers.length === 0) { return contextualMemberSymbols; @@ -42832,15 +42927,15 @@ var ts; } existingMemberNames[existingName] = true; } - var filteredMembers = []; - ts.forEach(contextualMemberSymbols, function (s) { - if (!existingMemberNames[s.name]) { - filteredMembers.push(s); - } - }); - return filteredMembers; + return ts.filter(contextualMemberSymbols, function (m) { return !ts.lookUp(existingMemberNames, m.name); }); } - function filterJsxAttributes(attributes, symbols) { + /** + * Filters out completion suggestions from 'symbols' according to existing JSX attributes. + * + * @returns Symbols to be suggested in a JSX element, barring those whose attributes + * do not occur at the current position and have not otherwise been typed. + */ + function filterJsxAttributes(symbols, attributes) { var seenNames = {}; for (var _i = 0; _i < attributes.length; _i++) { var attr = attributes[_i]; @@ -42852,14 +42947,7 @@ var ts; seenNames[attr.name.text] = true; } } - var result = []; - for (var _a = 0; _a < symbols.length; _a++) { - var sym = symbols[_a]; - if (!seenNames[sym.name]) { - result.push(sym); - } - } - return result; + return ts.filter(symbols, function (a) { return !ts.lookUp(seenNames, a.name); }); } } function getCompletionsAtPosition(fileName, position) { @@ -42892,10 +42980,10 @@ var ts; for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { var sourceFile = _a[_i]; var nameTable = getNameTable(sourceFile); - for (var name_31 in nameTable) { - if (!allNames[name_31]) { - allNames[name_31] = name_31; - var displayName = getCompletionEntryDisplayName(name_31, target, true); + for (var name_32 in nameTable) { + if (!allNames[name_32]) { + allNames[name_32] = name_32; + var displayName = getCompletionEntryDisplayName(name_32, target, true); if (displayName) { var entry = { name: displayName, @@ -43764,6 +43852,7 @@ var ts; if (hasKind(node.parent, 142 /* GetAccessor */) || hasKind(node.parent, 143 /* SetAccessor */)) { return getGetAndSetOccurrences(node.parent); } + break; default: if (ts.isModifier(node.kind) && node.parent && (ts.isDeclaration(node.parent) || node.parent.kind === 190 /* VariableStatement */)) { @@ -43879,12 +43968,13 @@ var ts; // Make sure we only highlight the keyword when it makes sense to do so. if (ts.isAccessibilityModifier(modifier)) { if (!(container.kind === 211 /* ClassDeclaration */ || + container.kind === 183 /* ClassExpression */ || (declaration.kind === 135 /* Parameter */ && hasKind(container, 141 /* Constructor */)))) { return undefined; } } else if (modifier === 110 /* StaticKeyword */) { - if (container.kind !== 211 /* ClassDeclaration */) { + if (!(container.kind === 211 /* ClassDeclaration */ || container.kind === 183 /* ClassExpression */)) { return undefined; } } @@ -43893,6 +43983,11 @@ var ts; return undefined; } } + else if (modifier === 112 /* AbstractKeyword */) { + if (!(container.kind === 211 /* ClassDeclaration */ || declaration.kind === 211 /* ClassDeclaration */)) { + return undefined; + } + } else { // unsupported modifier return undefined; @@ -43903,12 +43998,19 @@ var ts; switch (container.kind) { case 216 /* ModuleBlock */: case 245 /* SourceFile */: - nodes = container.statements; + // Container is either a class declaration or the declaration is a classDeclaration + if (modifierFlag & 256 /* Abstract */) { + nodes = declaration.members.concat(declaration); + } + else { + nodes = container.statements; + } break; case 141 /* Constructor */: nodes = container.parameters.concat(container.parent.members); break; case 211 /* ClassDeclaration */: + case 183 /* ClassExpression */: nodes = container.members; // If we're an accessibility modifier, we're in an instance member and should search // the constructor's parameter list for instance members as well. @@ -43920,6 +44022,9 @@ var ts; nodes = nodes.concat(constructor.parameters); } } + else if (modifierFlag & 256 /* Abstract */) { + nodes = nodes.concat(container); + } break; default: ts.Debug.fail("Invalid container kind."); @@ -43944,6 +44049,8 @@ var ts; return 1 /* Export */; case 119 /* DeclareKeyword */: return 2 /* Ambient */; + case 112 /* AbstractKeyword */: + return 256 /* Abstract */; default: ts.Debug.fail(); } @@ -44761,19 +44868,19 @@ var ts; if (isNameOfPropertyAssignment(node)) { var objectLiteral = node.parent.parent; var contextualType = typeChecker.getContextualType(objectLiteral); - var name_32 = node.text; + var name_33 = node.text; if (contextualType) { if (contextualType.flags & 16384 /* Union */) { // This is a union type, first see if the property we are looking for is a union property (i.e. exists in all types) // if not, search the constituent types for the property - var unionProperty = contextualType.getProperty(name_32); + var unionProperty = contextualType.getProperty(name_33); if (unionProperty) { return [unionProperty]; } else { var result_4 = []; ts.forEach(contextualType.types, function (t) { - var symbol = t.getProperty(name_32); + var symbol = t.getProperty(name_33); if (symbol) { result_4.push(symbol); } @@ -44782,7 +44889,7 @@ var ts; } } else { - var symbol_1 = contextualType.getProperty(name_32); + var symbol_1 = contextualType.getProperty(name_33); if (symbol_1) { return [symbol_1]; } @@ -45464,7 +45571,7 @@ var ts; return; } } - return 9 /* text */; + return 2 /* identifier */; } } function processElement(element) { @@ -46760,6 +46867,13 @@ var ts; var decoded = JSON.parse(encoded); return ts.createTextChangeRange(ts.createTextSpan(decoded.span.start, decoded.span.length), decoded.newLength); }; + ScriptSnapshotShimAdapter.prototype.dispose = function () { + // if scriptSnapshotShim is a COM object then property check becomes method call with no arguments + // 'in' does not have this effect + if ("dispose" in this.scriptSnapshotShim) { + this.scriptSnapshotShim.dispose(); + } + }; return ScriptSnapshotShimAdapter; })(); var LanguageServiceShimHostAdapter = (function () { diff --git a/package.json b/package.json index 82ab734d6f1..70ada6fef15 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "chai": "latest", "browserify": "latest", "istanbul": "latest", + "mocha-fivemat-progress-reporter": "latest", "tslint": "latest" }, "scripts": { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index da45c08ab44..7d022825ea7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2307,6 +2307,7 @@ namespace ts { if (declaration.parent.parent.kind === SyntaxKind.ForInStatement) { return anyType; } + if (declaration.parent.parent.kind === SyntaxKind.ForOfStatement) { // checkRightHandSideOfForOf will return undefined if the for-of expression type was // missing properties/signatures required to get its iteratedType (like @@ -2314,13 +2315,16 @@ namespace ts { // or it may have led to an error inside getElementTypeOfIterable. return checkRightHandSideOfForOf((declaration.parent.parent).expression) || anyType; } + if (isBindingPattern(declaration.parent)) { return getTypeForBindingElement(declaration); } + // Use type from type annotation if one is present if (declaration.type) { return getTypeFromTypeNode(declaration.type); } + if (declaration.kind === SyntaxKind.Parameter) { let func = declaration.parent; // For a parameter of a set accessor, use the type of the get accessor if one is present @@ -2336,14 +2340,22 @@ namespace ts { return type; } } + // Use the type of the initializer expression if one is present if (declaration.initializer) { return checkExpressionCached(declaration.initializer); } + // If it is a short-hand property assignment, use the type of the identifier if (declaration.kind === SyntaxKind.ShorthandPropertyAssignment) { return checkIdentifier(declaration.name); } + + // If the declaration specifies a binding pattern, use the type implied by the binding pattern + if (isBindingPattern(declaration.name)) { + return getTypeFromBindingPattern(declaration.name); + } + // No type specified and nothing can be inferred return undefined; } @@ -2429,13 +2441,10 @@ namespace ts { // tools see the actual type. return declaration.kind !== SyntaxKind.PropertyAssignment ? getWidenedType(type) : type; } - // If no type was specified and nothing could be inferred, and if the declaration specifies a binding pattern, use - // the type implied by the binding pattern - if (isBindingPattern(declaration.name)) { - return getTypeFromBindingPattern(declaration.name); - } + // Rest parameters default to type any[], other parameters default to type any type = declaration.dotDotDotToken ? anyArrayType : anyType; + // Report implicit any errors unless this is a private property within an ambient declaration if (reportErrors && compilerOptions.noImplicitAny) { let root = getRootDeclaration(declaration); @@ -3943,7 +3952,7 @@ namespace ts { let id = getTypeListId(elementTypes); let type = tupleTypes[id]; if (!type) { - type = tupleTypes[id] = createObjectType(TypeFlags.Tuple); + type = tupleTypes[id] = createObjectType(TypeFlags.Tuple | getWideningFlagsOfTypes(elementTypes)); type.elementTypes = elementTypes; } return type; @@ -5299,8 +5308,8 @@ namespace ts { * Check if a Type was written as a tuple type literal. * Prefer using isTupleLikeType() unless the use of `elementTypes` is required. */ - function isTupleType(type: Type): boolean { - return (type.flags & TypeFlags.Tuple) && !!(type).elementTypes; + function isTupleType(type: Type): type is TupleType { + return !!(type.flags & TypeFlags.Tuple); } function getWidenedTypeOfObjectLiteral(type: Type): Type { @@ -5341,26 +5350,45 @@ namespace ts { if (isArrayType(type)) { return createArrayType(getWidenedType((type).typeArguments[0])); } + if (isTupleType(type)) { + return createTupleType(map(type.elementTypes, getWidenedType)); + } } return type; } + /** + * Reports implicit any errors that occur as a result of widening 'null' and 'undefined' + * to 'any'. A call to reportWideningErrorsInType is normally accompanied by a call to + * getWidenedType. But in some cases getWidenedType is called without reporting errors + * (type argument inference is an example). + * + * The return value indicates whether an error was in fact reported. The particular circumstances + * are on a best effort basis. Currently, if the null or undefined that causes widening is inside + * an object literal property (arbitrarily deeply), this function reports an error. If no error is + * reported, reportImplicitAnyError is a suitable fallback to report a general error. + */ function reportWideningErrorsInType(type: Type): boolean { + let errorReported = false; if (type.flags & TypeFlags.Union) { - let errorReported = false; - forEach((type).types, t => { + for (let t of (type).types) { if (reportWideningErrorsInType(t)) { errorReported = true; } - }); - return errorReported; + } } if (isArrayType(type)) { return reportWideningErrorsInType((type).typeArguments[0]); } + if (isTupleType(type)) { + for (let t of type.elementTypes) { + if (reportWideningErrorsInType(t)) { + errorReported = true; + } + } + } if (type.flags & TypeFlags.ObjectLiteral) { - let errorReported = false; - forEach(getPropertiesOfObjectType(type), p => { + for (let p of getPropertiesOfObjectType(type)) { let t = getTypeOfSymbol(p); if (t.flags & TypeFlags.ContainsUndefinedOrNull) { if (!reportWideningErrorsInType(t)) { @@ -5368,10 +5396,9 @@ namespace ts { } errorReported = true; } - }); - return errorReported; + } } - return false; + return errorReported; } function reportImplicitAnyError(declaration: Declaration, type: Type) { @@ -5538,30 +5565,33 @@ namespace ts { inferFromTypes(sourceType, target); } } - else if (source.flags & TypeFlags.ObjectType && (target.flags & (TypeFlags.Reference | TypeFlags.Tuple) || - (target.flags & TypeFlags.Anonymous) && target.symbol && target.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class))) { - // If source is an object type, and target is a type reference, a tuple type, the type of a method, or a type literal, infer from members - if (isInProcess(source, target)) { - return; - } - if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) { - return; - } + else { + source = getApparentType(source); + if (source.flags & TypeFlags.ObjectType && (target.flags & (TypeFlags.Reference | TypeFlags.Tuple) || + (target.flags & TypeFlags.Anonymous) && target.symbol && target.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class))) { + // If source is an object type, and target is a type reference, a tuple type, the type of a method, or a type literal, infer from members + if (isInProcess(source, target)) { + return; + } + if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) { + return; + } - if (depth === 0) { - sourceStack = []; - targetStack = []; + if (depth === 0) { + sourceStack = []; + targetStack = []; + } + sourceStack[depth] = source; + targetStack[depth] = target; + depth++; + inferFromProperties(source, target); + inferFromSignatures(source, target, SignatureKind.Call); + inferFromSignatures(source, target, SignatureKind.Construct); + inferFromIndexTypes(source, target, IndexKind.String, IndexKind.String); + inferFromIndexTypes(source, target, IndexKind.Number, IndexKind.Number); + inferFromIndexTypes(source, target, IndexKind.String, IndexKind.Number); + depth--; } - sourceStack[depth] = source; - targetStack[depth] = target; - depth++; - inferFromProperties(source, target); - inferFromSignatures(source, target, SignatureKind.Call); - inferFromSignatures(source, target, SignatureKind.Construct); - inferFromIndexTypes(source, target, IndexKind.String, IndexKind.String); - inferFromIndexTypes(source, target, IndexKind.Number, IndexKind.Number); - inferFromIndexTypes(source, target, IndexKind.String, IndexKind.Number); - depth--; } } @@ -6961,7 +6991,6 @@ namespace ts { } } - function checkJsxSelfClosingElement(node: JsxSelfClosingElement) { checkJsxOpeningLikeElement(node); return jsxElementType || anyType; @@ -13650,10 +13679,22 @@ namespace ts { return getSymbolOfNode(node.parent); } - if (node.kind === SyntaxKind.Identifier && isInRightSideOfImportOrExportAssignment(node)) { - return node.parent.kind === SyntaxKind.ExportAssignment - ? getSymbolOfEntityNameOrPropertyAccessExpression(node) - : getSymbolOfPartOfRightHandSideOfImportEquals(node); + if (node.kind === SyntaxKind.Identifier) { + if (isInRightSideOfImportOrExportAssignment(node)) { + return node.parent.kind === SyntaxKind.ExportAssignment + ? getSymbolOfEntityNameOrPropertyAccessExpression(node) + : getSymbolOfPartOfRightHandSideOfImportEquals(node); + } + else if (node.parent.kind === SyntaxKind.BindingElement && + node.parent.parent.kind === SyntaxKind.ObjectBindingPattern && + node === (node.parent).propertyName) { + let typeOfPattern = getTypeAtLocation(node.parent.parent); + let propertyDeclaration = typeOfPattern && getPropertyOfType(typeOfPattern, (node).text); + + if (propertyDeclaration) { + return propertyDeclaration; + } + } } switch (node.kind) { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index fd0d4ad796e..9c8438565e7 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -4215,10 +4215,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } } + let startIndex = 0; + write(" {"); scopeEmitStart(node, "constructor"); increaseIndent(); if (ctor) { + // Emit all the directive prologues (like "use strict"). These have to come before + // any other preamble code we write (like parameter initializers). + startIndex = emitDirectivePrologues(ctor.body.statements, /*startWithNewLine*/ true); emitDetachedComments(ctor.body.statements); } emitCaptureThisForNodeIfNecessary(node); @@ -4253,7 +4258,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi if (superCall) { statements = statements.slice(1); } - emitLines(statements); + emitLinesStartingAt(statements, startIndex); } emitTempDeclarations(/*newLine*/ true); writeLine(); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index fecff11b1b4..127d1b58ee4 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3295,7 +3295,7 @@ namespace ts { function parseSuperExpression(): MemberExpression { let expression = parseTokenNode(); - if (token === SyntaxKind.OpenParenToken || token === SyntaxKind.DotToken) { + if (token === SyntaxKind.OpenParenToken || token === SyntaxKind.DotToken || token === SyntaxKind.OpenBracketToken) { return expression; } @@ -5135,7 +5135,12 @@ namespace ts { } else { node.exportClause = parseNamedImportsOrExports(SyntaxKind.NamedExports); - if (parseOptional(SyntaxKind.FromKeyword)) { + + // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios, + // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`) + // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect. + if (token === SyntaxKind.FromKeyword || (token === SyntaxKind.StringLiteral && !scanner.hasPrecedingLineBreak())) { + parseExpected(SyntaxKind.FromKeyword) node.moduleSpecifier = parseModuleSpecifier(); } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 5174589cdcf..df3f1c9f174 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -568,7 +568,7 @@ namespace ts { } } - export function isVariableLike(node: Node): boolean { + export function isVariableLike(node: Node): node is VariableLikeDeclaration { if (node) { switch (node.kind) { case SyntaxKind.BindingElement: diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index 1b399e1b706..b1d43302372 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -10,6 +10,7 @@ const enum CompilerTestType { class CompilerBaselineRunner extends RunnerBase { private basePath = 'tests/cases'; + private testSuiteName: string; private errors: boolean; private emit: boolean; private decl: boolean; @@ -24,43 +25,43 @@ class CompilerBaselineRunner extends RunnerBase { this.decl = true; this.output = true; if (testType === CompilerTestType.Conformance) { - this.basePath += '/conformance'; + this.testSuiteName = 'conformance'; } else if (testType === CompilerTestType.Regressions) { - this.basePath += '/compiler'; + this.testSuiteName = 'compiler'; } else if (testType === CompilerTestType.Test262) { - this.basePath += '/test262'; + this.testSuiteName = 'test262'; } else { - this.basePath += '/compiler'; // default to this for historical reasons + this.testSuiteName = 'compiler'; // default to this for historical reasons } + this.basePath += '/' + this.testSuiteName; } public checkTestCodeOutput(fileName: string) { describe('compiler tests for ' + fileName, () => { // Mocha holds onto the closure environment of the describe callback even after the test is done. // Everything declared here should be cleared out in the "after" callback. - var justName: string; - var content: string; - var testCaseContent: { settings: Harness.TestCaseParser.CompilerSetting[]; testUnitData: Harness.TestCaseParser.TestUnitData[]; } + let justName: string; + let content: string; + let testCaseContent: { settings: Harness.TestCaseParser.CompilerSetting[]; testUnitData: Harness.TestCaseParser.TestUnitData[]; }; - var units: Harness.TestCaseParser.TestUnitData[]; - var tcSettings: Harness.TestCaseParser.CompilerSetting[]; - var createNewInstance: boolean; + let units: Harness.TestCaseParser.TestUnitData[]; + let tcSettings: Harness.TestCaseParser.CompilerSetting[]; - var lastUnit: Harness.TestCaseParser.TestUnitData; - var rootDir: string; + let lastUnit: Harness.TestCaseParser.TestUnitData; + let rootDir: string; - var result: Harness.Compiler.CompilerResult; - var program: ts.Program; - var options: ts.CompilerOptions; + let result: Harness.Compiler.CompilerResult; + let program: ts.Program; + let options: ts.CompilerOptions; // equivalent to the files that will be passed on the command line - var toBeCompiled: { unitName: string; content: string }[]; + let toBeCompiled: { unitName: string; content: string }[]; // equivalent to other files on the file system not directly passed to the compiler (ie things that are referenced by other files) - var otherFiles: { unitName: string; content: string }[]; - var harnessCompiler: Harness.Compiler.HarnessCompiler; + let otherFiles: { unitName: string; content: string }[]; + let harnessCompiler: Harness.Compiler.HarnessCompiler; - var createNewInstance = false; + let createNewInstance = false; before(() => { justName = fileName.replace(/^.*[\\\/]/, ''); // strips the fileName from the path. @@ -100,10 +101,10 @@ class CompilerBaselineRunner extends RunnerBase { }); beforeEach(() => { - /* The compiler doesn't handle certain flags flipping during a single compilation setting. Tests on these flags will need + /* The compiler doesn't handle certain flags flipping during a single compilation setting. Tests on these flags will need a fresh compiler instance for themselves and then create a fresh one for the next test. Would be nice to get dev fixes eventually to remove this limitation. */ - for (var i = 0; i < tcSettings.length; ++i) { + for (let i = 0; i < tcSettings.length; ++i) { // noImplicitAny is passed to getCompiler, but target is just passed in the settings blob to setCompilerSettings if (!createNewInstance && (tcSettings[i].flag == "noimplicitany" || tcSettings[i].flag === 'target')) { harnessCompiler = Harness.Compiler.getCompiler(); @@ -160,7 +161,7 @@ class CompilerBaselineRunner extends RunnerBase { it('Correct sourcemap content for ' + fileName, () => { if (options.sourceMap || options.inlineSourceMap) { Harness.Baseline.runBaseline('Correct sourcemap content for ' + fileName, justName.replace(/\.tsx?$/, '.sourcemap.txt'), () => { - var record = result.getSourceMapRecord(); + let record = result.getSourceMapRecord(); if (options.noEmitOnError && result.errors.length !== 0 && record === undefined) { // Because of the noEmitOnError option no files are created. We need to return null because baselining isn't required. return null; @@ -178,18 +179,18 @@ class CompilerBaselineRunner extends RunnerBase { // check js output Harness.Baseline.runBaseline('Correct JS output for ' + fileName, justName.replace(/\.tsx?/, '.js'), () => { - var tsCode = ''; - var tsSources = otherFiles.concat(toBeCompiled); + let tsCode = ''; + let tsSources = otherFiles.concat(toBeCompiled); if (tsSources.length > 1) { tsCode += '//// [' + fileName + '] ////\r\n\r\n'; } - for (var i = 0; i < tsSources.length; i++) { + for (let i = 0; i < tsSources.length; i++) { tsCode += '//// [' + Harness.Path.getFileName(tsSources[i].unitName) + ']\r\n'; tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? '\r\n' : ''); } - var jsCode = ''; - for (var i = 0; i < result.files.length; i++) { + let jsCode = ''; + for (let i = 0; i < result.files.length; i++) { jsCode += '//// [' + Harness.Path.getFileName(result.files[i].fileName) + ']\r\n'; jsCode += getByteOrderMarkText(result.files[i]); jsCode += result.files[i].code; @@ -197,14 +198,14 @@ class CompilerBaselineRunner extends RunnerBase { if (result.declFilesCode.length > 0) { jsCode += '\r\n\r\n'; - for (var i = 0; i < result.declFilesCode.length; i++) { + for (let i = 0; i < result.declFilesCode.length; i++) { jsCode += '//// [' + Harness.Path.getFileName(result.declFilesCode[i].fileName) + ']\r\n'; jsCode += getByteOrderMarkText(result.declFilesCode[i]); jsCode += result.declFilesCode[i].code; } } - var declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) { + let declFileCompilationResult = harnessCompiler.compileDeclarationFiles(toBeCompiled, otherFiles, result, function (settings) { harnessCompiler.setCompilerSettings(tcSettings); }, options); @@ -242,8 +243,8 @@ class CompilerBaselineRunner extends RunnerBase { return null; } - var sourceMapCode = ''; - for (var i = 0; i < result.sourceMaps.length; i++) { + let sourceMapCode = ''; + for (let i = 0; i < result.sourceMaps.length; i++) { sourceMapCode += '//// [' + Harness.Path.getFileName(result.sourceMaps[i].fileName) + ']\r\n'; sourceMapCode += getByteOrderMarkText(result.sourceMaps[i]); sourceMapCode += result.sourceMaps[i].code; @@ -261,19 +262,19 @@ class CompilerBaselineRunner extends RunnerBase { // NEWTODO: Type baselines if (result.errors.length === 0) { - // The full walker simulates the types that you would get from doing a full + // The full walker simulates the types that you would get from doing a full // compile. The pull walker simulates the types you get when you just do // a type query for a random node (like how the LS would do it). Most of the // time, these will be the same. However, occasionally, they can be different. // Specifically, when the compiler internally depends on symbol IDs to order - // things, then we may see different results because symbols can be created in a + // things, then we may see different results because symbols can be created in a // different order with 'pull' operations, and thus can produce slightly differing // output. // // For example, with a full type check, we may see a type outputed as: number | string // But with a pull type check, we may see it as: string | number // - // These types are equivalent, but depend on what order the compiler observed + // These types are equivalent, but depend on what order the compiler observed // certain parts of the program. let allFiles = toBeCompiled.concat(otherFiles).filter(file => !!program.getSourceFile(file.unitName)); @@ -291,7 +292,7 @@ class CompilerBaselineRunner extends RunnerBase { // Produce baselines. The first gives the types for all expressions. // The second gives symbols for all identifiers. - var e1: Error, e2: Error; + let e1: Error, e2: Error; try { checkBaseLines(/*isSymbolBaseLine:*/ false); } @@ -333,20 +334,20 @@ class CompilerBaselineRunner extends RunnerBase { let typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {}; allFiles.forEach(file => { - var codeLines = file.content.split('\n'); + let codeLines = file.content.split('\n'); typeWriterResults[file.unitName].forEach(result => { if (isSymbolBaseline && !result.symbol) { return; } - var typeOrSymbolString = isSymbolBaseline ? result.symbol : result.type; - var formattedLine = result.sourceText.replace(/\r?\n/g, "") + " : " + typeOrSymbolString; + let typeOrSymbolString = isSymbolBaseline ? result.symbol : result.type; + let formattedLine = result.sourceText.replace(/\r?\n/g, "") + " : " + typeOrSymbolString; if (!typeMap[file.unitName]) { typeMap[file.unitName] = {}; } - var typeInfo = [formattedLine]; - var existingTypeInfo = typeMap[file.unitName][result.line]; + let typeInfo = [formattedLine]; + let existingTypeInfo = typeMap[file.unitName][result.line]; if (existingTypeInfo) { typeInfo = existingTypeInfo.concat(typeInfo); } @@ -354,11 +355,11 @@ class CompilerBaselineRunner extends RunnerBase { }); typeLines.push('=== ' + file.unitName + ' ===\r\n'); - for (var i = 0; i < codeLines.length; i++) { - var currentCodeLine = codeLines[i]; + for (let i = 0; i < codeLines.length; i++) { + let currentCodeLine = codeLines[i]; typeLines.push(currentCodeLine + '\r\n'); if (typeMap[file.unitName]) { - var typeInfo = typeMap[file.unitName][i]; + let typeInfo = typeMap[file.unitName][i]; if (typeInfo) { typeInfo.forEach(ty => { typeLines.push('>' + ty + '\r\n'); @@ -384,25 +385,27 @@ class CompilerBaselineRunner extends RunnerBase { } public initializeTests() { - describe("Setup compiler for compiler baselines", () => { - var harnessCompiler = Harness.Compiler.getCompiler(); - this.parseOptions(); - }); - - // this will set up a series of describe/it blocks to run between the setup and cleanup phases - if (this.tests.length === 0) { - var testFiles = this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true }); - testFiles.forEach(fn => { - fn = fn.replace(/\\/g, "/"); - this.checkTestCodeOutput(fn); + describe(this.testSuiteName + ' tests', () => { + describe("Setup compiler for compiler baselines", () => { + let harnessCompiler = Harness.Compiler.getCompiler(); + this.parseOptions(); }); - } - else { - this.tests.forEach(test => this.checkTestCodeOutput(test)); - } - describe("Cleanup after compiler baselines", () => { - var harnessCompiler = Harness.Compiler.getCompiler(); + // this will set up a series of describe/it blocks to run between the setup and cleanup phases + if (this.tests.length === 0) { + let testFiles = this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true }); + testFiles.forEach(fn => { + fn = fn.replace(/\\/g, "/"); + this.checkTestCodeOutput(fn); + }); + } + else { + this.tests.forEach(test => this.checkTestCodeOutput(test)); + } + + describe("Cleanup after compiler baselines", () => { + let harnessCompiler = Harness.Compiler.getCompiler(); + }); }); } @@ -413,8 +416,8 @@ class CompilerBaselineRunner extends RunnerBase { this.decl = false; this.output = false; - var opts = this.options.split(','); - for (var i = 0; i < opts.length; i++) { + let opts = this.options.split(','); + for (let i = 0; i < opts.length; i++) { switch (opts[i]) { case 'error': this.errors = true; @@ -434,4 +437,4 @@ class CompilerBaselineRunner extends RunnerBase { } } } -} \ No newline at end of file +} diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 0d03f7d6236..5c8e6bc8981 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1,6 +1,6 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -100,7 +100,7 @@ module FourSlash { end: number; } - var entityMap: ts.Map = { + let entityMap: ts.Map = { '&': '&', '"': '"', "'": ''', @@ -116,7 +116,7 @@ module FourSlash { // Name of testcase metadata including ts.CompilerOptions properties that will be used by globalOptions // To add additional option, add property into the testOptMetadataNames, refer the property in either globalMetadataNames or fileMetadataNames // Add cases into convertGlobalOptionsToCompilationsSettings function for the compiler to acknowledge such option from meta data - var metadataOptionNames = { + let metadataOptionNames = { baselineFile: 'BaselineFile', declaration: 'declaration', emitThisFile: 'emitThisFile', // This flag is used for testing getEmitOutput feature. It allows test-cases to indicate what file to be output in multiple files project @@ -132,15 +132,15 @@ module FourSlash { }; // List of allowed metadata names - var fileMetadataNames = [metadataOptionNames.fileName, metadataOptionNames.emitThisFile, metadataOptionNames.resolveReference]; - var globalMetadataNames = [metadataOptionNames.allowNonTsExtensions, metadataOptionNames.baselineFile, metadataOptionNames.declaration, + let fileMetadataNames = [metadataOptionNames.fileName, metadataOptionNames.emitThisFile, metadataOptionNames.resolveReference]; + let globalMetadataNames = [metadataOptionNames.allowNonTsExtensions, metadataOptionNames.baselineFile, metadataOptionNames.declaration, metadataOptionNames.mapRoot, metadataOptionNames.module, metadataOptionNames.out, - metadataOptionNames.outDir, metadataOptionNames.sourceMap, metadataOptionNames.sourceRoot] + metadataOptionNames.outDir, metadataOptionNames.sourceMap, metadataOptionNames.sourceRoot]; function convertGlobalOptionsToCompilerOptions(globalOptions: { [idx: string]: string }): ts.CompilerOptions { - var settings: ts.CompilerOptions = { target: ts.ScriptTarget.ES5 }; + let settings: ts.CompilerOptions = { target: ts.ScriptTarget.ES5 }; // Convert all property in globalOptions into ts.CompilationSettings - for (var prop in globalOptions) { + for (let prop in globalOptions) { if (globalOptions.hasOwnProperty(prop)) { switch (prop) { case metadataOptionNames.allowNonTsExtensions: @@ -185,14 +185,14 @@ module FourSlash { return settings; } - export var currentTestState: TestState = null; + export let currentTestState: TestState = null; function assertionMessage(msg: string) { return "\nMarker: " + currentTestState.lastKnownMarker + "\nChecking: " + msg + "\n\n"; } export class TestCancellationToken implements ts.HostCancellationToken { // 0 - cancelled - // >0 - not cancelled + // >0 - not cancelled // <0 - not cancelled and value denotes number of isCancellationRequested after which token become cancelled private static NotCanceled: number = -1; private numberOfCallsBeforeCancellation: number = TestCancellationToken.NotCanceled; @@ -271,11 +271,11 @@ module FourSlash { private taoInvalidReason: string = null; private inputFiles: ts.Map = {}; // Map between inputFile's fileName and its content for easily looking up when resolving references - + // Add input file which has matched file name with the given reference-file path. // This is necessary when resolveReference flag is specified private addMatchedInputFile(referenceFilePath: string) { - var inputFile = this.inputFiles[referenceFilePath]; + let inputFile = this.inputFiles[referenceFilePath]; if (inputFile && !Harness.isLibraryFile(referenceFilePath)) { this.languageServiceAdapterHost.addScript(referenceFilePath, inputFile); } @@ -297,13 +297,13 @@ module FourSlash { constructor(private basePath: string, private testType: FourSlashTestType, public testData: FourSlashData) { // Create a new Services Adapter this.cancellationToken = new TestCancellationToken(); - var compilationOptions = convertGlobalOptionsToCompilerOptions(this.testData.globalOptions); - var languageServiceAdapter = this.getLanguageServiceAdapter(testType, this.cancellationToken, compilationOptions); + let compilationOptions = convertGlobalOptionsToCompilerOptions(this.testData.globalOptions); + let languageServiceAdapter = this.getLanguageServiceAdapter(testType, this.cancellationToken, compilationOptions); this.languageServiceAdapterHost = languageServiceAdapter.getHost(); this.languageService = languageServiceAdapter.getLanguageService(); // Initialize the language service with all the scripts - var startResolveFileRef: FourSlashFile; + let startResolveFileRef: FourSlashFile; ts.forEach(testData.files, file => { // Create map between fileName and its content for easily looking up when resolveReference flag is specified @@ -320,14 +320,14 @@ module FourSlash { // Add the entry-point file itself into the languageServiceShimHost this.languageServiceAdapterHost.addScript(startResolveFileRef.fileName, startResolveFileRef.content); - var resolvedResult = languageServiceAdapter.getPreProcessedFileInfo(startResolveFileRef.fileName, startResolveFileRef.content); - var referencedFiles: ts.FileReference[] = resolvedResult.referencedFiles; - var importedFiles: ts.FileReference[] = resolvedResult.importedFiles; + let resolvedResult = languageServiceAdapter.getPreProcessedFileInfo(startResolveFileRef.fileName, startResolveFileRef.content); + let referencedFiles: ts.FileReference[] = resolvedResult.referencedFiles; + let importedFiles: ts.FileReference[] = resolvedResult.importedFiles; // Add triple reference files into language-service host ts.forEach(referencedFiles, referenceFile => { // Fourslash insert tests/cases/fourslash into inputFile.unitName so we will properly append the same base directory to refFile path - var referenceFilePath = this.basePath + '/' + referenceFile.fileName; + let referenceFilePath = this.basePath + '/' + referenceFile.fileName; this.addMatchedInputFile(referenceFilePath); }); @@ -335,7 +335,7 @@ module FourSlash { ts.forEach(importedFiles, importedFile => { // Fourslash insert tests/cases/fourslash into inputFile.unitName and import statement doesn't require ".ts" // so convert them before making appropriate comparison - var importedFilePath = this.basePath + '/' + importedFile.fileName + ".ts"; + let importedFilePath = this.basePath + '/' + importedFile.fileName + ".ts"; this.addMatchedInputFile(importedFilePath); }); @@ -370,8 +370,8 @@ module FourSlash { }; this.testData.files.forEach(file => { - var fileName = file.fileName.replace(Harness.IO.directoryName(file.fileName), '').substr(1); - var fileNameWithoutExtension = fileName.substr(0, fileName.lastIndexOf(".")); + let fileName = file.fileName.replace(Harness.IO.directoryName(file.fileName), '').substr(1); + let fileNameWithoutExtension = fileName.substr(0, fileName.lastIndexOf(".")); this.scenarioActions.push(''); }); @@ -380,18 +380,18 @@ module FourSlash { } private getFileContent(fileName: string): string { - var script = this.languageServiceAdapterHost.getScriptInfo(fileName); + let script = this.languageServiceAdapterHost.getScriptInfo(fileName); return script.content; } // Entry points from fourslash.ts public goToMarker(name = '') { - var marker = this.getMarkerByName(name); + let marker = this.getMarkerByName(name); if (this.activeFile.fileName !== marker.fileName) { this.openFile(marker.fileName); } - var content = this.getFileContent(marker.fileName); + let content = this.getFileContent(marker.fileName); if (marker.position === -1 || marker.position > content.length) { throw new Error('Marker "' + name + '" has been invalidated by unrecoverable edits to the file.'); } @@ -402,8 +402,8 @@ module FourSlash { public goToPosition(pos: number) { this.currentCaretPosition = pos; - var lineStarts = ts.computeLineStarts(this.getFileContent(this.activeFile.fileName)); - var lineCharPos = ts.computeLineAndCharacterOfPosition(lineStarts, pos); + let lineStarts = ts.computeLineStarts(this.getFileContent(this.activeFile.fileName)); + let lineCharPos = ts.computeLineAndCharacterOfPosition(lineStarts, pos); this.scenarioActions.push(``); } @@ -421,24 +421,24 @@ module FourSlash { public openFile(index: number): void; public openFile(name: string): void; public openFile(indexOrName: any) { - var fileToOpen: FourSlashFile = this.findFile(indexOrName); + let fileToOpen: FourSlashFile = this.findFile(indexOrName); fileToOpen.fileName = ts.normalizeSlashes(fileToOpen.fileName); this.activeFile = fileToOpen; - var fileName = fileToOpen.fileName.replace(Harness.IO.directoryName(fileToOpen.fileName), '').substr(1); + let fileName = fileToOpen.fileName.replace(Harness.IO.directoryName(fileToOpen.fileName), '').substr(1); this.scenarioActions.push(''); - + // Let the host know that this file is now open this.languageServiceAdapterHost.openFile(fileToOpen.fileName); } public verifyErrorExistsBetweenMarkers(startMarkerName: string, endMarkerName: string, negative: boolean) { - var startMarker = this.getMarkerByName(startMarkerName); - var endMarker = this.getMarkerByName(endMarkerName); - var predicate = function (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) { + let startMarker = this.getMarkerByName(startMarkerName); + let endMarker = this.getMarkerByName(endMarkerName); + let predicate = function (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) { return ((errorMinChar === startPos) && (errorLimChar === endPos)) ? true : false; }; - var exists = this.anyErrorInRange(predicate, startMarker, endMarker); + let exists = this.anyErrorInRange(predicate, startMarker, endMarker); this.taoInvalidReason = 'verifyErrorExistsBetweenMarkers NYI'; @@ -458,10 +458,10 @@ module FourSlash { } private getDiagnostics(fileName: string): ts.Diagnostic[] { - var syntacticErrors = this.languageService.getSyntacticDiagnostics(fileName); - var semanticErrors = this.languageService.getSemanticDiagnostics(fileName); + let syntacticErrors = this.languageService.getSyntacticDiagnostics(fileName); + let semanticErrors = this.languageService.getSemanticDiagnostics(fileName); - var diagnostics: ts.Diagnostic[] = []; + let diagnostics: ts.Diagnostic[] = []; diagnostics.push.apply(diagnostics, syntacticErrors); diagnostics.push.apply(diagnostics, semanticErrors); @@ -469,10 +469,10 @@ module FourSlash { } private getAllDiagnostics(): ts.Diagnostic[] { - var diagnostics: ts.Diagnostic[] = []; + let diagnostics: ts.Diagnostic[] = []; - var fileNames = this.languageServiceAdapterHost.getFilenames(); - for (var i = 0, n = fileNames.length; i < n; i++) { + let fileNames = this.languageServiceAdapterHost.getFilenames(); + for (let i = 0, n = fileNames.length; i < n; i++) { diagnostics.push.apply(this.getDiagnostics(fileNames[i])); } @@ -480,8 +480,8 @@ module FourSlash { } public verifyErrorExistsAfterMarker(markerName: string, negative: boolean, after: boolean) { - var marker: Marker = this.getMarkerByName(markerName); - var predicate: (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) => boolean; + let marker: Marker = this.getMarkerByName(markerName); + let predicate: (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) => boolean; if (after) { predicate = function (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) { @@ -495,8 +495,8 @@ module FourSlash { this.taoInvalidReason = 'verifyErrorExistsAfterMarker NYI'; - var exists = this.anyErrorInRange(predicate, marker); - var diagnostics = this.getAllDiagnostics(); + let exists = this.anyErrorInRange(predicate, marker); + let diagnostics = this.getAllDiagnostics(); if (exists !== negative) { this.printErrorLog(negative, diagnostics); @@ -506,12 +506,13 @@ module FourSlash { private anyErrorInRange(predicate: (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) => boolean, startMarker: Marker, endMarker?: Marker) { - var errors = this.getDiagnostics(startMarker.fileName); - var exists = false; + let errors = this.getDiagnostics(startMarker.fileName); + let exists = false; - var startPos = startMarker.position; + let startPos = startMarker.position; + let endPos: number = undefined; if (endMarker !== undefined) { - var endPos = endMarker.position; + endPos = endMarker.position; } errors.forEach(function (error: ts.Diagnostic) { @@ -538,40 +539,40 @@ module FourSlash { } public verifyNumberOfErrorsInCurrentFile(expected: number) { - var errors = this.getDiagnostics(this.activeFile.fileName); - var actual = errors.length; + let errors = this.getDiagnostics(this.activeFile.fileName); + let actual = errors.length; this.scenarioActions.push(''); if (actual !== expected) { this.printErrorLog(false, errors); - var errorMsg = "Actual number of errors (" + actual + ") does not match expected number (" + expected + ")"; + let errorMsg = "Actual number of errors (" + actual + ") does not match expected number (" + expected + ")"; Harness.IO.log(errorMsg); this.raiseError(errorMsg); } } public verifyEval(expr: string, value: any) { - var emit = this.languageService.getEmitOutput(this.activeFile.fileName); + let emit = this.languageService.getEmitOutput(this.activeFile.fileName); if (emit.outputFiles.length !== 1) { throw new Error("Expected exactly one output from emit of " + this.activeFile.fileName); } this.taoInvalidReason = 'verifyEval impossible'; - var evaluation = new Function(emit.outputFiles[0].text + ';\r\nreturn (' + expr + ');')(); + let evaluation = new Function(emit.outputFiles[0].text + ';\r\nreturn (' + expr + ');')(); if (evaluation !== value) { this.raiseError('Expected evaluation of expression "' + expr + '" to equal "' + value + '", but got "' + evaluation + '"'); } } public verifyGetEmitOutputForCurrentFile(expected: string): void { - var emit = this.languageService.getEmitOutput(this.activeFile.fileName); + let emit = this.languageService.getEmitOutput(this.activeFile.fileName); if (emit.outputFiles.length !== 1) { throw new Error("Expected exactly one output from emit of " + this.activeFile.fileName); } this.taoInvalidReason = 'verifyGetEmitOutputForCurrentFile impossible'; - var actual = emit.outputFiles[0].text; + let actual = emit.outputFiles[0].text; if (actual !== expected) { this.raiseError("Expected emit output to be '" + expected + "', but got '" + actual + "'"); } @@ -585,7 +586,7 @@ module FourSlash { this.taoInvalidReason = 'verifyMemberListContains only supports the "symbol" parameter'; } - var members = this.getMemberListAtCaret(); + let members = this.getMemberListAtCaret(); if (members) { this.assertItemInCompletionList(members.entries, symbol, text, documentation, kind); } @@ -607,10 +608,10 @@ module FourSlash { this.scenarioActions.push(''); } - var members = this.getMemberListAtCaret(); + let members = this.getMemberListAtCaret(); if (members) { - var match = members.entries.length === expectedCount; + let match = members.entries.length === expectedCount; if ((!match && !negative) || (match && negative)) { this.raiseError("Member list count was " + members.entries.length + ". Expected " + expectedCount); @@ -625,7 +626,7 @@ module FourSlash { this.scenarioActions.push(''); this.scenarioActions.push(''); - var members = this.getMemberListAtCaret(); + let members = this.getMemberListAtCaret(); if (members && members.entries.filter(e => e.name === symbol).length !== 0) { this.raiseError('Member list did contain ' + symbol); } @@ -634,8 +635,8 @@ module FourSlash { public verifyCompletionListItemsCountIsGreaterThan(count: number) { this.taoInvalidReason = 'verifyCompletionListItemsCountIsGreaterThan NYI'; - var completions = this.getCompletionListAtCaret(); - var itemsCount = completions.entries.length; + let completions = this.getCompletionListAtCaret(); + let itemsCount = completions.entries.length; if (itemsCount <= count) { this.raiseError('Expected completion list items count to be greater than ' + count + ', but is actually ' + itemsCount); @@ -649,13 +650,13 @@ module FourSlash { this.scenarioActions.push(''); } - var members = this.getMemberListAtCaret(); + let members = this.getMemberListAtCaret(); if ((!members || members.entries.length === 0) && negative) { this.raiseError("Member list is empty at Caret"); } else if ((members && members.entries.length !== 0) && !negative) { - var errorMsg = "\n" + "Member List contains: [" + members.entries[0].name; - for (var i = 1; i < members.entries.length; i++) { + let errorMsg = "\n" + "Member List contains: [" + members.entries[0].name; + for (let i = 1; i < members.entries.length; i++) { errorMsg += ", " + members.entries[i].name; } errorMsg += "]\n"; @@ -668,24 +669,24 @@ module FourSlash { public verifyCompletionListIsEmpty(negative: boolean) { this.scenarioActions.push(''); - var completions = this.getCompletionListAtCaret(); + let completions = this.getCompletionListAtCaret(); if ((!completions || completions.entries.length === 0) && negative) { - this.raiseError("Completion list is empty at Caret"); - } else if ((completions && completions.entries.length !== 0) && !negative) { - - var errorMsg = "\n" + "Completion List contains: [" + completions.entries[0].name; - for (var i = 1; i < completions.entries.length; i++) { + this.raiseError("Completion list is empty at caret at position " + this.activeFile.fileName + " " + this.currentCaretPosition); + } + else if (completions && completions.entries.length !== 0 && !negative) { + let errorMsg = "\n" + "Completion List contains: [" + completions.entries[0].name; + for (let i = 1; i < completions.entries.length; i++) { errorMsg += ", " + completions.entries[i].name; } errorMsg += "]\n"; - Harness.IO.log(errorMsg); - this.raiseError("Completion list is not empty at Caret"); + this.raiseError("Completion list is not empty at caret at position " + this.activeFile.fileName + " " + this.currentCaretPosition + errorMsg); } } + public verifyCompletionListAllowsNewIdentifier(negative: boolean) { - var completions = this.getCompletionListAtCaret(); + let completions = this.getCompletionListAtCaret(); if ((completions && !completions.isNewIdentifierLocation) && !negative) { this.raiseError("Expected builder completion entry"); @@ -695,7 +696,7 @@ module FourSlash { } public verifyCompletionListContains(symbol: string, text?: string, documentation?: string, kind?: string) { - var completions = this.getCompletionListAtCaret(); + let completions = this.getCompletionListAtCaret(); if (completions) { this.assertItemInCompletionList(completions.entries, symbol, text, documentation, kind); } @@ -737,7 +738,7 @@ module FourSlash { this.scenarioActions.push(''); this.scenarioActions.push(''); - var completions = this.getCompletionListAtCaret(); + let completions = this.getCompletionListAtCaret(); if (completions) { let filterCompletions = completions.entries.filter(e => e.name === symbol); filterCompletions = expectedKind ? filterCompletions.filter(e => e.kind === expectedKind) : filterCompletions; @@ -755,7 +756,7 @@ module FourSlash { error += "Expected documentation: " + expectedDocumentation + " to equal: " + ts.displayPartsToString(details.documentation) + "."; } if (expectedKind) { - error += "Expected kind: " + expectedKind + " to equal: " + filterCompletions[0].kind + "." + error += "Expected kind: " + expectedKind + " to equal: " + filterCompletions[0].kind + "."; } this.raiseError(error); } @@ -765,7 +766,7 @@ module FourSlash { public verifyCompletionEntryDetails(entryName: string, expectedText: string, expectedDocumentation?: string, kind?: string) { this.taoInvalidReason = 'verifyCompletionEntryDetails NYI'; - var details = this.getCompletionEntryDetails(entryName); + let details = this.getCompletionEntryDetails(entryName); assert.equal(ts.displayPartsToString(details.displayParts), expectedText, assertionMessage("completion entry details text")); @@ -781,14 +782,14 @@ module FourSlash { public verifyReferencesAtPositionListContains(fileName: string, start: number, end: number, isWriteAccess?: boolean) { this.taoInvalidReason = 'verifyReferencesAtPositionListContains NYI'; - var references = this.getReferencesAtCaret(); + let references = this.getReferencesAtCaret(); if (!references || references.length === 0) { this.raiseError('verifyReferencesAtPositionListContains failed - found 0 references, expected at least one.'); } - for (var i = 0; i < references.length; i++) { - var reference = references[i]; + for (let i = 0; i < references.length; i++) { + let reference = references[i]; if (reference && reference.fileName === fileName && reference.textSpan.start === start && ts.textSpanEnd(reference.textSpan) === end) { if (typeof isWriteAccess !== "undefined" && reference.isWriteAccess !== isWriteAccess) { this.raiseError('verifyReferencesAtPositionListContains failed - item isWriteAccess value does not match, actual: ' + reference.isWriteAccess + ', expected: ' + isWriteAccess + '.'); @@ -797,18 +798,18 @@ module FourSlash { } } - var missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess }; + let missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess }; this.raiseError('verifyReferencesAtPositionListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(references) + ')'); } public verifyReferencesCountIs(count: number, localFilesOnly: boolean = true) { this.taoInvalidReason = 'verifyReferences NYI'; - var references = this.getReferencesAtCaret(); - var referencesCount = 0; + let references = this.getReferencesAtCaret(); + let referencesCount = 0; if (localFilesOnly) { - var localFiles = this.testData.files.map(file => file.fileName); + let localFiles = this.testData.files.map(file => file.fileName); // Count only the references in local files. Filter the ones in lib and other files. ts.forEach(references, entry => { if (localFiles.some((fileName) => fileName === entry.fileName)) { @@ -821,7 +822,7 @@ module FourSlash { } if (referencesCount !== count) { - var condition = localFilesOnly ? "excluding libs" : "including libs"; + let condition = localFilesOnly ? "excluding libs" : "including libs"; this.raiseError("Expected references count (" + condition + ") to be " + count + ", but is actually " + referencesCount); } } @@ -847,18 +848,18 @@ module FourSlash { } public getSyntacticDiagnostics(expected: string) { - var diagnostics = this.languageService.getSyntacticDiagnostics(this.activeFile.fileName); + let diagnostics = this.languageService.getSyntacticDiagnostics(this.activeFile.fileName); this.testDiagnostics(expected, diagnostics); } public getSemanticDiagnostics(expected: string) { - var diagnostics = this.languageService.getSemanticDiagnostics(this.activeFile.fileName); + let diagnostics = this.languageService.getSemanticDiagnostics(this.activeFile.fileName); this.testDiagnostics(expected, diagnostics); } private testDiagnostics(expected: string, diagnostics: ts.Diagnostic[]) { - var realized = ts.realizeDiagnostics(diagnostics, "\r\n"); - var actual = JSON.stringify(realized, null, " "); + let realized = ts.realizeDiagnostics(diagnostics, "\r\n"); + let actual = JSON.stringify(realized, null, " "); assert.equal(actual, expected); } @@ -870,9 +871,9 @@ module FourSlash { } }); - var actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); - var actualQuickInfoText = actualQuickInfo ? ts.displayPartsToString(actualQuickInfo.displayParts) : ""; - var actualQuickInfoDocumentation = actualQuickInfo ? ts.displayPartsToString(actualQuickInfo.documentation) : ""; + let actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let actualQuickInfoText = actualQuickInfo ? ts.displayPartsToString(actualQuickInfo.displayParts) : ""; + let actualQuickInfoDocumentation = actualQuickInfo ? ts.displayPartsToString(actualQuickInfo.documentation) : ""; if (negative) { if (expectedText !== undefined) { @@ -900,7 +901,7 @@ module FourSlash { this.scenarioActions.push(''); function getDisplayPartsJson(displayParts: ts.SymbolDisplayPart[]) { - var result = ""; + let result = ""; ts.forEach(displayParts, part => { if (result) { result += ",\n "; @@ -917,7 +918,7 @@ module FourSlash { return result; } - var actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); assert.equal(actualQuickInfo.kind, kind, this.messageAtLastKnownMarker("QuickInfo kind")); assert.equal(actualQuickInfo.kindModifiers, kindModifiers, this.messageAtLastKnownMarker("QuickInfo kindModifiers")); assert.equal(JSON.stringify(actualQuickInfo.textSpan), JSON.stringify(textSpan), this.messageAtLastKnownMarker("QuickInfo textSpan")); @@ -926,12 +927,12 @@ module FourSlash { } public verifyRenameLocations(findInStrings: boolean, findInComments: boolean) { - var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); + let renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); if (renameInfo.canRename) { - var references = this.languageService.findRenameLocations( + let references = this.languageService.findRenameLocations( this.activeFile.fileName, this.currentCaretPosition, findInStrings, findInComments); - var ranges = this.getRanges(); + let ranges = this.getRanges(); if (!references) { if (ranges.length !== 0) { @@ -947,9 +948,9 @@ module FourSlash { ranges = ranges.sort((r1, r2) => r1.start - r2.start); references = references.sort((r1, r2) => r1.textSpan.start - r2.textSpan.start); - for (var i = 0, n = ranges.length; i < n; i++) { - var reference = references[i]; - var range = ranges[i]; + for (let i = 0, n = ranges.length; i < n; i++) { + let reference = references[i]; + let range = ranges[i]; if (reference.textSpan.start !== range.start || ts.textSpanEnd(reference.textSpan) !== range.end) { @@ -966,7 +967,7 @@ module FourSlash { public verifyQuickInfoExists(negative: boolean) { this.taoInvalidReason = 'verifyQuickInfoExists NYI'; - var actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (negative) { if (actualQuickInfo) { this.raiseError('verifyQuickInfoExists failed. Expected quick info NOT to exist'); @@ -982,17 +983,17 @@ module FourSlash { public verifyCurrentSignatureHelpIs(expected: string) { this.taoInvalidReason = 'verifyCurrentSignatureHelpIs NYI'; - var help = this.getActiveSignatureHelpItem(); + let help = this.getActiveSignatureHelpItem(); assert.equal( ts.displayPartsToString(help.prefixDisplayParts) + help.parameters.map(p => ts.displayPartsToString(p.displayParts)).join(ts.displayPartsToString(help.separatorDisplayParts)) + ts.displayPartsToString(help.suffixDisplayParts), expected); } - public verifyCurrentParameterIsVariable(isVariable: boolean) { - this.taoInvalidReason = 'verifyCurrentParameterIsVariable NYI'; + public verifyCurrentParameterIsletiable(isVariable: boolean) { + this.taoInvalidReason = 'verifyCurrentParameterIsletiable NYI'; - var signature = this.getActiveSignatureHelpItem(); + let signature = this.getActiveSignatureHelpItem(); assert.isNotNull(signature); assert.equal(isVariable, signature.isVariadic); } @@ -1000,24 +1001,24 @@ module FourSlash { public verifyCurrentParameterHelpName(name: string) { this.taoInvalidReason = 'verifyCurrentParameterHelpName NYI'; - var activeParameter = this.getActiveParameter(); - var activeParameterName = activeParameter.name; + let activeParameter = this.getActiveParameter(); + let activeParameterName = activeParameter.name; assert.equal(activeParameterName, name); } public verifyCurrentParameterSpanIs(parameter: string) { this.taoInvalidReason = 'verifyCurrentParameterSpanIs NYI'; - var activeSignature = this.getActiveSignatureHelpItem(); - var activeParameter = this.getActiveParameter(); + let activeSignature = this.getActiveSignatureHelpItem(); + let activeParameter = this.getActiveParameter(); assert.equal(ts.displayPartsToString(activeParameter.displayParts), parameter); } public verifyCurrentParameterHelpDocComment(docComment: string) { this.taoInvalidReason = 'verifyCurrentParameterHelpDocComment NYI'; - var activeParameter = this.getActiveParameter(); - var activeParameterDocComment = activeParameter.documentation; + let activeParameter = this.getActiveParameter(); + let activeParameterDocComment = activeParameter.documentation; assert.equal(ts.displayPartsToString(activeParameterDocComment), docComment, assertionMessage("current parameter Help DocComment")); } @@ -1036,7 +1037,7 @@ module FourSlash { public verifyCurrentSignatureHelpDocComment(docComment: string) { this.taoInvalidReason = 'verifyCurrentSignatureHelpDocComment NYI'; - var actualDocComment = this.getActiveSignatureHelpItem().documentation; + let actualDocComment = this.getActiveSignatureHelpItem().documentation; assert.equal(ts.displayPartsToString(actualDocComment), docComment, assertionMessage("current signature help doc comment")); } @@ -1044,22 +1045,22 @@ module FourSlash { this.scenarioActions.push(''); this.scenarioActions.push(''); - var help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); - var actual = help && help.items ? help.items.length : 0; + let help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); + let actual = help && help.items ? help.items.length : 0; assert.equal(actual, expected); } public verifySignatureHelpArgumentCount(expected: number) { this.taoInvalidReason = 'verifySignatureHelpArgumentCount NYI'; - var signatureHelpItems = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); - var actual = signatureHelpItems.argumentCount; + let signatureHelpItems = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); + let actual = signatureHelpItems.argumentCount; assert.equal(actual, expected); } public verifySignatureHelpPresent(shouldBePresent = true) { this.taoInvalidReason = 'verifySignatureHelpPresent NYI'; - var actual = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); + let actual = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); if (shouldBePresent) { if (!actual) { this.raiseError("Expected signature help to be present, but it wasn't"); @@ -1078,7 +1079,7 @@ module FourSlash { } public verifyRenameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string) { - var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); + let renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); if (!renameInfo.canRename) { this.raiseError("Rename did not succeed"); } @@ -1092,7 +1093,7 @@ module FourSlash { this.raiseError("Expected a single range to be selected in the test file."); } - var expectedRange = this.getRanges()[0]; + let expectedRange = this.getRanges()[0]; if (renameInfo.triggerSpan.start !== expectedRange.start || ts.textSpanEnd(renameInfo.triggerSpan) !== expectedRange.end) { this.raiseError("Expected triggerSpan [" + expectedRange.start + "," + expectedRange.end + "). Got [" + @@ -1101,7 +1102,7 @@ module FourSlash { } public verifyRenameInfoFailed(message?: string) { - var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); + let renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); if (renameInfo.canRename) { this.raiseError("Rename was expected to fail"); } @@ -1110,26 +1111,26 @@ module FourSlash { } private getActiveSignatureHelpItem() { - var help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); - var index = help.selectedItemIndex; + let help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); + let index = help.selectedItemIndex; return help.items[index]; } private getActiveParameter(): ts.SignatureHelpParameter { - var help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); - var item = help.items[help.selectedItemIndex]; - var currentParam = help.argumentIndex; + let help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); + let item = help.items[help.selectedItemIndex]; + let currentParam = help.argumentIndex; return item.parameters[currentParam]; } private alignmentForExtraInfo = 50; private spanInfoToString(pos: number, spanInfo: ts.TextSpan, prefixString: string) { - var resultString = "SpanInfo: " + JSON.stringify(spanInfo); + let resultString = "SpanInfo: " + JSON.stringify(spanInfo); if (spanInfo) { - var spanString = this.activeFile.content.substr(spanInfo.start, spanInfo.length); - var spanLineMap = ts.computeLineStarts(spanString); - for (var i = 0; i < spanLineMap.length; i++) { + let spanString = this.activeFile.content.substr(spanInfo.start, spanInfo.length); + let spanLineMap = ts.computeLineStarts(spanString); + for (let i = 0; i < spanLineMap.length; i++) { if (!i) { resultString += "\n"; } @@ -1142,19 +1143,20 @@ module FourSlash { } private baselineCurrentFileLocations(getSpanAtPos: (pos: number) => ts.TextSpan): string { - var fileLineMap = ts.computeLineStarts(this.activeFile.content); - var nextLine = 0; - var resultString = ""; - var currentLine: string; - var previousSpanInfo: string; - var startColumn: number; - var length: number; - var prefixString = " >"; + let fileLineMap = ts.computeLineStarts(this.activeFile.content); + let nextLine = 0; + let resultString = ""; + let currentLine: string; + let previousSpanInfo: string; + let startColumn: number; + let length: number; + let prefixString = " >"; - var addSpanInfoString = () => { + let pos = 0; + let addSpanInfoString = () => { if (previousSpanInfo) { resultString += currentLine; - var thisLineMarker = repeatString(startColumn, " ") + repeatString(length, "~"); + let thisLineMarker = repeatString(startColumn, " ") + repeatString(length, "~"); thisLineMarker += repeatString(this.alignmentForExtraInfo - thisLineMarker.length - prefixString.length + 1, " "); resultString += thisLineMarker; resultString += "=> Pos: (" + (pos - length) + " to " + (pos - 1) + ") "; @@ -1163,7 +1165,7 @@ module FourSlash { } }; - for (var pos = 0; pos < this.activeFile.content.length; pos++) { + for (; pos < this.activeFile.content.length; pos++) { if (pos === 0 || pos === fileLineMap[nextLine]) { nextLine++; addSpanInfoString(); @@ -1174,7 +1176,7 @@ module FourSlash { startColumn = 0; length = 0; } - var spanInfo = this.spanInfoToString(pos, getSpanAtPos(pos), prefixString); + let spanInfo = this.spanInfoToString(pos, getSpanAtPos(pos), prefixString); if (previousSpanInfo && previousSpanInfo !== spanInfo) { addSpanInfoString(); previousSpanInfo = spanInfo; @@ -1190,8 +1192,8 @@ module FourSlash { return resultString; function repeatString(count: number, char: string) { - var result = ""; - for (var i = 0; i < count; i++) { + let result = ""; + for (let i = 0; i < count; i++) { result += char; } return result; @@ -1218,11 +1220,11 @@ module FourSlash { public baselineGetEmitOutput() { this.taoInvalidReason = 'baselineGetEmitOutput impossible'; // Find file to be emitted - var emitFiles: FourSlashFile[] = []; // List of FourSlashFile that has emitThisFile flag on + let emitFiles: FourSlashFile[] = []; // List of FourSlashFile that has emitThisFile flag on - var allFourSlashFiles = this.testData.files; - for (var idx = 0; idx < allFourSlashFiles.length; ++idx) { - var file = allFourSlashFiles[idx]; + let allFourSlashFiles = this.testData.files; + for (let idx = 0; idx < allFourSlashFiles.length; ++idx) { + let file = allFourSlashFiles[idx]; if (file.fileOptions[metadataOptionNames.emitThisFile] === "true") { // Find a file with the flag emitThisFile turned on emitFiles.push(file); @@ -1238,23 +1240,23 @@ module FourSlash { "Generate getEmitOutput baseline : " + emitFiles.join(" "), this.testData.globalOptions[metadataOptionNames.baselineFile], () => { - var resultString = ""; + let resultString = ""; // Loop through all the emittedFiles and emit them one by one emitFiles.forEach(emitFile => { - var emitOutput = this.languageService.getEmitOutput(emitFile.fileName); + let emitOutput = this.languageService.getEmitOutput(emitFile.fileName); // Print emitOutputStatus in readable format resultString += "EmitSkipped: " + emitOutput.emitSkipped + ts.sys.newLine; if (emitOutput.emitSkipped) { resultString += "Diagnostics:" + ts.sys.newLine; - var diagnostics = ts.getPreEmitDiagnostics(this.languageService.getProgram()); - for (var i = 0, n = diagnostics.length; i < n; i++) { + let diagnostics = ts.getPreEmitDiagnostics(this.languageService.getProgram()); + for (let i = 0, n = diagnostics.length; i < n; i++) { resultString += " " + diagnostics[0].messageText + ts.sys.newLine; } } emitOutput.outputFiles.forEach((outputFile, idx, array) => { - var fileName = "FileName : " + outputFile.name + ts.sys.newLine; + let fileName = "FileName : " + outputFile.name + ts.sys.newLine; resultString = resultString + fileName + outputFile.text; }); resultString += ts.sys.newLine; @@ -1274,19 +1276,19 @@ module FourSlash { } public printCurrentParameterHelp() { - var help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); + let help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition); Harness.IO.log(JSON.stringify(help)); } public printCurrentQuickInfo() { - var quickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let quickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); Harness.IO.log(JSON.stringify(quickInfo)); } public printErrorList() { - var syntacticErrors = this.languageService.getSyntacticDiagnostics(this.activeFile.fileName); - var semanticErrors = this.languageService.getSemanticDiagnostics(this.activeFile.fileName); - var errorList = syntacticErrors.concat(semanticErrors); + let syntacticErrors = this.languageService.getSyntacticDiagnostics(this.activeFile.fileName); + let semanticErrors = this.languageService.getSemanticDiagnostics(this.activeFile.fileName); + let errorList = syntacticErrors.concat(semanticErrors); Harness.IO.log('Error list (' + errorList.length + ' errors)'); if (errorList.length) { @@ -1300,11 +1302,11 @@ module FourSlash { } public printCurrentFileState(makeWhitespaceVisible = false, makeCaretVisible = true) { - for (var i = 0; i < this.testData.files.length; i++) { - var file = this.testData.files[i]; - var active = (this.activeFile === file); + for (let i = 0; i < this.testData.files.length; i++) { + let file = this.testData.files[i]; + let active = (this.activeFile === file); Harness.IO.log('=== Script (' + file.fileName + ') ' + (active ? '(active, cursor at |)' : '') + ' ==='); - var content = this.getFileContent(file.fileName); + let content = this.getFileContent(file.fileName); if (active) { content = content.substr(0, this.currentCaretPosition) + (makeCaretVisible ? '|' : "") + content.substr(this.currentCaretPosition); } @@ -1316,22 +1318,22 @@ module FourSlash { } public printCurrentSignatureHelp() { - var sigHelp = this.getActiveSignatureHelpItem(); + let sigHelp = this.getActiveSignatureHelpItem(); Harness.IO.log(JSON.stringify(sigHelp)); } public printMemberListMembers() { - var members = this.getMemberListAtCaret(); + let members = this.getMemberListAtCaret(); Harness.IO.log(JSON.stringify(members)); } public printCompletionListMembers() { - var completions = this.getCompletionListAtCaret(); + let completions = this.getCompletionListAtCaret(); Harness.IO.log(JSON.stringify(completions)); } public printReferences() { - var references = this.getReferencesAtCaret(); + let references = this.getReferencesAtCaret(); ts.forEach(references, entry => { Harness.IO.log(JSON.stringify(entry)); }); @@ -1344,26 +1346,26 @@ module FourSlash { public deleteChar(count = 1) { this.scenarioActions.push(''); - var offset = this.currentCaretPosition; - var ch = ""; + let offset = this.currentCaretPosition; + let ch = ""; - var checkCadence = (count >> 2) + 1 + let checkCadence = (count >> 2) + 1; - for (var i = 0; i < count; i++) { + for (let i = 0; i < count; i++) { // Make the edit this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset + 1, ch); this.updateMarkersForEdit(this.activeFile.fileName, offset, offset + 1, ch); if (i % checkCadence === 0) { - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); } // Handle post-keystroke formatting if (this.enableFormatting) { - var edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions); + let edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions); if (edits.length) { offset += this.applyEdits(this.activeFile.fileName, edits, true); - //this.checkPostEditInvariants(); + // this.checkPostEditInletiants(); } } } @@ -1372,7 +1374,7 @@ module FourSlash { this.currentCaretPosition = offset; this.fixCaretPosition(); - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); } public replace(start: number, length: number, text: string) { @@ -1380,29 +1382,29 @@ module FourSlash { this.languageServiceAdapterHost.editScript(this.activeFile.fileName, start, start + length, text); this.updateMarkersForEdit(this.activeFile.fileName, start, start + length, text); - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); } public deleteCharBehindMarker(count = 1) { this.scenarioActions.push(''); - var offset = this.currentCaretPosition; - var ch = ""; - var checkCadence = (count >> 2) + 1 + let offset = this.currentCaretPosition; + let ch = ""; + let checkCadence = (count >> 2) + 1; - for (var i = 0; i < count; i++) { + for (let i = 0; i < count; i++) { offset--; // Make the edit this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset + 1, ch); this.updateMarkersForEdit(this.activeFile.fileName, offset, offset + 1, ch); if (i % checkCadence === 0) { - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); } // Handle post-keystroke formatting if (this.enableFormatting) { - var edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions); + let edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions); if (edits.length) { offset += this.applyEdits(this.activeFile.fileName, edits, true); } @@ -1413,7 +1415,7 @@ module FourSlash { this.currentCaretPosition = offset; this.fixCaretPosition(); - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); } // Enters lines of text at the current caret position @@ -1431,13 +1433,13 @@ module FourSlash { // language service APIs to mimic Visual Studio's behavior // as much as possible private typeHighFidelity(text: string) { - var offset = this.currentCaretPosition; - var prevChar = ' '; - var checkCadence = (text.length >> 2) + 1; + let offset = this.currentCaretPosition; + let prevChar = ' '; + let checkCadence = (text.length >> 2) + 1; - for (var i = 0; i < text.length; i++) { + for (let i = 0; i < text.length; i++) { // Make the edit - var ch = text.charAt(i); + let ch = text.charAt(i); this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset, ch); this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, offset); @@ -1453,17 +1455,17 @@ module FourSlash { } if (i % checkCadence === 0) { - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); // this.languageService.getSyntacticDiagnostics(this.activeFile.fileName); // this.languageService.getSemanticDiagnostics(this.activeFile.fileName); } // Handle post-keystroke formatting if (this.enableFormatting) { - var edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions); + let edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeOptions); if (edits.length) { offset += this.applyEdits(this.activeFile.fileName, edits, true); - // this.checkPostEditInvariants(); + // this.checkPostEditInletiants(); } } } @@ -1472,26 +1474,26 @@ module FourSlash { this.currentCaretPosition = offset; this.fixCaretPosition(); - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); } // Enters text as if the user had pasted it public paste(text: string) { this.scenarioActions.push(''); - var start = this.currentCaretPosition; - var offset = this.currentCaretPosition; + let start = this.currentCaretPosition; + let offset = this.currentCaretPosition; this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset, text); this.updateMarkersForEdit(this.activeFile.fileName, offset, offset, text); - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); offset += text.length; // Handle formatting if (this.enableFormatting) { - var edits = this.languageService.getFormattingEditsForRange(this.activeFile.fileName, start, offset, this.formatCodeOptions); + let edits = this.languageService.getFormattingEditsForRange(this.activeFile.fileName, start, offset, this.formatCodeOptions); if (edits.length) { offset += this.applyEdits(this.activeFile.fileName, edits, true); - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); } } @@ -1499,27 +1501,27 @@ module FourSlash { this.currentCaretPosition = offset; this.fixCaretPosition(); - this.checkPostEditInvariants(); + this.checkPostEditInletiants(); } - private checkPostEditInvariants() { - if (this.testType !== FourSlashTestType.Native) { - // getSourcefile() results can not be serialized. Only perform these verifications + private checkPostEditInletiants() { + if (this.testType !== FourSlashTestType.Native) { + // getSourcefile() results can not be serialized. Only perform these verifications // if running against a native LS object. return; } - var incrementalSourceFile = this.languageService.getSourceFile(this.activeFile.fileName); + let incrementalSourceFile = this.languageService.getSourceFile(this.activeFile.fileName); Utils.assertInvariants(incrementalSourceFile, /*parent:*/ undefined); - var incrementalSyntaxDiagnostics = incrementalSourceFile.parseDiagnostics; + let incrementalSyntaxDiagnostics = incrementalSourceFile.parseDiagnostics; // Check syntactic structure - var content = this.getFileContent(this.activeFile.fileName); + let content = this.getFileContent(this.activeFile.fileName); - var referenceSourceFile = ts.createLanguageServiceSourceFile( + let referenceSourceFile = ts.createLanguageServiceSourceFile( this.activeFile.fileName, createScriptSnapShot(content), ts.ScriptTarget.Latest, /*version:*/ "0", /*setNodeParents:*/ false); - var referenceSyntaxDiagnostics = referenceSourceFile.parseDiagnostics; + let referenceSyntaxDiagnostics = referenceSourceFile.parseDiagnostics; Utils.assertDiagnosticsEquals(incrementalSyntaxDiagnostics, referenceSyntaxDiagnostics); Utils.assertStructuralEquals(incrementalSourceFile, referenceSourceFile); @@ -1529,7 +1531,7 @@ module FourSlash { // The caret can potentially end up between the \r and \n, which is confusing. If // that happens, move it back one character if (this.currentCaretPosition > 0) { - var ch = this.getFileContent(this.activeFile.fileName).substring(this.currentCaretPosition - 1, this.currentCaretPosition); + let ch = this.getFileContent(this.activeFile.fileName).substring(this.currentCaretPosition - 1, this.currentCaretPosition); if (ch === '\r') { this.currentCaretPosition--; } @@ -1539,21 +1541,21 @@ module FourSlash { private applyEdits(fileName: string, edits: ts.TextChange[], isFormattingEdit = false): number { // We get back a set of edits, but langSvc.editScript only accepts one at a time. Use this to keep track // of the incremental offset from each edit to the next. Assumption is that these edit ranges don't overlap - var runningOffset = 0; + let runningOffset = 0; edits = edits.sort((a, b) => a.span.start - b.span.start); // Get a snapshot of the content of the file so we can make sure any formatting edits didn't destroy non-whitespace characters - var oldContent = this.getFileContent(this.activeFile.fileName); - for (var j = 0; j < edits.length; j++) { + let oldContent = this.getFileContent(this.activeFile.fileName); + for (let j = 0; j < edits.length; j++) { this.languageServiceAdapterHost.editScript(fileName, edits[j].span.start + runningOffset, ts.textSpanEnd(edits[j].span) + runningOffset, edits[j].newText); this.updateMarkersForEdit(fileName, edits[j].span.start + runningOffset, ts.textSpanEnd(edits[j].span) + runningOffset, edits[j].newText); - var change = (edits[j].span.start - ts.textSpanEnd(edits[j].span)) + edits[j].newText.length; + let change = (edits[j].span.start - ts.textSpanEnd(edits[j].span)) + edits[j].newText.length; runningOffset += change; // TODO: Consider doing this at least some of the time for higher fidelity. Currently causes a failure (bug 707150) // this.languageService.getScriptLexicalStructure(fileName); } if (isFormattingEdit) { - var newContent = this.getFileContent(fileName); + let newContent = this.getFileContent(fileName); if (newContent.replace(/\s/g, '') !== oldContent.replace(/\s/g, '')) { this.raiseError('Formatting operation destroyed non-whitespace content'); @@ -1567,7 +1569,7 @@ module FourSlash { } public setFormatOptions(formatCodeOptions: ts.FormatCodeOptions): ts.FormatCodeOptions { - var oldFormatCodeOptions = this.formatCodeOptions; + let oldFormatCodeOptions = this.formatCodeOptions; this.formatCodeOptions = formatCodeOptions; return oldFormatCodeOptions; } @@ -1575,7 +1577,7 @@ module FourSlash { public formatDocument() { this.scenarioActions.push(''); - var edits = this.languageService.getFormattingEditsForDocument(this.activeFile.fileName, this.formatCodeOptions); + let edits = this.languageService.getFormattingEditsForDocument(this.activeFile.fileName, this.formatCodeOptions); this.currentCaretPosition += this.applyEdits(this.activeFile.fileName, edits, true); this.fixCaretPosition(); } @@ -1583,14 +1585,14 @@ module FourSlash { public formatSelection(start: number, end: number) { this.taoInvalidReason = 'formatSelection NYI'; - var edits = this.languageService.getFormattingEditsForRange(this.activeFile.fileName, start, end, this.formatCodeOptions); + let edits = this.languageService.getFormattingEditsForRange(this.activeFile.fileName, start, end, this.formatCodeOptions); this.currentCaretPosition += this.applyEdits(this.activeFile.fileName, edits, true); this.fixCaretPosition(); } private updateMarkersForEdit(fileName: string, minChar: number, limChar: number, text: string) { - for (var i = 0; i < this.testData.markers.length; i++) { - var marker = this.testData.markers[i]; + for (let i = 0; i < this.testData.markers.length; i++) { + let marker = this.testData.markers[i]; if (marker.fileName === fileName) { if (marker.position > minChar) { if (marker.position < limChar) { @@ -1610,7 +1612,7 @@ module FourSlash { } public goToEOF() { - var len = this.getFileContent(this.activeFile.fileName).length; + let len = this.getFileContent(this.activeFile.fileName).length; this.goToPosition(len); } @@ -1621,7 +1623,7 @@ module FourSlash { this.taoInvalidReason = 'GoToDefinition not supported for non-zero definition indices'; } - var definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (!definitions || !definitions.length) { this.raiseError('goToDefinition failed - expected to at least one definition location but got 0'); } @@ -1630,7 +1632,7 @@ module FourSlash { this.raiseError('goToDefinition failed - definitionIndex value (' + definitionIndex + ') exceeds definition list size (' + definitions.length + ')'); } - var definition = definitions[definitionIndex]; + let definition = definitions[definitionIndex]; this.openFile(definition.fileName); this.currentCaretPosition = definition.textSpan.start; } @@ -1643,7 +1645,7 @@ module FourSlash { this.taoInvalidReason = 'GoToTypeDefinition not supported for non-zero definition indices'; } - var definitions = this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let definitions = this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (!definitions || !definitions.length) { this.raiseError('goToTypeDefinition failed - expected to at least one definition location but got 0'); } @@ -1652,7 +1654,7 @@ module FourSlash { this.raiseError('goToTypeDefinition failed - definitionIndex value (' + definitionIndex + ') exceeds definition list size (' + definitions.length + ')'); } - var definition = definitions[definitionIndex]; + let definition = definitions[definitionIndex]; this.openFile(definition.fileName); this.currentCaretPosition = definition.textSpan.start; } @@ -1660,9 +1662,9 @@ module FourSlash { public verifyDefinitionLocationExists(negative: boolean) { this.taoInvalidReason = 'verifyDefinitionLocationExists NYI'; - var definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); - var foundDefinitions = definitions && definitions.length; + let foundDefinitions = definitions && definitions.length; if (foundDefinitions && negative) { this.raiseError('goToDefinition - expected to 0 definition locations but got ' + definitions.length); @@ -1673,19 +1675,19 @@ module FourSlash { } public verifyDefinitionsCount(negative: boolean, expectedCount: number) { - var assertFn = negative ? assert.notEqual : assert.equal; + let assertFn = negative ? assert.notEqual : assert.equal; - var definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); - var actualCount = definitions && definitions.length || 0; + let definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let actualCount = definitions && definitions.length || 0; assertFn(actualCount, expectedCount, this.messageAtLastKnownMarker("Definitions Count")); } public verifyTypeDefinitionsCount(negative: boolean, expectedCount: number) { - var assertFn = negative ? assert.notEqual : assert.equal; + let assertFn = negative ? assert.notEqual : assert.equal; - var definitions = this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); - var actualCount = definitions && definitions.length || 0; + let definitions = this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let actualCount = definitions && definitions.length || 0; assertFn(actualCount, expectedCount, this.messageAtLastKnownMarker("Type definitions Count")); } @@ -1693,9 +1695,9 @@ module FourSlash { public verifyDefinitionsName(negative: boolean, expectedName: string, expectedContainerName: string) { this.taoInvalidReason = 'verifyDefinititionsInfo NYI'; - var definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); - var actualDefinitionName = definitions && definitions.length ? definitions[0].name : ""; - var actualDefinitionContainerName = definitions && definitions.length ? definitions[0].containerName : ""; + let definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition); + let actualDefinitionName = definitions && definitions.length ? definitions[0].name : ""; + let actualDefinitionContainerName = definitions && definitions.length ? definitions[0].containerName : ""; if (negative) { assert.notEqual(actualDefinitionName, expectedName, this.messageAtLastKnownMarker("Definition Info Name")); assert.notEqual(actualDefinitionContainerName, expectedContainerName, this.messageAtLastKnownMarker("Definition Info Container Name")); @@ -1718,7 +1720,7 @@ module FourSlash { public verifyCaretAtMarker(markerName = '') { this.taoInvalidReason = 'verifyCaretAtMarker NYI'; - var pos = this.getMarkerByName(markerName); + let pos = this.getMarkerByName(markerName); if (pos.fileName !== this.activeFile.fileName) { throw new Error('verifyCaretAtMarker failed - expected to be in file "' + pos.fileName + '", but was in file "' + this.activeFile.fileName + '"'); } @@ -1734,8 +1736,8 @@ module FourSlash { public verifyIndentationAtCurrentPosition(numberOfSpaces: number) { this.taoInvalidReason = 'verifyIndentationAtCurrentPosition NYI'; - var actual = this.getIndentation(this.activeFile.fileName, this.currentCaretPosition); - var lineCol = this.getLineColStringAtPosition(this.currentCaretPosition); + let actual = this.getIndentation(this.activeFile.fileName, this.currentCaretPosition); + let lineCol = this.getLineColStringAtPosition(this.currentCaretPosition); if (actual !== numberOfSpaces) { this.raiseError('verifyIndentationAtCurrentPosition failed at ' + lineCol + ' - expected: ' + numberOfSpaces + ', actual: ' + actual); } @@ -1744,8 +1746,8 @@ module FourSlash { public verifyIndentationAtPosition(fileName: string, position: number, numberOfSpaces: number) { this.taoInvalidReason = 'verifyIndentationAtPosition NYI'; - var actual = this.getIndentation(fileName, position); - var lineCol = this.getLineColStringAtPosition(position); + let actual = this.getIndentation(fileName, position); + let lineCol = this.getLineColStringAtPosition(position); if (actual !== numberOfSpaces) { this.raiseError('verifyIndentationAtPosition failed at ' + lineCol + ' - expected: ' + numberOfSpaces + ', actual: ' + actual); } @@ -1754,7 +1756,7 @@ module FourSlash { public verifyCurrentLineContent(text: string) { this.taoInvalidReason = 'verifyCurrentLineContent NYI'; - var actual = this.getCurrentLineContent(); + let actual = this.getCurrentLineContent(); if (actual !== text) { throw new Error('verifyCurrentLineContent\n' + '\tExpected: "' + text + '"\n' + @@ -1765,8 +1767,8 @@ module FourSlash { public verifyCurrentFileContent(text: string) { this.taoInvalidReason = 'verifyCurrentFileContent NYI'; - var actual = this.getFileContent(this.activeFile.fileName); - var replaceNewlines = (str: string) => str.replace(/\r\n/g, "\n"); + let actual = this.getFileContent(this.activeFile.fileName); + let replaceNewlines = (str: string) => str.replace(/\r\n/g, "\n"); if (replaceNewlines(actual) !== replaceNewlines(text)) { throw new Error('verifyCurrentFileContent\n' + '\tExpected: "' + text + '"\n' + @@ -1777,7 +1779,7 @@ module FourSlash { public verifyTextAtCaretIs(text: string) { this.taoInvalidReason = 'verifyCurrentFileContent NYI'; - var actual = this.getFileContent(this.activeFile.fileName).substring(this.currentCaretPosition, this.currentCaretPosition + text.length); + let actual = this.getFileContent(this.activeFile.fileName).substring(this.currentCaretPosition, this.currentCaretPosition + text.length); if (actual !== text) { throw new Error('verifyTextAtCaretIs\n' + '\tExpected: "' + text + '"\n' + @@ -1788,14 +1790,14 @@ module FourSlash { public verifyCurrentNameOrDottedNameSpanText(text: string) { this.taoInvalidReason = 'verifyCurrentNameOrDottedNameSpanText NYI'; - var span = this.languageService.getNameOrDottedNameSpan(this.activeFile.fileName, this.currentCaretPosition, this.currentCaretPosition); + let span = this.languageService.getNameOrDottedNameSpan(this.activeFile.fileName, this.currentCaretPosition, this.currentCaretPosition); if (!span) { this.raiseError('verifyCurrentNameOrDottedNameSpanText\n' + '\tExpected: "' + text + '"\n' + '\t Actual: undefined'); } - var actual = this.getFileContent(this.activeFile.fileName).substring(span.start, ts.textSpanEnd(span)); + let actual = this.getFileContent(this.activeFile.fileName).substring(span.start, ts.textSpanEnd(span)); if (actual !== text) { this.raiseError('verifyCurrentNameOrDottedNameSpanText\n' + '\tExpected: "' + text + '"\n' + @@ -1832,11 +1834,11 @@ module FourSlash { jsonMismatchString()); } - for (var i = 0; i < expected.length; i++) { - var expectedClassification = expected[i]; - var actualClassification = actual[i]; + for (let i = 0; i < expected.length; i++) { + let expectedClassification = expected[i]; + let actualClassification = actual[i]; - var expectedType: string = (ts.ClassificationTypeNames)[expectedClassification.classificationType]; + let expectedType: string = (ts.ClassificationTypeNames)[expectedClassification.classificationType]; if (expectedType !== actualClassification.classificationType) { this.raiseError('verifyClassifications failed - expected classifications type to be ' + expectedType + ', but was ' + @@ -1844,11 +1846,11 @@ module FourSlash { jsonMismatchString()); } - var expectedSpan = expectedClassification.textSpan; - var actualSpan = actualClassification.textSpan; + let expectedSpan = expectedClassification.textSpan; + let actualSpan = actualClassification.textSpan; if (expectedSpan) { - var expectedLength = expectedSpan.end - expectedSpan.start; + let expectedLength = expectedSpan.end - expectedSpan.start; if (expectedSpan.start !== actualSpan.start || expectedLength !== actualSpan.length) { this.raiseError("verifyClassifications failed - expected span of text to be " + @@ -1858,7 +1860,7 @@ module FourSlash { } } - var actualText = this.activeFile.content.substr(actualSpan.start, actualSpan.length); + let actualText = this.activeFile.content.substr(actualSpan.start, actualSpan.length); if (expectedClassification.text !== actualText) { this.raiseError('verifyClassifications failed - expected classified text to be ' + expectedClassification.text + ', but was ' + @@ -1882,22 +1884,22 @@ module FourSlash { ); assert.equal( expected.join(","), - actual.fileNames.map( file => { - return file.replace(this.basePath + "/", "") + actual.fileNameList.map( file => { + return file.replace(this.basePath + "/", ""); }).join(",") ); } } public verifySemanticClassifications(expected: { classificationType: string; text: string }[]) { - var actual = this.languageService.getSemanticClassifications(this.activeFile.fileName, + let actual = this.languageService.getSemanticClassifications(this.activeFile.fileName, ts.createTextSpan(0, this.activeFile.content.length)); this.verifyClassifications(expected, actual); } public verifySyntacticClassifications(expected: { classificationType: string; text: string }[]) { - var actual = this.languageService.getSyntacticClassifications(this.activeFile.fileName, + let actual = this.languageService.getSyntacticClassifications(this.activeFile.fileName, ts.createTextSpan(0, this.activeFile.content.length)); this.verifyClassifications(expected, actual); @@ -1906,15 +1908,15 @@ module FourSlash { public verifyOutliningSpans(spans: TextSpan[]) { this.taoInvalidReason = 'verifyOutliningSpans NYI'; - var actual = this.languageService.getOutliningSpans(this.activeFile.fileName); + let actual = this.languageService.getOutliningSpans(this.activeFile.fileName); if (actual.length !== spans.length) { this.raiseError('verifyOutliningSpans failed - expected total spans to be ' + spans.length + ', but was ' + actual.length); } - for (var i = 0; i < spans.length; i++) { - var expectedSpan = spans[i]; - var actualSpan = actual[i]; + for (let i = 0; i < spans.length; i++) { + let expectedSpan = spans[i]; + let actualSpan = actual[i]; if (expectedSpan.start !== actualSpan.textSpan.start || expectedSpan.end !== ts.textSpanEnd(actualSpan.textSpan)) { this.raiseError('verifyOutliningSpans failed - span ' + (i + 1) + ' expected: (' + expectedSpan.start + ',' + expectedSpan.end + '), actual: (' + actualSpan.textSpan.start + ',' + ts.textSpanEnd(actualSpan.textSpan) + ')'); } @@ -1922,17 +1924,17 @@ module FourSlash { } public verifyTodoComments(descriptors: string[], spans: TextSpan[]) { - var actual = this.languageService.getTodoComments(this.activeFile.fileName, + let actual = this.languageService.getTodoComments(this.activeFile.fileName, descriptors.map(d => { return { text: d, priority: 0 }; })); if (actual.length !== spans.length) { this.raiseError('verifyTodoComments failed - expected total spans to be ' + spans.length + ', but was ' + actual.length); } - for (var i = 0; i < spans.length; i++) { - var expectedSpan = spans[i]; - var actualComment = actual[i]; - var actualCommentSpan = ts.createTextSpan(actualComment.position, actualComment.message.length); + for (let i = 0; i < spans.length; i++) { + let expectedSpan = spans[i]; + let actualComment = actual[i]; + let actualCommentSpan = ts.createTextSpan(actualComment.position, actualComment.message.length); if (expectedSpan.start !== actualCommentSpan.start || expectedSpan.end !== ts.textSpanEnd(actualCommentSpan)) { this.raiseError('verifyOutliningSpans failed - span ' + (i + 1) + ' expected: (' + expectedSpan.start + ',' + expectedSpan.end + '), actual: (' + actualCommentSpan.start + ',' + ts.textSpanEnd(actualCommentSpan) + ')'); @@ -1943,13 +1945,13 @@ module FourSlash { public verifyMatchingBracePosition(bracePosition: number, expectedMatchPosition: number) { this.taoInvalidReason = 'verifyMatchingBracePosition NYI'; - var actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition); + let actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition); if (actual.length !== 2) { this.raiseError('verifyMatchingBracePosition failed - expected result to contain 2 spans, but it had ' + actual.length); } - var actualMatchPosition = -1; + let actualMatchPosition = -1; if (bracePosition === actual[0].start) { actualMatchPosition = actual[1].start; } else if (bracePosition === actual[1].start) { @@ -1966,7 +1968,7 @@ module FourSlash { public verifyNoMatchingBracePosition(bracePosition: number) { this.taoInvalidReason = 'verifyNoMatchingBracePosition NYI'; - var actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition); + let actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition); if (actual.length !== 0) { this.raiseError('verifyNoMatchingBracePosition failed - expected: 0 spans, actual: ' + actual.length); @@ -1980,12 +1982,12 @@ module FourSlash { public verifyNavigationItemsCount(expected: number, searchValue: string, matchKind?: string) { this.taoInvalidReason = 'verifyNavigationItemsCount NYI'; - var items = this.languageService.getNavigateToItems(searchValue); - var actual = 0; - var item: ts.NavigateToItem = null; + let items = this.languageService.getNavigateToItems(searchValue); + let actual = 0; + let item: ts.NavigateToItem = null; // Count only the match that match the same MatchKind - for (var i = 0; i < items.length; ++i) { + for (let i = 0; i < items.length; ++i) { item = items[i]; if (!matchKind || item.matchKind === matchKind) { actual++; @@ -2010,14 +2012,14 @@ module FourSlash { parentName?: string) { this.taoInvalidReason = 'verifyNavigationItemsListContains NYI'; - var items = this.languageService.getNavigateToItems(searchValue); + let items = this.languageService.getNavigateToItems(searchValue); if (!items || items.length === 0) { this.raiseError('verifyNavigationItemsListContains failed - found 0 navigation items, expected at least one.'); } - for (var i = 0; i < items.length; i++) { - var item = items[i]; + for (let i = 0; i < items.length; i++) { + let item = items[i]; if (item && item.name === name && item.kind === kind && (matchKind === undefined || item.matchKind === matchKind) && (fileName === undefined || item.fileName === fileName) && @@ -2028,7 +2030,7 @@ module FourSlash { // if there was an explicit match kind specified, then it should be validated. if (matchKind !== undefined) { - var missingItem = { name: name, kind: kind, searchValue: searchValue, matchKind: matchKind, fileName: fileName, parentName: parentName }; + let missingItem = { name: name, kind: kind, searchValue: searchValue, matchKind: matchKind, fileName: fileName, parentName: parentName }; this.raiseError('verifyNavigationItemsListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(items) + ')'); } } @@ -2036,8 +2038,8 @@ module FourSlash { public verifyGetScriptLexicalStructureListCount(expected: number) { this.taoInvalidReason = 'verifyNavigationItemsListContains impossible'; - var items = this.languageService.getNavigationBarItems(this.activeFile.fileName); - var actual = this.getNavigationBarItemsCount(items); + let items = this.languageService.getNavigationBarItems(this.activeFile.fileName); + let actual = this.getNavigationBarItemsCount(items); if (expected !== actual) { this.raiseError('verifyGetScriptLexicalStructureListCount failed - found: ' + actual + ' navigation items, expected: ' + expected + '.'); @@ -2045,9 +2047,9 @@ module FourSlash { } private getNavigationBarItemsCount(items: ts.NavigationBarItem[]) { - var result = 0; + let result = 0; if (items) { - for (var i = 0, n = items.length; i < n; i++) { + for (let i = 0, n = items.length; i < n; i++) { result++; result += this.getNavigationBarItemsCount(items[i].childItems); } @@ -2062,7 +2064,7 @@ module FourSlash { markerPosition?: number) { this.taoInvalidReason = 'verifGetScriptLexicalStructureListContains impossible'; - var items = this.languageService.getNavigationBarItems(this.activeFile.fileName); + let items = this.languageService.getNavigationBarItems(this.activeFile.fileName); if (!items || items.length === 0) { this.raiseError('verifyGetScriptLexicalStructureListContains failed - found 0 navigation items, expected at least one.'); @@ -2072,14 +2074,14 @@ module FourSlash { return; } - var missingItem = { name: name, kind: kind }; + let missingItem = { name: name, kind: kind }; this.raiseError('verifyGetScriptLexicalStructureListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(items, null, " ") + ')'); } private navigationBarItemsContains(items: ts.NavigationBarItem[], name: string, kind: string) { if (items) { - for (var i = 0; i < items.length; i++) { - var item = items[i]; + for (let i = 0; i < items.length; i++) { + let item = items[i]; if (item && item.text === name && item.kind === kind) { return true; } @@ -2094,25 +2096,25 @@ module FourSlash { } public printNavigationItems(searchValue: string) { - var items = this.languageService.getNavigateToItems(searchValue); - var length = items && items.length; + let items = this.languageService.getNavigateToItems(searchValue); + let length = items && items.length; Harness.IO.log('NavigationItems list (' + length + ' items)'); - for (var i = 0; i < length; i++) { - var item = items[i]; + for (let i = 0; i < length; i++) { + let item = items[i]; Harness.IO.log('name: ' + item.name + ', kind: ' + item.kind + ', parentName: ' + item.containerName + ', fileName: ' + item.fileName); } } public printScriptLexicalStructureItems() { - var items = this.languageService.getNavigationBarItems(this.activeFile.fileName); - var length = items && items.length; + let items = this.languageService.getNavigationBarItems(this.activeFile.fileName); + let length = items && items.length; Harness.IO.log('NavigationItems list (' + length + ' items)'); - for (var i = 0; i < length; i++) { - var item = items[i]; + for (let i = 0; i < length; i++) { + let item = items[i]; Harness.IO.log('name: ' + item.text + ', kind: ' + item.kind); } } @@ -2124,14 +2126,14 @@ module FourSlash { public verifyOccurrencesAtPositionListContains(fileName: string, start: number, end: number, isWriteAccess?: boolean) { this.taoInvalidReason = 'verifyOccurrencesAtPositionListContains NYI'; - var occurances = this.getOccurancesAtCurrentPosition(); + let occurances = this.getOccurancesAtCurrentPosition(); if (!occurances || occurances.length === 0) { this.raiseError('verifyOccurancesAtPositionListContains failed - found 0 references, expected at least one.'); } - for (var i = 0; i < occurances.length; i++) { - var occurance = occurances[i]; + for (let i = 0; i < occurances.length; i++) { + let occurance = occurances[i]; if (occurance && occurance.fileName === fileName && occurance.textSpan.start === start && ts.textSpanEnd(occurance.textSpan) === end) { if (typeof isWriteAccess !== "undefined" && occurance.isWriteAccess !== isWriteAccess) { this.raiseError('verifyOccurancesAtPositionListContains failed - item isWriteAccess value doe not match, actual: ' + occurance.isWriteAccess + ', expected: ' + isWriteAccess + '.'); @@ -2140,15 +2142,15 @@ module FourSlash { } } - var missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess }; + let missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess }; this.raiseError('verifyOccurancesAtPositionListContains failed - could not find the item: ' + JSON.stringify(missingItem) + ' in the returned list: (' + JSON.stringify(occurances) + ')'); } public verifyOccurrencesAtPositionListCount(expectedCount: number) { this.taoInvalidReason = 'verifyOccurrencesAtPositionListCount NYI'; - var occurances = this.getOccurancesAtCurrentPosition(); - var actualCount = occurances ? occurances.length : 0; + let occurances = this.getOccurancesAtCurrentPosition(); + let actualCount = occurances ? occurances.length : 0; if (expectedCount !== actualCount) { this.raiseError('verifyOccurrencesAtPositionListCount failed - actual: ' + actualCount + ', expected:' + expectedCount); } @@ -2156,13 +2158,13 @@ module FourSlash { // Get the text of the entire line the caret is currently at private getCurrentLineContent() { - var text = this.getFileContent(this.activeFile.fileName) + let text = this.getFileContent(this.activeFile.fileName); - var pos = this.currentCaretPosition; - var startPos = pos, endPos = pos; + let pos = this.currentCaretPosition; + let startPos = pos, endPos = pos; while (startPos > 0) { - var ch = text.charCodeAt(startPos - 1); + let ch = text.charCodeAt(startPos - 1); if (ch === ts.CharacterCodes.carriageReturn || ch === ts.CharacterCodes.lineFeed) { break; } @@ -2171,7 +2173,7 @@ module FourSlash { } while (endPos < text.length) { - var ch = text.charCodeAt(endPos); + let ch = text.charCodeAt(endPos); if (ch === ts.CharacterCodes.carriageReturn || ch === ts.CharacterCodes.lineFeed) { break; @@ -2191,11 +2193,11 @@ module FourSlash { this.taoInvalidReason = 'assertItemInCompletionList only supports the "name" parameter'; } - for (var i = 0; i < items.length; i++) { - var item = items[i]; + for (let i = 0; i < items.length; i++) { + let item = items[i]; if (item.name === name) { if (documentation != undefined || text !== undefined) { - var details = this.getCompletionEntryDetails(item.name); + let details = this.getCompletionEntryDetails(item.name); if (documentation !== undefined) { assert.equal(ts.displayPartsToString(details.documentation), documentation, assertionMessage("completion item documentation")); @@ -2213,30 +2215,30 @@ module FourSlash { } } - var itemsString = items.map((item) => JSON.stringify({ name: item.name, kind: item.kind })).join(",\n"); + let itemsString = items.map((item) => JSON.stringify({ name: item.name, kind: item.kind })).join(",\n"); this.raiseError('Expected "' + JSON.stringify({ name, text, documentation, kind }) + '" to be in list [' + itemsString + ']'); } private findFile(indexOrName: any) { - var result: FourSlashFile = null; + let result: FourSlashFile = null; if (typeof indexOrName === 'number') { - var index = indexOrName; + let index = indexOrName; if (index >= this.testData.files.length) { throw new Error('File index (' + index + ') in openFile was out of range. There are only ' + this.testData.files.length + ' files in this test.'); } else { result = this.testData.files[index]; } } else if (typeof indexOrName === 'string') { - var name = indexOrName; + let name = indexOrName; // names are stored in the compiler with this relative path, this allows people to use goTo.file on just the fileName name = name.indexOf('/') === -1 ? (this.basePath + '/' + name) : name; - var availableNames: string[] = []; - var foundIt = false; - for (var i = 0; i < this.testData.files.length; i++) { - var fn = this.testData.files[i].fileName; + let availableNames: string[] = []; + let foundIt = false; + for (let i = 0; i < this.testData.files.length; i++) { + let fn = this.testData.files[i].fileName; if (fn) { if (fn === name) { result = this.testData.files[i]; @@ -2258,15 +2260,15 @@ module FourSlash { } private getLineColStringAtPosition(position: number) { - var pos = this.languageServiceAdapterHost.positionToLineAndCharacter(this.activeFile.fileName, position); + let pos = this.languageServiceAdapterHost.positionToLineAndCharacter(this.activeFile.fileName, position); return 'line ' + (pos.line + 1) + ', col ' + pos.character; } private getMarkerByName(markerName: string) { - var markerPos = this.testData.markerPositions[markerName]; + let markerPos = this.testData.markerPositions[markerName]; if (markerPos === undefined) { - var markerNames: string[] = []; - for (var m in this.testData.markerPositions) markerNames.push(m); + let markerNames: string[] = []; + for (let m in this.testData.markerPositions) markerNames.push(m); throw new Error('Unknown marker "' + markerName + '" Available markers: ' + markerNames.map(m => '"' + m + '"').join(', ')); } else { return markerPos; @@ -2286,7 +2288,7 @@ module FourSlash { } public setCancelled(numberOfCalls: number): void { - this.cancellationToken.setCancelled(numberOfCalls) + this.cancellationToken.setCancelled(numberOfCalls); } public resetCancelled(): void { @@ -2295,12 +2297,12 @@ module FourSlash { } // TOOD: should these just use the Harness's stdout/stderr? - var fsOutput = new Harness.Compiler.WriterAggregator(); - var fsErrors = new Harness.Compiler.WriterAggregator(); - export var xmlData: TestXmlData[] = []; + let fsOutput = new Harness.Compiler.WriterAggregator(); + let fsErrors = new Harness.Compiler.WriterAggregator(); + export let xmlData: TestXmlData[] = []; export function runFourSlashTest(basePath: string, testType: FourSlashTestType, fileName: string) { - var content = Harness.IO.readFile(fileName); - var xml = runFourSlashTestContent(basePath, testType, content, fileName); + let content = Harness.IO.readFile(fileName); + let xml = runFourSlashTestContent(basePath, testType, content, fileName); xmlData.push(xml); } @@ -2365,8 +2367,8 @@ module FourSlash { } function chompLeadingSpace(content: string) { - var lines = content.split("\n"); - for (var i = 0; i < lines.length; i++) { + let lines = content.split("\n"); + for (let i = 0; i < lines.length; i++) { if ((lines[i].length !== 0) && (lines[i].charAt(0) !== ' ')) { return content; } @@ -2377,31 +2379,31 @@ module FourSlash { function parseTestData(basePath: string, contents: string, fileName: string): FourSlashData { // Regex for parsing options in the format "@Alpha: Value of any sort" - var optionRegex = /^\s*@(\w+): (.*)\s*/; + let optionRegex = /^\s*@(\w+): (.*)\s*/; // List of all the subfiles we've parsed out - var files: FourSlashFile[] = []; + let files: FourSlashFile[] = []; // Global options - var globalOptions: { [s: string]: string; } = {}; + let globalOptions: { [s: string]: string; } = {}; // Marker positions // Split up the input file by line // Note: IE JS engine incorrectly handles consecutive delimiters here when using RegExp split, so // we have to string-based splitting instead and try to figure out the delimiting chars - var lines = contents.split('\n'); + let lines = contents.split('\n'); - var markerPositions: MarkerMap = {}; - var markers: Marker[] = []; - var ranges: Range[] = []; + let markerPositions: MarkerMap = {}; + let markers: Marker[] = []; + let ranges: Range[] = []; // Stuff related to the subfile we're parsing - var currentFileContent: string = null; - var currentFileName = fileName; - var currentFileOptions: { [s: string]: string } = {}; + let currentFileContent: string = null; + let currentFileName = fileName; + let currentFileOptions: { [s: string]: string } = {}; - for (var i = 0; i < lines.length; i++) { - var line = lines[i]; - var lineLength = line.length; + for (let i = 0; i < lines.length; i++) { + let line = lines[i]; + let lineLength = line.length; if (lineLength > 0 && line.charAt(lineLength - 1) === '\r') { line = line.substr(0, lineLength - 1); @@ -2421,17 +2423,17 @@ module FourSlash { currentFileContent = currentFileContent + line.substr(4); } else if (line.substr(0, 2) === '//') { // Comment line, check for global/file @options and record them - var match = optionRegex.exec(line.substr(2)); + let match = optionRegex.exec(line.substr(2)); if (match) { - var globalMetadataNamesIndex = globalMetadataNames.indexOf(match[1]); - var fileMetadataNamesIndex = fileMetadataNames.indexOf(match[1]); + let globalMetadataNamesIndex = globalMetadataNames.indexOf(match[1]); + let fileMetadataNamesIndex = fileMetadataNames.indexOf(match[1]); if (globalMetadataNamesIndex === -1) { if (fileMetadataNamesIndex === -1) { throw new Error('Unrecognized metadata name "' + match[1] + '". Available global metadata names are: ' + globalMetadataNames.join(', ') + '; file metadata names are: ' + fileMetadataNames.join(', ')); } else if (fileMetadataNamesIndex === fileMetadataNames.indexOf(metadataOptionNames.fileName)) { // Found an @FileName directive, if this is not the first then create a new subfile if (currentFileContent) { - var file = parseFileContent(currentFileContent, currentFileName, markerPositions, markers, ranges); + let file = parseFileContent(currentFileContent, currentFileName, markerPositions, markers, ranges); file.fileOptions = currentFileOptions; // Store result file @@ -2464,7 +2466,7 @@ module FourSlash { } else { // Empty line or code line, terminate current subfile if there is one if (currentFileContent) { - var file = parseFileContent(currentFileContent, currentFileName, markerPositions, markers, ranges); + let file = parseFileContent(currentFileContent, currentFileName, markerPositions, markers, ranges); file.fileOptions = currentFileOptions; // Store result file @@ -2494,12 +2496,12 @@ module FourSlash { } function reportError(fileName: string, line: number, col: number, message: string) { - var errorMessage = fileName + "(" + line + "," + col + "): " + message; + let errorMessage = fileName + "(" + line + "," + col + "): " + message; throw new Error(errorMessage); } function recordObjectMarker(fileName: string, location: ILocationInformation, text: string, markerMap: MarkerMap, markers: Marker[]): Marker { - var markerValue: any = undefined; + let markerValue: any = undefined; try { // Attempt to parse the marker value as JSON markerValue = JSON.parse("{ " + text + " }"); @@ -2512,7 +2514,7 @@ module FourSlash { return null; } - var marker: Marker = { + let marker: Marker = { fileName: fileName, position: location.position, data: markerValue @@ -2529,14 +2531,14 @@ module FourSlash { } function recordMarker(fileName: string, location: ILocationInformation, name: string, markerMap: MarkerMap, markers: Marker[]): Marker { - var marker: Marker = { + let marker: Marker = { fileName: fileName, position: location.position }; // Verify markers for uniqueness if (markerMap[name] !== undefined) { - var message = "Marker '" + name + "' is duplicated in the source file contents."; + let message = "Marker '" + name + "' is duplicated in the source file contents."; reportError(marker.fileName, location.sourceLine, location.sourceColumn, message); return null; } else { @@ -2550,34 +2552,34 @@ module FourSlash { content = chompLeadingSpace(content); // Any slash-star comment with a character not in this string is not a marker. - var validMarkerChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz$1234567890_'; + let validMarkerChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz$1234567890_'; /// The file content (minus metacharacters) so far - var output: string = ""; + let output: string = ""; /// The current marker (or maybe multi-line comment?) we're parsing, possibly - var openMarker: ILocationInformation = null; + let openMarker: ILocationInformation = null; /// A stack of the open range markers that are still unclosed - var openRanges: IRangeLocationInformation[] = []; + let openRanges: IRangeLocationInformation[] = []; /// A list of ranges we've collected so far */ - var localRanges: Range[] = []; + let localRanges: Range[] = []; /// The latest position of the start of an unflushed plain text area - var lastNormalCharPosition: number = 0; + let lastNormalCharPosition: number = 0; /// The total number of metacharacters removed from the file (so far) - var difference: number = 0; + let difference: number = 0; /// The fourslash file state object we are generating - var state: State = State.none; + let state: State = State.none; /// Current position data - var line: number = 1; - var column: number = 1; + let line: number = 1; + let column: number = 1; - var flush = (lastSafeCharIndex: number) => { + let flush = (lastSafeCharIndex: number) => { if (lastSafeCharIndex === undefined) { output = output + content.substr(lastNormalCharPosition); } else { @@ -2586,9 +2588,9 @@ module FourSlash { }; if (content.length > 0) { - var previousChar = content.charAt(0); - for (var i = 1; i < content.length; i++) { - var currentChar = content.charAt(i); + let previousChar = content.charAt(0); + for (let i = 1; i < content.length; i++) { + let currentChar = content.charAt(i); switch (state) { case State.none: if (previousChar === "[" && currentChar === "|") { @@ -2605,12 +2607,12 @@ module FourSlash { difference += 2; } else if (previousChar === "|" && currentChar === "]") { // found a range end - var rangeStart = openRanges.pop(); + let rangeStart = openRanges.pop(); if (!rangeStart) { reportError(fileName, line, column, "Found range end with no matching start."); } - var range: Range = { + let range: Range = { fileName: fileName, start: rangeStart.position, end: (i - 1) - difference, @@ -2648,8 +2650,8 @@ module FourSlash { // Object markers are only ever terminated by |} and have no content restrictions if (previousChar === "|" && currentChar === "}") { // Record the marker - var objectMarkerNameText = content.substring(openMarker.sourcePosition + 2, i - 1).trim(); - var marker = recordObjectMarker(fileName, openMarker, objectMarkerNameText, markerMap, markers); + let objectMarkerNameText = content.substring(openMarker.sourcePosition + 2, i - 1).trim(); + let marker = recordObjectMarker(fileName, openMarker, objectMarkerNameText, markerMap, markers); if (openRanges.length > 0) { openRanges[openRanges.length - 1].marker = marker; @@ -2669,8 +2671,8 @@ module FourSlash { if (previousChar === "*" && currentChar === "/") { // Record the marker // start + 2 to ignore the */, -1 on the end to ignore the * (/ is next) - var markerNameText = content.substring(openMarker.sourcePosition + 2, i - 1).trim(); - var marker = recordMarker(fileName, openMarker, markerNameText, markerMap, markers); + let markerNameText = content.substring(openMarker.sourcePosition + 2, i - 1).trim(); + let marker = recordMarker(fileName, openMarker, markerNameText, markerMap, markers); if (openRanges.length > 0) { openRanges[openRanges.length - 1].marker = marker; @@ -2718,7 +2720,7 @@ module FourSlash { flush(undefined); if (openRanges.length > 0) { - var openRange = openRanges[0]; + let openRange = openRanges[0]; reportError(fileName, openRange.sourceLine, openRange.sourceColumn, "Unterminated range."); } diff --git a/src/harness/fourslashRunner.ts b/src/harness/fourslashRunner.ts index 0db01c30f32..05a11c4f52d 100644 --- a/src/harness/fourslashRunner.ts +++ b/src/harness/fourslashRunner.ts @@ -2,7 +2,7 @@ /// /// -const enum FourSlashTestType { +const enum FourSlashTestType { Native, Shims, Server @@ -35,70 +35,72 @@ class FourSlashRunner extends RunnerBase { this.tests = this.enumerateFiles(this.basePath, /\.ts/i, { recursive: false }); } - this.tests.forEach((fn: string) => { - describe(fn, () => { - fn = ts.normalizeSlashes(fn); - var justName = fn.replace(/^.*[\\\/]/, ''); + describe(this.testSuiteName + ' tests', () => { + this.tests.forEach((fn: string) => { + describe(fn, () => { + fn = ts.normalizeSlashes(fn); + let justName = fn.replace(/^.*[\\\/]/, ''); - // Convert to relative path - var testIndex = fn.indexOf('tests/'); - if (testIndex >= 0) fn = fn.substr(testIndex); + // Convert to relative path + let testIndex = fn.indexOf('tests/'); + if (testIndex >= 0) fn = fn.substr(testIndex); - if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) { - it(this.testSuiteName + ' test ' + justName + ' runs correctly', () => { - FourSlash.runFourSlashTest(this.basePath, this.testType, fn); - }); - } + if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) { + it(this.testSuiteName + ' test ' + justName + ' runs correctly', () => { + FourSlash.runFourSlashTest(this.basePath, this.testType, fn); + }); + } + }); }); - }); - describe('Generate Tao XML', () => { - var invalidReasons: any = {}; - FourSlash.xmlData.forEach(xml => { - if (xml.invalidReason !== null) { - invalidReasons[xml.invalidReason] = (invalidReasons[xml.invalidReason] || 0) + 1; + describe('Generate Tao XML', () => { + let invalidReasons: any = {}; + FourSlash.xmlData.forEach(xml => { + if (xml.invalidReason !== null) { + invalidReasons[xml.invalidReason] = (invalidReasons[xml.invalidReason] || 0) + 1; + } + }); + let invalidReport: { reason: string; count: number }[] = []; + for (let reason in invalidReasons) { + if (invalidReasons.hasOwnProperty(reason)) { + invalidReport.push({ reason: reason, count: invalidReasons[reason] }); + } } - }); - var invalidReport: { reason: string; count: number }[] = []; - for (var reason in invalidReasons) { - if (invalidReasons.hasOwnProperty(reason)) { - invalidReport.push({ reason: reason, count: invalidReasons[reason] }); - } - } - invalidReport.sort((lhs, rhs) => lhs.count > rhs.count ? -1 : lhs.count === rhs.count ? 0 : 1); + invalidReport.sort((lhs, rhs) => lhs.count > rhs.count ? -1 : lhs.count === rhs.count ? 0 : 1); - var lines: string[] = []; - lines.push(''); + lines.push(''); + lines.push(' '); + lines.push(' '); + lines.push(' '); + lines.push(' '); + FourSlash.xmlData.forEach(xml => { + if (xml.invalidReason !== null) { + lines.push(''); + } else { + lines.push(' '); + xml.actions.forEach(action => { + lines.push(' ' + action); + }); + lines.push(' '); + } + }); + lines.push(' '); + lines.push(' '); + lines.push(' '); + lines.push(' '); + lines.push(' '); + lines.push(' '); + lines.push(' '); + lines.push(' '); + lines.push(''); + Harness.IO.writeFile('built/local/fourslash.xml', lines.join('\r\n')); }); - lines.push('-->'); - lines.push(''); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - FourSlash.xmlData.forEach(xml => { - if (xml.invalidReason !== null) { - lines.push(''); - } else { - lines.push(' '); - xml.actions.forEach(action => { - lines.push(' ' + action); - }); - lines.push(' '); - } - }); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(' '); - lines.push(''); - Harness.IO.writeFile('built/local/fourslash.xml', lines.join('\r\n')); }); } } @@ -108,4 +110,4 @@ class GeneratedFourslashRunner extends FourSlashRunner { super(testType); this.basePath += '/generated/'; } -} \ No newline at end of file +} diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 9f26887ff90..17aa0dd325c 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -33,8 +33,6 @@ declare var __dirname: string; // Node-specific var global = Function("return this").call(null); module Utils { - var global = Function("return this").call(null); - // Setup some globals based on the current environment export const enum ExecutionEnvironment { Node, @@ -54,17 +52,17 @@ module Utils { } } - export var currentExecutionEnvironment = getExecutionEnvironment(); + export let currentExecutionEnvironment = getExecutionEnvironment(); export function evalFile(fileContents: string, fileName: string, nodeContext?: any) { - var environment = getExecutionEnvironment(); + let environment = getExecutionEnvironment(); switch (environment) { case ExecutionEnvironment.CScript: case ExecutionEnvironment.Browser: eval(fileContents); break; case ExecutionEnvironment.Node: - var vm = require('vm'); + let vm = require('vm'); if (nodeContext) { vm.runInNewContext(fileContents, nodeContext, fileName); } else { @@ -81,7 +79,7 @@ module Utils { // Split up the input file by line // Note: IE JS engine incorrectly handles consecutive delimiters here when using RegExp split, so // we have to use string-based splitting instead and try to figure out the delimiting chars - var lines = content.split('\r\n'); + let lines = content.split('\r\n'); if (lines.length === 1) { lines = content.split('\n'); @@ -98,8 +96,9 @@ module Utils { path = "tests/" + path; } + let content: string = undefined; try { - var content = ts.sys.readFile(Harness.userSpecifiedRoot + path); + content = ts.sys.readFile(Harness.userSpecifiedRoot + path); } catch (err) { return undefined; @@ -109,11 +108,11 @@ module Utils { } export function memoize(f: T): T { - var cache: { [idx: string]: any } = {}; + let cache: { [idx: string]: any } = {}; return (function () { - var key = Array.prototype.join.call(arguments); - var cachedResult = cache[key]; + let key = Array.prototype.join.call(arguments); + let cachedResult = cache[key]; if (cachedResult) { return cachedResult; } else { @@ -140,7 +139,7 @@ module Utils { }); // Make sure each of the children is in order. - var currentPos = 0; + let currentPos = 0; ts.forEachChild(node, child => { assert.isFalse(child.pos < currentPos, "child.pos < currentPos"); @@ -151,22 +150,22 @@ module Utils { assert.isFalse(array.end > node.end, "array.end > node.end"); assert.isFalse(array.pos < currentPos, "array.pos < currentPos"); - for (var i = 0, n = array.length; i < n; i++) { + for (let i = 0, n = array.length; i < n; i++) { assert.isFalse(array[i].pos < currentPos, "array[i].pos < currentPos"); - currentPos = array[i].end + currentPos = array[i].end; } currentPos = array.end; }); - var childNodesAndArrays: any[] = []; - ts.forEachChild(node, child => { childNodesAndArrays.push(child) }, array => { childNodesAndArrays.push(array) }); + let childNodesAndArrays: any[] = []; + ts.forEachChild(node, child => { childNodesAndArrays.push(child); }, array => { childNodesAndArrays.push(array); }); - for (var childName in node) { + for (let childName in node) { if (childName === "parent" || childName === "nextContainer" || childName === "modifiers" || childName === "externalModuleIndicator") { continue; } - var child = (node)[childName]; + let child = (node)[childName]; if (isNodeOrArray(child)) { assert.isFalse(childNodesAndArrays.indexOf(child) < 0, "Missing child when forEach'ing over node: " + (ts).SyntaxKind[node.kind] + "-" + childName); @@ -194,7 +193,7 @@ module Utils { } export function sourceFileToJSON(file: ts.Node): string { - return JSON.stringify(file,(k, v) => { + return JSON.stringify(file, (k, v) => { return isNodeOrArray(v) ? serializeNode(v) : v; }, " "); @@ -203,7 +202,7 @@ module Utils { return k; } - return (ts).SyntaxKind[k] + return (ts).SyntaxKind[k]; } function getFlagName(flags: any, f: number): any { @@ -211,7 +210,7 @@ module Utils { return 0; } - var result = ""; + let result = ""; ts.forEach(Object.getOwnPropertyNames(flags), (v: any) => { if (isFinite(v)) { v = +v; @@ -234,7 +233,7 @@ module Utils { function getParserContextFlagName(f: number) { return getFlagName((ts).ParserContextFlags, f); } function serializeNode(n: ts.Node): any { - var o: any = { kind: getKindName(n.kind) }; + let o: any = { kind: getKindName(n.kind) }; if (ts.containsParseError(n)) { o.containsParseError = true; } @@ -268,7 +267,7 @@ module Utils { // Clear the flag that are produced by aggregating child values.. That is ephemeral // data we don't care about in the dump. We only care what the parser set directly // on the ast. - var value = n.parserContextFlags & ts.ParserContextFlags.ParserGeneratedFlags; + let value = n.parserContextFlags & ts.ParserContextFlags.ParserGeneratedFlags; if (value) { o[propertyName] = getParserContextFlagName(value); } @@ -313,9 +312,9 @@ module Utils { assert.equal(array1.length, array2.length, "array1.length !== array2.length"); - for (var i = 0, n = array1.length; i < n; i++) { - var d1 = array1[i]; - var d2 = array2[i]; + for (let i = 0, n = array1.length; i < n; i++) { + let d1 = array1[i]; + let d2 = array2[i]; assert.equal(d1.start, d2.start, "d1.start !== d2.start"); assert.equal(d1.length, d2.length, "d1.length !== d2.length"); @@ -346,14 +345,14 @@ module Utils { ts.forEachChild(node1, child1 => { - var childName = findChildName(node1, child1); - var child2: ts.Node = (node2)[childName]; + let childName = findChildName(node1, child1); + let child2: ts.Node = (node2)[childName]; assertStructuralEquals(child1, child2); }, (array1: ts.NodeArray) => { - var childName = findChildName(node1, array1); - var array2: ts.NodeArray = (node2)[childName]; + let childName = findChildName(node1, array1); + let array2: ts.NodeArray = (node2)[childName]; assertArrayStructuralEquals(array1, array2); }); @@ -370,13 +369,13 @@ module Utils { assert.equal(array1.end, array2.end, "array1.end !== array2.end"); assert.equal(array1.length, array2.length, "array1.length !== array2.length"); - for (var i = 0, n = array1.length; i < n; i++) { + for (let i = 0, n = array1.length; i < n; i++) { assertStructuralEquals(array1[i], array2[i]); } } function findChildName(parent: any, child: any) { - for (var name in parent) { + for (let name in parent) { if (parent.hasOwnProperty(name) && parent[name] === child) { return name; } @@ -393,8 +392,8 @@ module Harness.Path { export function filePath(fullPath: string) { fullPath = ts.normalizeSlashes(fullPath); - var components = fullPath.split("/"); - var path: string[] = components.slice(0, components.length - 1); + let components = fullPath.split("/"); + let path: string[] = components.slice(0, components.length - 1); return path.join("/") + "/"; } } @@ -422,19 +421,19 @@ module Harness { } export module CScript { - var fso: any; + let fso: any; if (global.ActiveXObject) { fso = new global.ActiveXObject("Scripting.FileSystemObject"); } else { fso = {}; } - export var readFile: typeof IO.readFile = ts.sys.readFile; - export var writeFile: typeof IO.writeFile = ts.sys.writeFile; - export var directoryName: typeof IO.directoryName = fso.GetParentFolderName; - export var directoryExists: typeof IO.directoryExists = fso.FolderExists; - export var fileExists: typeof IO.fileExists = fso.FileExists; - export var log: typeof IO.log = global.WScript && global.WScript.StdOut.WriteLine; + export let readFile: typeof IO.readFile = ts.sys.readFile; + export let writeFile: typeof IO.writeFile = ts.sys.writeFile; + export let directoryName: typeof IO.directoryName = fso.GetParentFolderName; + export let directoryExists: typeof IO.directoryExists = fso.FolderExists; + export let fileExists: typeof IO.fileExists = fso.FileExists; + export let log: typeof IO.log = global.WScript && global.WScript.StdOut.WriteLine; export function createDirectory(path: string) { if (directoryExists(path)) { @@ -448,11 +447,11 @@ module Harness { } } - export var listFiles: typeof IO.listFiles = (path, spec?, options?) => { + export let listFiles: typeof IO.listFiles = (path, spec?, options?) => { options = options || <{ recursive?: boolean; }>{}; function filesInFolder(folder: any, root: string): string[] { - var paths: string[] = []; - var fc: any; + let paths: string[] = []; + let fc: any; if (options.recursive) { fc = new Enumerator(folder.subfolders); @@ -473,17 +472,16 @@ module Harness { return paths; } - var folder: any = fso.GetFolder(path); - var paths: string[] = []; + let folder: any = fso.GetFolder(path); + let paths: string[] = []; return filesInFolder(folder, path); - - } + }; } export module Node { - declare var require: any; - var fs: any, pathModule: any; + declare let require: any; + let fs: any, pathModule: any; if (require) { fs = require('fs'); pathModule = require('path'); @@ -491,10 +489,10 @@ module Harness { fs = pathModule = {}; } - export var readFile: typeof IO.readFile = ts.sys.readFile; - export var writeFile: typeof IO.writeFile = ts.sys.writeFile; - export var fileExists: typeof IO.fileExists = fs.existsSync; - export var log: typeof IO.log = console.log; + export let readFile: typeof IO.readFile = ts.sys.readFile; + export let writeFile: typeof IO.writeFile = ts.sys.writeFile; + export let fileExists: typeof IO.fileExists = fs.existsSync; + export let log: typeof IO.log = console.log; export function createDirectory(path: string) { if (!directoryExists(path)) { @@ -514,7 +512,7 @@ module Harness { } export function directoryName(path: string) { - var dirPath = pathModule.dirname(path); + let dirPath = pathModule.dirname(path); // Node will just continue to repeat the root path, rather than return null if (dirPath === path) { @@ -524,16 +522,16 @@ module Harness { } } - export var listFiles: typeof IO.listFiles = (path, spec?, options?) => { + export let listFiles: typeof IO.listFiles = (path, spec?, options?) => { options = options || <{ recursive?: boolean; }>{}; function filesInFolder(folder: string): string[] { - var paths: string[] = []; + let paths: string[] = []; - var files = fs.readdirSync(folder); - for (var i = 0; i < files.length; i++) { - var pathToFile = pathModule.join(folder, files[i]); - var stat = fs.statSync(pathToFile); + let files = fs.readdirSync(folder); + for (let i = 0; i < files.length; i++) { + let pathToFile = pathModule.join(folder, files[i]); + let stat = fs.statSync(pathToFile); if (options.recursive && stat.isDirectory()) { paths = paths.concat(filesInFolder(pathToFile)); } @@ -546,23 +544,23 @@ module Harness { } return filesInFolder(path); - } + }; - export var getMemoryUsage: typeof IO.getMemoryUsage = () => { + export let getMemoryUsage: typeof IO.getMemoryUsage = () => { if (global.gc) { global.gc(); } return process.memoryUsage().heapUsed; - } + }; } export module Network { - var serverRoot = "http://localhost:8888/"; + let serverRoot = "http://localhost:8888/"; // Unused? - var newLine = '\r\n'; - var currentDirectory = () => ''; - var supportsCodePage = () => false; + let newLine = '\r\n'; + let currentDirectory = () => ''; + let supportsCodePage = () => false; module Http { function waitForXHR(xhr: XMLHttpRequest) { @@ -572,7 +570,7 @@ module Harness { /// Ask the server to use node's path.resolve to resolve the given path function getResolvedPathFromServer(path: string) { - var xhr = new XMLHttpRequest(); + let xhr = new XMLHttpRequest(); try { xhr.open("GET", path + "?resolve", false); xhr.send(); @@ -591,7 +589,7 @@ module Harness { /// Ask the server for the contents of the file at the given URL via a simple GET request export function getFileFromServerSync(url: string): XHRResponse { - var xhr = new XMLHttpRequest(); + let xhr = new XMLHttpRequest(); try { xhr.open("GET", url, false); xhr.send(); @@ -605,10 +603,10 @@ module Harness { /// Submit a POST request to the server to do the given action (ex WRITE, DELETE) on the provided URL export function writeToServerSync(url: string, action: string, contents?: string): XHRResponse { - var xhr = new XMLHttpRequest(); + let xhr = new XMLHttpRequest(); try { - var action = '?action=' + action; - xhr.open('POST', url + action, false); + let actionMsg = '?action=' + action; + xhr.open('POST', url + actionMsg, false); xhr.setRequestHeader('Access-Control-Allow-Origin', '*'); xhr.send(contents); } @@ -633,7 +631,7 @@ module Harness { } function directoryNameImpl(path: string) { - var dirPath = path; + let dirPath = path; // root of the server if (dirPath.match(/localhost:\d+$/) || dirPath.match(/localhost:\d+\/$/)) { dirPath = null; @@ -646,22 +644,22 @@ module Harness { if (dirPath.match(/.*\/$/)) { dirPath = dirPath.substring(0, dirPath.length - 2); } - var dirPath = dirPath.substring(0, dirPath.lastIndexOf('/')); + dirPath = dirPath.substring(0, dirPath.lastIndexOf('/')); } return dirPath; } - export var directoryName: typeof IO.directoryName = Utils.memoize(directoryNameImpl); + export let directoryName: typeof IO.directoryName = Utils.memoize(directoryNameImpl); export function fileExists(path: string): boolean { - var response = Http.getFileFromServerSync(serverRoot + path); + let response = Http.getFileFromServerSync(serverRoot + path); return response.status === 200; } export function _listFilesImpl(path: string, spec?: RegExp, options?: any) { - var response = Http.getFileFromServerSync(serverRoot + path); + let response = Http.getFileFromServerSync(serverRoot + path); if (response.status === 200) { - var results = response.responseText.split(','); + let results = response.responseText.split(','); if (spec) { return results.filter(file => spec.test(file)); } else { @@ -672,12 +670,12 @@ module Harness { return ['']; } }; - export var listFiles = Utils.memoize(_listFilesImpl); + export let listFiles = Utils.memoize(_listFilesImpl); - export var log = console.log; + export let log = console.log; export function readFile(file: string) { - var response = Http.getFileFromServerSync(serverRoot + file); + let response = Http.getFileFromServerSync(serverRoot + file); if (response.status === 200) { return response.responseText; } else { @@ -706,9 +704,9 @@ module Harness { } module Harness { - var tcServicesFileName = "typescriptServices.js"; + let tcServicesFileName = "typescriptServices.js"; - export var libFolder: string; + export let libFolder: string; switch (Utils.getExecutionEnvironment()) { case Utils.ExecutionEnvironment.CScript: libFolder = "built/local/"; @@ -725,7 +723,7 @@ module Harness { default: throw new Error('Unknown context'); } - export var tcServicesFile = IO.readFile(tcServicesFileName); + export let tcServicesFile = IO.readFile(tcServicesFileName); export interface SourceMapEmitterCallback { (emittedFile: string, emittedLine: number, emittedColumn: number, sourceFile: string, sourceLine: number, sourceColumn: number, sourceName: string): void; @@ -777,7 +775,7 @@ module Harness { /** create file gets the whole path to create, so this works as expected with the --out parameter */ public writeFile(s: string, contents: string, writeByteOrderMark: boolean): void { - var writer: ITextWriter; + let writer: ITextWriter; if (this.fileCollection[s]) { writer = this.fileCollection[s]; } @@ -795,10 +793,10 @@ module Harness { public reset() { this.fileCollection = {}; } public toArray(): { fileName: string; file: WriterAggregator; }[] { - var result: { fileName: string; file: WriterAggregator; }[] = []; - for (var p in this.fileCollection) { + let result: { fileName: string; file: WriterAggregator; }[] = []; + for (let p in this.fileCollection) { if (this.fileCollection.hasOwnProperty(p)) { - var current = this.fileCollection[p]; + let current = this.fileCollection[p]; if (current.lines.length > 0) { if (p.indexOf('.d.ts') !== -1) { current.lines.unshift(['////[', Path.getFileName(p), ']'].join('')); } result.push({ fileName: p, file: this.fileCollection[p] }); @@ -813,11 +811,11 @@ module Harness { fileName: string, sourceText: string, languageVersion: ts.ScriptTarget) { - // We'll only assert invariants outside of light mode. + // We'll only assert inletiants outside of light mode. const shouldAssertInvariants = !Harness.lightMode; - // Only set the parent nodes if we're asserting invariants. We don't need them otherwise. - var result = ts.createSourceFile(fileName, sourceText, languageVersion, /*setParentNodes:*/ shouldAssertInvariants); + // Only set the parent nodes if we're asserting inletiants. We don't need them otherwise. + let result = ts.createSourceFile(fileName, sourceText, languageVersion, /*setParentNodes:*/ shouldAssertInvariants); if (shouldAssertInvariants) { Utils.assertInvariants(result, /*parent:*/ undefined); @@ -829,13 +827,13 @@ module Harness { const carriageReturnLineFeed = "\r\n"; const lineFeed = "\n"; - export var defaultLibFileName = 'lib.d.ts'; - export var defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest); - export var defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.es6.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest); + export let defaultLibFileName = 'lib.d.ts'; + export let defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest); + export let defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.es6.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest); // Cache these between executions so we don't have to re-parse them for every test - export var fourslashFileName = 'fourslash.ts'; - export var fourslashSourceFile: ts.SourceFile; + export let fourslashFileName = 'fourslash.ts'; + export let fourslashSourceFile: ts.SourceFile; export function getCanonicalFileName(fileName: string): string { return ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(); @@ -855,13 +853,13 @@ module Harness { return useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(); } - var filemap: { [fileName: string]: ts.SourceFile; } = {}; - var getCurrentDirectory = currentDirectory === undefined ? ts.sys.getCurrentDirectory : () => currentDirectory; + let filemap: { [fileName: string]: ts.SourceFile; } = {}; + let getCurrentDirectory = currentDirectory === undefined ? ts.sys.getCurrentDirectory : () => currentDirectory; // Register input files function register(file: { unitName: string; content: string; }) { if (file.content !== undefined) { - var fileName = ts.normalizePath(file.unitName); + let fileName = ts.normalizePath(file.unitName); filemap[getCanonicalFileName(fileName)] = createSourceFileAndAssertInvariants(fileName, file.content, scriptTarget); } }; @@ -880,11 +878,11 @@ module Harness { return filemap[getCanonicalFileName(fn)]; } else if (currentDirectory) { - var canonicalAbsolutePath = getCanonicalFileName(ts.getNormalizedAbsolutePath(fn, currentDirectory)); + let canonicalAbsolutePath = getCanonicalFileName(ts.getNormalizedAbsolutePath(fn, currentDirectory)); return Object.prototype.hasOwnProperty.call(filemap, getCanonicalFileName(canonicalAbsolutePath)) ? filemap[canonicalAbsolutePath] : undefined; } else if (fn === fourslashFileName) { - var tsFn = 'tests/cases/fourslash/' + fourslashFileName; + let tsFn = 'tests/cases/fourslash/' + fourslashFileName; fourslashSourceFile = fourslashSourceFile || createSourceFileAndAssertInvariants(tsFn, Harness.IO.readFile(tsFn), scriptTarget); return fourslashSourceFile; } @@ -980,27 +978,27 @@ module Harness { // Files from built\local that are requested by test "@includeBuiltFiles" to be in the context. // Treat them as library files, so include them in build, but not in baselines. - var includeBuiltFiles: { unitName: string; content: string }[] = []; + let includeBuiltFiles: { unitName: string; content: string }[] = []; - var useCaseSensitiveFileNames = ts.sys.useCaseSensitiveFileNames; + let useCaseSensitiveFileNames = ts.sys.useCaseSensitiveFileNames; this.settings.forEach(setCompilerOptionForSetting); - var fileOutputs: GeneratedFile[] = []; + let fileOutputs: GeneratedFile[] = []; - var programFiles = inputFiles.concat(includeBuiltFiles).map(file => file.unitName); + let programFiles = inputFiles.concat(includeBuiltFiles).map(file => file.unitName); - var compilerHost = createCompilerHost( + let compilerHost = createCompilerHost( inputFiles.concat(includeBuiltFiles).concat(otherFiles), (fn, contents, writeByteOrderMark) => fileOutputs.push({ fileName: fn, code: contents, writeByteOrderMark: writeByteOrderMark }), options.target, useCaseSensitiveFileNames, currentDirectory, options.newLine); - var program = ts.createProgram(programFiles, options, compilerHost); + let program = ts.createProgram(programFiles, options, compilerHost); - var emitResult = program.emit(); + let emitResult = program.emit(); - var errors = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); + let errors = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); this.lastErrors = errors; - var result = new CompilerResult(fileOutputs, errors, program, ts.sys.getCurrentDirectory(), emitResult.sourceMaps); + let result = new CompilerResult(fileOutputs, errors, program, ts.sys.getCurrentDirectory(), emitResult.sourceMaps); onComplete(result, program); // reset what newline means in case the last test changed it @@ -1193,12 +1191,12 @@ module Harness { throw new Error('There were no errors and declFiles generated did not match number of js files generated'); } + let declInputFiles: { unitName: string; content: string }[] = []; + let declOtherFiles: { unitName: string; content: string }[] = []; + let declResult: Harness.Compiler.CompilerResult; + // if the .d.ts is non-empty, confirm it compiles correctly as well if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) { - var declInputFiles: { unitName: string; content: string }[] = []; - var declOtherFiles: { unitName: string; content: string }[] = []; - var declResult: Harness.Compiler.CompilerResult; - ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles)); ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles)); this.compileFiles(declInputFiles, declOtherFiles, function (compileResult) { declResult = compileResult; }, @@ -1212,20 +1210,20 @@ module Harness { dtsFiles.push(file); } else if (isTS(file.unitName)) { - var declFile = findResultCodeFile(file.unitName); + let declFile = findResultCodeFile(file.unitName); if (!findUnit(declFile.fileName, declInputFiles) && !findUnit(declFile.fileName, declOtherFiles)) { dtsFiles.push({ unitName: declFile.fileName, content: declFile.code }); } } function findResultCodeFile(fileName: string) { - var sourceFile = result.program.getSourceFile(fileName); + let sourceFile = result.program.getSourceFile(fileName); assert(sourceFile, "Program has no source file with name '" + fileName + "'"); // Is this file going to be emitted separately - var sourceFileName: string; + let sourceFileName: string; if (ts.isExternalModule(sourceFile) || !options.out) { if (options.outDir) { - var sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, result.currentDirectoryForProgram); + let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, result.currentDirectoryForProgram); sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), ""); sourceFileName = ts.combinePaths(options.outDir, sourceFilePath); } @@ -1238,7 +1236,7 @@ module Harness { sourceFileName = options.out; } - var dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts"; + let dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts"; return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined); } @@ -1251,7 +1249,7 @@ module Harness { } function normalizeLineEndings(text: string, lineEnding: string): string { - var normalized = text.replace(/\r\n?/g, '\n'); + let normalized = text.replace(/\r\n?/g, '\n'); if (lineEnding !== '\n') { normalized = normalized.replace(/\n/g, lineEnding); } @@ -1260,10 +1258,10 @@ module Harness { export function minimalDiagnosticsToString(diagnostics: ts.Diagnostic[]) { // This is basically copied from tsc.ts's reportError to replicate what tsc does - var errorOutput = ""; + let errorOutput = ""; ts.forEach(diagnostics, diagnostic => { if (diagnostic.file) { - var lineAndCharacter = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); + let lineAndCharacter = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); errorOutput += diagnostic.file.fileName + "(" + (lineAndCharacter.line + 1) + "," + (lineAndCharacter.character + 1) + "): "; } @@ -1275,14 +1273,14 @@ module Harness { export function getErrorBaseline(inputFiles: { unitName: string; content: string }[], diagnostics: ts.Diagnostic[]) { diagnostics.sort(ts.compareDiagnostics); - var outputLines: string[] = []; + let outputLines: string[] = []; // Count up all the errors we find so we don't miss any - var totalErrorsReported = 0; + let totalErrorsReported = 0; function outputErrorText(error: ts.Diagnostic) { - var message = ts.flattenDiagnosticMessageText(error.messageText, ts.sys.newLine); + let message = ts.flattenDiagnosticMessageText(error.messageText, ts.sys.newLine); - var errLines = RunnerBase.removeFullPaths(message) + let errLines = RunnerBase.removeFullPaths(message) .split('\n') .map(s => s.length > 0 && s.charAt(s.length - 1) === '\r' ? s.substr(0, s.length - 1) : s) .filter(s => s.length > 0) @@ -1293,14 +1291,14 @@ module Harness { } // Report global errors - var globalErrors = diagnostics.filter(err => !err.file); + let globalErrors = diagnostics.filter(err => !err.file); globalErrors.forEach(outputErrorText); // 'merge' the lines of each input file with any errors associated with it inputFiles.filter(f => f.content !== undefined).forEach(inputFile => { // Filter down to the errors in the file - var fileErrors = diagnostics.filter(e => { - var errFn = e.file; + let fileErrors = diagnostics.filter(e => { + let errFn = e.file; return errFn && errFn.fileName === inputFile.unitName; }); @@ -1309,13 +1307,13 @@ module Harness { outputLines.push('==== ' + inputFile.unitName + ' (' + fileErrors.length + ' errors) ===='); // Make sure we emit something for every error - var markedErrorCount = 0; + let markedErrorCount = 0; // For each line, emit the line followed by any error squiggles matching this line // Note: IE JS engine incorrectly handles consecutive delimiters here when using RegExp split, so // we have to string-based splitting instead and try to figure out the delimiting chars - var lineStarts = ts.computeLineStarts(inputFile.content); - var lines = inputFile.content.split('\n'); + let lineStarts = ts.computeLineStarts(inputFile.content); + let lines = inputFile.content.split('\n'); if (lines.length === 1) { lines = lines[0].split("\r"); } @@ -1325,8 +1323,8 @@ module Harness { line = line.substr(0, line.length - 1); } - var thisLineStart = lineStarts[lineIndex]; - var nextLineStart: number; + let thisLineStart = lineStarts[lineIndex]; + let nextLineStart: number; // On the last line of the file, fake the next line start number so that we handle errors on the last character of the file correctly if (lineIndex === lines.length - 1) { nextLineStart = inputFile.content.length; @@ -1340,11 +1338,11 @@ module Harness { let end = ts.textSpanEnd(err); if ((end >= thisLineStart) && ((err.start < nextLineStart) || (lineIndex === lines.length - 1))) { // How many characters from the start of this line the error starts at (could be positive or negative) - var relativeOffset = err.start - thisLineStart; + let relativeOffset = err.start - thisLineStart; // How many characters of the error are on this line (might be longer than this line in reality) - var length = (end - err.start) - Math.max(0, thisLineStart - err.start); + let length = (end - err.start) - Math.max(0, thisLineStart - err.start); // Calculate the start of the squiggle - var squiggleStart = Math.max(0, relativeOffset); + let squiggleStart = Math.max(0, relativeOffset); // TODO/REVIEW: this doesn't work quite right in the browser if a multi file test has files whose names are just the right length relative to one another outputLines.push(' ' + line.substr(0, squiggleStart).replace(/[^\s]/g, ' ') + new Array(Math.min(length, line.length - squiggleStart) + 1).join('~')); @@ -1364,11 +1362,11 @@ module Harness { assert.equal(markedErrorCount, fileErrors.length, 'count of errors in ' + inputFile.unitName); }); - var numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => { + let numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => { return diagnostic.file && (isLibraryFile(diagnostic.file.fileName) || isBuiltFile(diagnostic.file.fileName)); }); - var numTest262HarnessDiagnostics = ts.countWhere(diagnostics, diagnostic => { + let numTest262HarnessDiagnostics = ts.countWhere(diagnostics, diagnostic => { // Count an error generated from tests262-harness folder.This should only apply for test262 return diagnostic.file && diagnostic.file.fileName.indexOf("test262-harness") >= 0; }); @@ -1385,7 +1383,7 @@ module Harness { outputFiles.sort((a, b) => cleanName(a.fileName).localeCompare(cleanName(b.fileName))); // Emit them - var result = ''; + let result = ''; for (let outputFile of outputFiles) { // Some extra spacing if this isn't the first file if (result.length) { @@ -1401,13 +1399,13 @@ module Harness { return result; function cleanName(fn: string) { - var lastSlash = ts.normalizeSlashes(fn).lastIndexOf('/'); + let lastSlash = ts.normalizeSlashes(fn).lastIndexOf('/'); return fn.substr(lastSlash + 1).toLowerCase(); } } /** The harness' compiler instance used when tests are actually run. Reseting or changing settings of this compiler instance must be done within a test case (i.e., describe/it) */ - var harnessCompiler: HarnessCompiler; + let harnessCompiler: HarnessCompiler; /** Returns the singleton harness compiler instance for generating and running tests. If required a fresh compiler instance will be created, otherwise the existing singleton will be re-used. @@ -1420,8 +1418,6 @@ module Harness { export function compileString(code: string, unitName: string, callback: (result: CompilerResult) => void) { // NEWTODO: Re-implement 'compileString' throw new Error('compileString NYI'); - //var harnessCompiler = Harness.Compiler.getCompiler(Harness.Compiler.CompilerInstance.RunTime); - //harnessCompiler.compileString(code, unitName, callback); } export interface GeneratedFile { @@ -1513,10 +1509,10 @@ module Harness { } // Regex for parsing options in the format "@Alpha: Value of any sort" - var optionRegex = /^[\/]{2}\s*@(\w+)\s*:\s*(\S*)/gm; // multiple matches on multiple lines + let optionRegex = /^[\/]{2}\s*@(\w+)\s*:\s*(\S*)/gm; // multiple matches on multiple lines // List of allowed metadata names - var fileMetadataNames = ["filename", "comments", "declaration", "module", + let fileMetadataNames = ["filename", "comments", "declaration", "module", "nolib", "sourcemap", "target", "out", "outdir", "noemithelpers", "noemitonerror", "noimplicitany", "noresolve", "newline", "normalizenewline", "emitbom", "errortruncation", "usecasesensitivefilenames", "preserveconstenums", @@ -1527,9 +1523,9 @@ module Harness { function extractCompilerSettings(content: string): CompilerSetting[] { - var opts: CompilerSetting[] = []; + let opts: CompilerSetting[] = []; - var match: RegExpExecArray; + let match: RegExpExecArray; while ((match = optionRegex.exec(content)) != null) { opts.push({ flag: match[1], value: match[2] }); } @@ -1539,26 +1535,26 @@ module Harness { /** Given a test file containing // @FileName directives, return an array of named units of code to be added to an existing compiler instance */ export function makeUnitsFromTest(code: string, fileName: string): { settings: CompilerSetting[]; testUnitData: TestUnitData[]; } { - var settings = extractCompilerSettings(code); + let settings = extractCompilerSettings(code); // List of all the subfiles we've parsed out - var testUnitData: TestUnitData[] = []; + let testUnitData: TestUnitData[] = []; - var lines = Utils.splitContentByNewlines(code); + let lines = Utils.splitContentByNewlines(code); // Stuff related to the subfile we're parsing - var currentFileContent: string = null; - var currentFileOptions: any = {}; - var currentFileName: any = null; - var refs: string[] = []; + let currentFileContent: string = null; + let currentFileOptions: any = {}; + let currentFileName: any = null; + let refs: string[] = []; - for (var i = 0; i < lines.length; i++) { - var line = lines[i]; - var testMetaData = optionRegex.exec(line); + for (let i = 0; i < lines.length; i++) { + let line = lines[i]; + let testMetaData = optionRegex.exec(line); if (testMetaData) { // Comment line, check for global/file @options and record them optionRegex.lastIndex = 0; - var metaDataName = testMetaData[1].toLowerCase(); + let metaDataName = testMetaData[1].toLowerCase(); if (metaDataName === "filename") { currentFileOptions[testMetaData[1]] = testMetaData[2]; } else { @@ -1568,8 +1564,7 @@ module Harness { // New metadata statement after having collected some code to go with the previous metadata if (currentFileName) { // Store result file - var newTestFile = - { + let newTestFile = { content: currentFileContent, name: currentFileName, fileOptions: currentFileOptions, @@ -1604,7 +1599,7 @@ module Harness { currentFileName = testUnitData.length > 0 ? currentFileName : Path.getFileName(fileName); // EOF, push whatever remains - var newTestFile2 = { + let newTestFile2 = { content: currentFileContent || '', name: currentFileName, fileOptions: currentFileOptions, @@ -1651,7 +1646,7 @@ module Harness { } } - var fileCache: { [idx: string]: boolean } = {}; + let fileCache: { [idx: string]: boolean } = {}; function generateActual(actualFileName: string, generateContent: () => string): string { // For now this is written using TypeScript, because sys is not available when running old test cases. // But we need to move to sys once we have @@ -1662,7 +1657,7 @@ module Harness { return; } - var parentDirectory = IO.directoryName(dirName); + let parentDirectory = IO.directoryName(dirName); if (parentDirectory != "") { createDirectoryStructure(parentDirectory); } @@ -1678,7 +1673,7 @@ module Harness { IO.deleteFile(actualFileName); } - var actual = generateContent(); + let actual = generateContent(); if (actual === undefined) { throw new Error('The generated content was "undefined". Return "null" if no baselining is required."'); @@ -1701,13 +1696,13 @@ module Harness { return; } - var refFileName = referencePath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder); + let refFileName = referencePath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder); if (actual === null) { actual = ''; } - var expected = ''; + let expected = ''; if (IO.fileExists(refFileName)) { expected = IO.readFile(refFileName); } @@ -1716,10 +1711,10 @@ module Harness { } function writeComparison(expected: string, actual: string, relativeFileName: string, actualFileName: string, descriptionForDescribe: string) { - var encoded_actual = (new Buffer(actual)).toString('utf8') + let encoded_actual = (new Buffer(actual)).toString('utf8'); if (expected != encoded_actual) { // Overwrite & issue error - var errMsg = 'The baseline file ' + relativeFileName + ' has changed'; + let errMsg = 'The baseline file ' + relativeFileName + ' has changed'; throw new Error(errMsg); } } @@ -1731,17 +1726,17 @@ module Harness { runImmediately = false, opts?: BaselineOptions): void { - var actual = undefined; - var actualFileName = localPath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder); + let actual = undefined; + let actualFileName = localPath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder); if (runImmediately) { actual = generateActual(actualFileName, generateContent); - var comparison = compareToBaseline(actual, relativeFileName, opts); + let comparison = compareToBaseline(actual, relativeFileName, opts); writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe); } else { actual = generateActual(actualFileName, generateContent); - var comparison = compareToBaseline(actual, relativeFileName, opts); + let comparison = compareToBaseline(actual, relativeFileName, opts); writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe); } } @@ -1756,11 +1751,11 @@ module Harness { } export function getDefaultLibraryFile(): { unitName: string, content: string } { - var libFile = Harness.userSpecifiedRoot + Harness.libFolder + "/" + "lib.d.ts"; + let libFile = Harness.userSpecifiedRoot + Harness.libFolder + "/" + "lib.d.ts"; return { unitName: libFile, content: IO.readFile(libFile) - } + }; } if (Error) (Error).stackTraceLimit = 1; diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 6cb92df5948..3c543e50566 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -26,9 +26,9 @@ module Harness.LanguageService { public editContent(start: number, end: number, newText: string): void { // Apply edits - var prefix = this.content.substring(0, start); - var middle = newText; - var suffix = this.content.substring(end); + let prefix = this.content.substring(0, start); + let middle = newText; + let suffix = this.content.substring(end); this.setContent(prefix + middle + suffix); // Store edit range + new length of script @@ -48,10 +48,10 @@ module Harness.LanguageService { return ts.unchangedTextChangeRange; } - var initialEditRangeIndex = this.editRanges.length - (this.version - startVersion); - var lastEditRangeIndex = this.editRanges.length - (this.version - endVersion); + let initialEditRangeIndex = this.editRanges.length - (this.version - startVersion); + let lastEditRangeIndex = this.editRanges.length - (this.version - endVersion); - var entries = this.editRanges.slice(initialEditRangeIndex, lastEditRangeIndex); + let entries = this.editRanges.slice(initialEditRangeIndex, lastEditRangeIndex); return ts.collapseTextChangeRangesAcrossMultipleVersions(entries.map(e => e.textChangeRange)); } } @@ -74,7 +74,7 @@ module Harness.LanguageService { } public getChangeRange(oldScript: ts.IScriptSnapshot): ts.TextChangeRange { - var oldShim = oldScript; + let oldShim = oldScript; return this.scriptInfo.getTextChangeRangeBetweenVersions(oldShim.version, this.version); } } @@ -92,9 +92,9 @@ module Harness.LanguageService { } public getChangeRange(oldScript: ts.ScriptSnapshotShim): string { - var oldShim = oldScript; + let oldShim = oldScript; - var range = this.scriptSnapshot.getChangeRange(oldShim.scriptSnapshot); + let range = this.scriptSnapshot.getChangeRange(oldShim.scriptSnapshot); if (range === null) { return null; } @@ -130,8 +130,8 @@ module Harness.LanguageService { } public getFilenames(): string[] { - var fileNames: string[] = []; - ts.forEachKey(this.fileNameToScript,(fileName) => { fileNames.push(fileName); }); + let fileNames: string[] = []; + ts.forEachKey(this.fileNameToScript, (fileName) => { fileNames.push(fileName); }); return fileNames; } @@ -144,7 +144,7 @@ module Harness.LanguageService { } public editScript(fileName: string, start: number, end: number, newText: string) { - var script = this.getScriptInfo(fileName); + let script = this.getScriptInfo(fileName); if (script !== null) { script.editContent(start, end, newText); return; @@ -161,7 +161,7 @@ module Harness.LanguageService { * @param col 0 based index */ public positionToLineAndCharacter(fileName: string, position: number): ts.LineAndCharacter { - var script: ScriptInfo = this.fileNameToScript[fileName]; + let script: ScriptInfo = this.fileNameToScript[fileName]; assert.isNotNull(script); return ts.computeLineAndCharacterOfPosition(script.lineMap, position); @@ -176,11 +176,11 @@ module Harness.LanguageService { getDefaultLibFileName(): string { return ""; } getScriptFileNames(): string[] { return this.getFilenames(); } getScriptSnapshot(fileName: string): ts.IScriptSnapshot { - var script = this.getScriptInfo(fileName); + let script = this.getScriptInfo(fileName); return script ? new ScriptSnapshot(script) : undefined; } getScriptVersion(fileName: string): string { - var script = this.getScriptInfo(fileName); + let script = this.getScriptInfo(fileName); return script ? script.version.toString() : undefined; } @@ -220,7 +220,7 @@ module Harness.LanguageService { getDefaultLibFileName(): string { return this.nativeHost.getDefaultLibFileName(); } getScriptFileNames(): string { return JSON.stringify(this.nativeHost.getScriptFileNames()); } getScriptSnapshot(fileName: string): ts.ScriptSnapshotShim { - var nativeScriptSnapshot = this.nativeHost.getScriptSnapshot(fileName); + let nativeScriptSnapshot = this.nativeHost.getScriptSnapshot(fileName); return nativeScriptSnapshot && new ScriptSnapshotProxy(nativeScriptSnapshot); } getScriptVersion(fileName: string): string { return this.nativeHost.getScriptVersion(fileName); } @@ -242,13 +242,13 @@ module Harness.LanguageService { throw new Error("NYI"); } getClassificationsForLine(text: string, lexState: ts.EndOfLineState, classifyKeywordsInGenerics?: boolean): ts.ClassificationResult { - var result = this.shim.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics).split('\n'); - var entries: ts.ClassificationInfo[] = []; - var i = 0; - var position = 0; + let result = this.shim.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics).split('\n'); + let entries: ts.ClassificationInfo[] = []; + let i = 0; + let position = 0; for (; i < result.length - 1; i += 2) { - var t = entries[i / 2] = { + let t = entries[i / 2] = { length: parseInt(result[i]), classification: parseInt(result[i + 1]) }; @@ -256,7 +256,7 @@ module Harness.LanguageService { assert.isTrue(t.length > 0, "Result length should be greater than 0, got :" + t.length); position += t.length; } - var finalLexState = parseInt(result[result.length - 1]); + let finalLexState = parseInt(result[result.length - 1]); assert.equal(position, text.length, "Expected cumulative length of all entries to match the length of the source. expected: " + text.length + ", but got: " + position); @@ -268,7 +268,7 @@ module Harness.LanguageService { } function unwrapJSONCallResult(result: string): any { - var parsedResult = JSON.parse(result); + let parsedResult = JSON.parse(result); if (parsedResult.error) { throw new Error("Language Service Shim Error: " + JSON.stringify(parsedResult.error)); } @@ -282,7 +282,7 @@ module Harness.LanguageService { constructor(private shim: ts.LanguageServiceShim) { } private unwrappJSONCallResult(result: string): any { - var parsedResult = JSON.parse(result); + let parsedResult = JSON.parse(result); if (parsedResult.error) { throw new Error("Language Service Shim Error: " + JSON.stringify(parsedResult.error)); } @@ -404,16 +404,16 @@ module Harness.LanguageService { getLanguageService(): ts.LanguageService { return new LanguageServiceShimProxy(this.factory.createLanguageServiceShim(this.host)); } getClassifier(): ts.Classifier { return new ClassifierShimProxy(this.factory.createClassifierShim(this.host)); } getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo { - var shimResult: { + let shimResult: { referencedFiles: ts.IFileReference[]; importedFiles: ts.IFileReference[]; isLibFile: boolean; }; - var coreServicesShim = this.factory.createCoreServicesShim(this.host); + let coreServicesShim = this.factory.createCoreServicesShim(this.host); shimResult = unwrapJSONCallResult(coreServicesShim.getPreProcessedFileInfo(fileName, ts.ScriptSnapshot.fromString(fileContents))); - var convertResult: ts.PreProcessedFileInfo = { + let convertResult: ts.PreProcessedFileInfo = { referencedFiles: [], importedFiles: [], isLibFile: shimResult.isLibFile @@ -496,7 +496,7 @@ module Harness.LanguageService { fileName = Harness.Compiler.defaultLibFileName; } - var snapshot = this.host.getScriptSnapshot(fileName); + let snapshot = this.host.getScriptSnapshot(fileName); return snapshot && snapshot.getText(0, snapshot.getLength()); } @@ -574,13 +574,13 @@ module Harness.LanguageService { private client: ts.server.SessionClient; constructor(cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) { // This is the main host that tests use to direct tests - var clientHost = new SessionClientHost(cancellationToken, options); - var client = new ts.server.SessionClient(clientHost); + let clientHost = new SessionClientHost(cancellationToken, options); + let client = new ts.server.SessionClient(clientHost); // This host is just a proxy for the clientHost, it uses the client // host to answer server queries about files on disk - var serverHost = new SessionServerHost(clientHost); - var server = new ts.server.Session(serverHost, Buffer.byteLength, process.hrtime, serverHost); + let serverHost = new SessionServerHost(clientHost); + let server = new ts.server.Session(serverHost, Buffer.byteLength, process.hrtime, serverHost); // Fake the connection between the client and the server serverHost.writeMessage = client.onMessage.bind(client); diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts index 8ba38043e78..0ce567e9563 100644 --- a/src/harness/loggedIO.ts +++ b/src/harness/loggedIO.ts @@ -70,9 +70,9 @@ interface PlaybackControl { } module Playback { - var recordLog: IOLog = undefined; - var replayLog: IOLog = undefined; - var recordLogFileNameBase = ''; + let recordLog: IOLog = undefined; + let replayLog: IOLog = undefined; + let recordLogFileNameBase = ''; interface Memoized { (s: string): T; @@ -80,8 +80,8 @@ module Playback { } function memoize(func: (s: string) => T): Memoized { - var lookup: { [s: string]: T } = {}; - var run: Memoized = >((s: string) => { + let lookup: { [s: string]: T } = {}; + let run: Memoized = >((s: string) => { if (lookup.hasOwnProperty(s)) return lookup[s]; return lookup[s] = func(s); }); @@ -161,10 +161,10 @@ module Playback { } function findResultByFields(logArray: { result?: T }[], expectedFields: {}, defaultValue?: T): T { - var predicate = (entry: { result?: T }) => { + let predicate = (entry: { result?: T }) => { return Object.getOwnPropertyNames(expectedFields).every((name) => (entry)[name] === (expectedFields)[name]); }; - var results = logArray.filter(entry => predicate(entry)); + let results = logArray.filter(entry => predicate(entry)); if (results.length === 0) { if (defaultValue !== undefined) { return defaultValue; @@ -176,17 +176,17 @@ module Playback { } function findResultByPath(wrapper: { resolvePath(s: string): string }, logArray: { path: string; result?: T }[], expectedPath: string, defaultValue?: T): T { - var normalizedName = ts.normalizeSlashes(expectedPath).toLowerCase(); + let normalizedName = ts.normalizeSlashes(expectedPath).toLowerCase(); // Try to find the result through normal fileName - for (var i = 0; i < logArray.length; i++) { + for (let i = 0; i < logArray.length; i++) { if (ts.normalizeSlashes(logArray[i].path).toLowerCase() === normalizedName) { return logArray[i].result; } } // Fallback, try to resolve the target paths as well if (replayLog.pathsResolved.length > 0) { - var normalizedResolvedName = wrapper.resolvePath(expectedPath).toLowerCase(); - for (var i = 0; i < logArray.length; i++) { + let normalizedResolvedName = wrapper.resolvePath(expectedPath).toLowerCase(); + for (let i = 0; i < logArray.length; i++) { if (wrapper.resolvePath(logArray[i].path).toLowerCase() === normalizedResolvedName) { return logArray[i].result; } @@ -200,9 +200,9 @@ module Playback { } } - var pathEquivCache: any = {}; + let pathEquivCache: any = {}; function pathsAreEquivalent(left: string, right: string, wrapper: { resolvePath(s: string): string }) { - var key = left + '-~~-' + right; + let key = left + '-~~-' + right; function areSame(a: string, b: string) { return ts.normalizeSlashes(a).toLowerCase() === ts.normalizeSlashes(b).toLowerCase(); } @@ -219,11 +219,11 @@ module Playback { } function noOpReplay(name: string) { - //console.log("Swallowed write operation during replay: " + name); + // console.log("Swallowed write operation during replay: " + name); } export function wrapSystem(underlying: ts.System): PlaybackSystem { - var wrapper: PlaybackSystem = {}; + let wrapper: PlaybackSystem = {}; initWrapper(wrapper, underlying); wrapper.startReplayFromFile = logFn => { @@ -231,8 +231,8 @@ module Playback { }; wrapper.endRecord = () => { if (recordLog !== undefined) { - var i = 0; - var fn = () => recordLogFileNameBase + i + '.json'; + let i = 0; + let fn = () => recordLogFileNameBase + i + '.json'; while (underlying.fileExists(fn())) i++; underlying.writeFile(fn(), JSON.stringify(recordLog)); recordLog = undefined; @@ -289,8 +289,8 @@ module Playback { wrapper.readFile = recordReplay(wrapper.readFile, underlying)( (path) => { - var result = underlying.readFile(path); - var logEntry = { path: path, codepage: 0, result: { contents: result, codepage: 0 } }; + let result = underlying.readFile(path); + let logEntry = { path: path, codepage: 0, result: { contents: result, codepage: 0 } }; recordLog.filesRead.push(logEntry); return result; }, diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index 5eb0016ff8d..5ea118aacbf 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -46,7 +46,7 @@ interface BatchCompileProjectTestCaseResult extends CompileProjectFilesResult { class ProjectRunner extends RunnerBase { public initializeTests() { if (this.tests.length === 0) { - var testFiles = this.enumerateFiles("tests/cases/project", /\.json$/, { recursive: true }); + let testFiles = this.enumerateFiles("tests/cases/project", /\.json$/, { recursive: true }); testFiles.forEach(fn => { fn = fn.replace(/\\/g, "/"); this.runProjectTestCase(fn); @@ -58,10 +58,11 @@ class ProjectRunner extends RunnerBase { } private runProjectTestCase(testCaseFileName: string) { - var testCase: ProjectRunnerTestCase; + let testCase: ProjectRunnerTestCase; + let testFileText: string = null; try { - var testFileText = ts.sys.readFile(testCaseFileName); + testFileText = ts.sys.readFile(testCaseFileName); } catch (e) { assert(false, "Unable to open testcase file: " + testCaseFileName + ": " + e.message); @@ -73,7 +74,7 @@ class ProjectRunner extends RunnerBase { catch (e) { assert(false, "Testcase: " + testCaseFileName + " does not contain valid json format: " + e.message); } - var testCaseJustName = testCaseFileName.replace(/^.*[\\\/]/, '').replace(/\.json/, ""); + let testCaseJustName = testCaseFileName.replace(/^.*[\\\/]/, '').replace(/\.json/, ""); function moduleNameToString(moduleKind: ts.ModuleKind) { return moduleKind === ts.ModuleKind.AMD @@ -89,7 +90,7 @@ class ProjectRunner extends RunnerBase { } // When test case output goes to tests/baselines/local/projectOutput/testCaseName/moduleKind/ - // We have these two separate locations because when comparing baselines the baseline verifier will delete the existing file + // We have these two separate locations because when comparing baselines the baseline verifier will delete the existing file // so even if it was created by compiler in that location, the file will be deleted by verified before we can read it // so lets keep these two locations separate function getProjectOutputFolder(fileName: string, moduleKind: ts.ModuleKind) { @@ -97,9 +98,9 @@ class ProjectRunner extends RunnerBase { } function cleanProjectUrl(url: string) { - var diskProjectPath = ts.normalizeSlashes(ts.sys.resolvePath(testCase.projectRoot)); - var projectRootUrl = "file:///" + diskProjectPath; - var normalizedProjectRoot = ts.normalizeSlashes(testCase.projectRoot); + let diskProjectPath = ts.normalizeSlashes(ts.sys.resolvePath(testCase.projectRoot)); + let projectRootUrl = "file:///" + diskProjectPath; + let normalizedProjectRoot = ts.normalizeSlashes(testCase.projectRoot); diskProjectPath = diskProjectPath.substr(0, diskProjectPath.lastIndexOf(normalizedProjectRoot)); projectRootUrl = projectRootUrl.substr(0, projectRootUrl.lastIndexOf(normalizedProjectRoot)); if (url && url.length) { @@ -124,21 +125,21 @@ class ProjectRunner extends RunnerBase { return ts.sys.resolvePath(testCase.projectRoot); } - function compileProjectFiles(moduleKind: ts.ModuleKind, getInputFiles: ()=> string[], + function compileProjectFiles(moduleKind: ts.ModuleKind, getInputFiles: () => string[], getSourceFileText: (fileName: string) => string, writeFile: (fileName: string, data: string, writeByteOrderMark: boolean) => void): CompileProjectFilesResult { - var program = ts.createProgram(getInputFiles(), createCompilerOptions(), createCompilerHost()); - var errors = ts.getPreEmitDiagnostics(program); + let program = ts.createProgram(getInputFiles(), createCompilerOptions(), createCompilerHost()); + let errors = ts.getPreEmitDiagnostics(program); - var emitResult = program.emit(); + let emitResult = program.emit(); errors = ts.concatenate(errors, emitResult.diagnostics); - var sourceMapData = emitResult.sourceMaps; + let sourceMapData = emitResult.sourceMaps; // Clean up source map data that will be used in baselining if (sourceMapData) { - for (var i = 0; i < sourceMapData.length; i++) { - for (var j = 0; j < sourceMapData[i].sourceMapSources.length; j++) { + for (let i = 0; i < sourceMapData.length; i++) { + for (let j = 0; j < sourceMapData[i].sourceMapSources.length; j++) { sourceMapData[i].sourceMapSources[j] = cleanProjectUrl(sourceMapData[i].sourceMapSources[j]); } sourceMapData[i].jsSourceMappingURL = cleanProjectUrl(sourceMapData[i].jsSourceMappingURL); @@ -168,12 +169,12 @@ class ProjectRunner extends RunnerBase { } function getSourceFile(fileName: string, languageVersion: ts.ScriptTarget): ts.SourceFile { - var sourceFile: ts.SourceFile = undefined; + let sourceFile: ts.SourceFile = undefined; if (fileName === Harness.Compiler.defaultLibFileName) { sourceFile = languageVersion === ts.ScriptTarget.ES6 ? Harness.Compiler.defaultES6LibSourceFile : Harness.Compiler.defaultLibSourceFile; } else { - var text = getSourceFileText(fileName); + let text = getSourceFileText(fileName); if (text !== undefined) { sourceFile = Harness.Compiler.createSourceFileAndAssertInvariants(fileName, text, languageVersion); } @@ -194,13 +195,13 @@ class ProjectRunner extends RunnerBase { }; } } - + function batchCompilerProjectTestCase(moduleKind: ts.ModuleKind): BatchCompileProjectTestCaseResult{ - var nonSubfolderDiskFiles = 0; + let nonSubfolderDiskFiles = 0; - var outputFiles: BatchCompileProjectTestCaseEmittedFile[] = []; + let outputFiles: BatchCompileProjectTestCaseEmittedFile[] = []; - var projectCompilerResult = compileProjectFiles(moduleKind, () => testCase.inputFiles, getSourceFileText, writeFile); + let projectCompilerResult = compileProjectFiles(moduleKind, () => testCase.inputFiles, getSourceFileText, writeFile); return { moduleKind, program: projectCompilerResult.program, @@ -211,8 +212,9 @@ class ProjectRunner extends RunnerBase { }; function getSourceFileText(fileName: string): string { + let text: string = undefined; try { - var text = ts.sys.readFile(ts.isRootedDiskPath(fileName) + text = ts.sys.readFile(ts.isRootedDiskPath(fileName) ? fileName : ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(fileName)); } @@ -223,14 +225,14 @@ class ProjectRunner extends RunnerBase { } function writeFile(fileName: string, data: string, writeByteOrderMark: boolean) { - var diskFileName = ts.isRootedDiskPath(fileName) + let diskFileName = ts.isRootedDiskPath(fileName) ? fileName : ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(fileName); - var diskRelativeName = ts.getRelativePathToDirectoryOrUrl(testCase.projectRoot, diskFileName, + let diskRelativeName = ts.getRelativePathToDirectoryOrUrl(testCase.projectRoot, diskFileName, getCurrentDirectory(), Harness.Compiler.getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); if (ts.isRootedDiskPath(diskRelativeName) || diskRelativeName.substr(0, 3) === "../") { - // If the generated output file resides in the parent folder or is rooted path, + // If the generated output file resides in the parent folder or is rooted path, // we need to instead create files that can live in the project reference folder // but make sure extension of these files matches with the fileName the compiler asked to write diskRelativeName = "diskFile" + nonSubfolderDiskFiles++ + @@ -240,22 +242,22 @@ class ProjectRunner extends RunnerBase { if (Harness.Compiler.isJS(fileName)) { // Make sure if there is URl we have it cleaned up - var indexOfSourceMapUrl = data.lastIndexOf("//# sourceMappingURL="); + let indexOfSourceMapUrl = data.lastIndexOf("//# sourceMappingURL="); if (indexOfSourceMapUrl !== -1) { data = data.substring(0, indexOfSourceMapUrl + 21) + cleanProjectUrl(data.substring(indexOfSourceMapUrl + 21)); } } else if (Harness.Compiler.isJSMap(fileName)) { // Make sure sources list is cleaned - var sourceMapData = JSON.parse(data); - for (var i = 0; i < sourceMapData.sources.length; i++) { + let sourceMapData = JSON.parse(data); + for (let i = 0; i < sourceMapData.sources.length; i++) { sourceMapData.sources[i] = cleanProjectUrl(sourceMapData.sources[i]); } sourceMapData.sourceRoot = cleanProjectUrl(sourceMapData.sourceRoot); data = JSON.stringify(sourceMapData); } - var outputFilePath = getProjectOutputFolder(diskRelativeName, moduleKind); + let outputFilePath = getProjectOutputFolder(diskRelativeName, moduleKind); // Actual writing of file as in tc.ts function ensureDirectoryStructure(directoryname: string) { if (directoryname) { @@ -273,36 +275,37 @@ class ProjectRunner extends RunnerBase { } function compileCompileDTsFiles(compilerResult: BatchCompileProjectTestCaseResult) { - var allInputFiles: { emittedFileName: string; code: string; }[] = []; - var compilerOptions = compilerResult.program.getCompilerOptions(); + let allInputFiles: { emittedFileName: string; code: string; }[] = []; + let compilerOptions = compilerResult.program.getCompilerOptions(); ts.forEach(compilerResult.program.getSourceFiles(), sourceFile => { if (Harness.Compiler.isDTS(sourceFile.fileName)) { allInputFiles.unshift({ emittedFileName: sourceFile.fileName, code: sourceFile.text }); } else if (ts.shouldEmitToOwnFile(sourceFile, compilerResult.program.getCompilerOptions())) { + let emitOutputFilePathWithoutExtension: string = undefined; if (compilerOptions.outDir) { - var sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, compilerResult.program.getCurrentDirectory()); + let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, compilerResult.program.getCurrentDirectory()); sourceFilePath = sourceFilePath.replace(compilerResult.program.getCommonSourceDirectory(), ""); - var emitOutputFilePathWithoutExtension = ts.removeFileExtension(ts.combinePaths(compilerOptions.outDir, sourceFilePath)); + emitOutputFilePathWithoutExtension = ts.removeFileExtension(ts.combinePaths(compilerOptions.outDir, sourceFilePath)); } else { - var emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.fileName); + emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.fileName); } - var outputDtsFileName = emitOutputFilePathWithoutExtension + ".d.ts"; + let outputDtsFileName = emitOutputFilePathWithoutExtension + ".d.ts"; allInputFiles.unshift(findOutpuDtsFile(outputDtsFileName)); } else { - var outputDtsFileName = ts.removeFileExtension(compilerOptions.out) + ".d.ts"; - var outputDtsFile = findOutpuDtsFile(outputDtsFileName); + let outputDtsFileName = ts.removeFileExtension(compilerOptions.out) + ".d.ts"; + let outputDtsFile = findOutpuDtsFile(outputDtsFileName); if (!ts.contains(allInputFiles, outputDtsFile)) { allInputFiles.unshift(outputDtsFile); } } }); - return compileProjectFiles(compilerResult.moduleKind,getInputFiles, getSourceFileText, writeFile); + return compileProjectFiles(compilerResult.moduleKind, getInputFiles, getSourceFileText, writeFile); function findOutpuDtsFile(fileName: string) { return ts.forEach(compilerResult.outputFiles, outputFile => outputFile.emittedFileName === fileName ? outputFile : undefined); @@ -319,7 +322,7 @@ class ProjectRunner extends RunnerBase { } function getErrorsBaseline(compilerResult: CompileProjectFilesResult) { - var inputFiles = ts.map(ts.filter(compilerResult.program.getSourceFiles(), + let inputFiles = ts.map(ts.filter(compilerResult.program.getSourceFiles(), sourceFile => sourceFile.fileName !== "lib.d.ts"), sourceFile => { return { unitName: sourceFile.fileName, content: sourceFile.text }; @@ -328,110 +331,112 @@ class ProjectRunner extends RunnerBase { return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors); } - var name = 'Compiling project for ' + testCase.scenario + ': testcase ' + testCaseFileName; + let name = 'Compiling project for ' + testCase.scenario + ': testcase ' + testCaseFileName; - describe(name, () => { - function verifyCompilerResults(moduleKind: ts.ModuleKind) { - function getCompilerResolutionInfo() { - var resolutionInfo: ProjectRunnerTestCaseResolutionInfo = { - scenario: testCase.scenario, - projectRoot: testCase.projectRoot, - inputFiles: testCase.inputFiles, - out: testCase.out, - outDir: testCase.outDir, - sourceMap: testCase.sourceMap, - mapRoot: testCase.mapRoot, - resolveMapRoot: testCase.resolveMapRoot, - sourceRoot: testCase.sourceRoot, - resolveSourceRoot: testCase.resolveSourceRoot, - declaration: testCase.declaration, - baselineCheck: testCase.baselineCheck, - runTest: testCase.runTest, - bug: testCase.bug, - rootDir: testCase.rootDir, - resolvedInputFiles: ts.map(compilerResult.program.getSourceFiles(), inputFile => inputFile.fileName), - emittedFiles: ts.map(compilerResult.outputFiles, outputFile => outputFile.emittedFileName) - }; + describe('Projects tests', () => { + describe(name, () => { + function verifyCompilerResults(moduleKind: ts.ModuleKind) { + let compilerResult: BatchCompileProjectTestCaseResult; - return resolutionInfo; - } + function getCompilerResolutionInfo() { + let resolutionInfo: ProjectRunnerTestCaseResolutionInfo = { + scenario: testCase.scenario, + projectRoot: testCase.projectRoot, + inputFiles: testCase.inputFiles, + out: testCase.out, + outDir: testCase.outDir, + sourceMap: testCase.sourceMap, + mapRoot: testCase.mapRoot, + resolveMapRoot: testCase.resolveMapRoot, + sourceRoot: testCase.sourceRoot, + resolveSourceRoot: testCase.resolveSourceRoot, + declaration: testCase.declaration, + baselineCheck: testCase.baselineCheck, + runTest: testCase.runTest, + bug: testCase.bug, + rootDir: testCase.rootDir, + resolvedInputFiles: ts.map(compilerResult.program.getSourceFiles(), inputFile => inputFile.fileName), + emittedFiles: ts.map(compilerResult.outputFiles, outputFile => outputFile.emittedFileName) + }; - var compilerResult: BatchCompileProjectTestCaseResult; + return resolutionInfo; + } - it(name + ": " + moduleNameToString(moduleKind) , () => { - // Compile using node - compilerResult = batchCompilerProjectTestCase(moduleKind); - }); - - it('Resolution information of (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { - Harness.Baseline.runBaseline('Resolution information of (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.json', () => { - return JSON.stringify(getCompilerResolutionInfo(), undefined, " "); + it(name + ": " + moduleNameToString(moduleKind) , () => { + // Compile using node + compilerResult = batchCompilerProjectTestCase(moduleKind); }); - }); - - it('Errors for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { - if (compilerResult.errors.length) { - Harness.Baseline.runBaseline('Errors for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.errors.txt', () => { - return getErrorsBaseline(compilerResult); + it('Resolution information of (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { + Harness.Baseline.runBaseline('Resolution information of (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.json', () => { + return JSON.stringify(getCompilerResolutionInfo(), undefined, " "); }); - } - }); + }); - it('Baseline of emitted result (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { - if (testCase.baselineCheck) { - ts.forEach(compilerResult.outputFiles, outputFile => { - - Harness.Baseline.runBaseline('Baseline of emitted result (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + outputFile.fileName, () => { - try { - return ts.sys.readFile(getProjectOutputFolder(outputFile.fileName, compilerResult.moduleKind)); - } - catch (e) { - return undefined; - } - }); - }); - } - }); - - - it('SourceMapRecord for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { - if (compilerResult.sourceMapData) { - Harness.Baseline.runBaseline('SourceMapRecord for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.sourcemap.txt', () => { - return Harness.SourceMapRecoder.getSourceMapRecord(compilerResult.sourceMapData, compilerResult.program, - ts.filter(compilerResult.outputFiles, outputFile => Harness.Compiler.isJS(outputFile.emittedFileName))); - }); - } - }); - - // Verify that all the generated .d.ts files compile - - it('Errors in generated Dts files for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { - if (!compilerResult.errors.length && testCase.declaration) { - var dTsCompileResult = compileCompileDTsFiles(compilerResult); - if (dTsCompileResult.errors.length) { - Harness.Baseline.runBaseline('Errors in generated Dts files for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.dts.errors.txt', () => { - return getErrorsBaseline(dTsCompileResult); + it('Errors for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { + if (compilerResult.errors.length) { + Harness.Baseline.runBaseline('Errors for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.errors.txt', () => { + return getErrorsBaseline(compilerResult); }); } - } - }); + }); + + + it('Baseline of emitted result (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { + if (testCase.baselineCheck) { + ts.forEach(compilerResult.outputFiles, outputFile => { + + Harness.Baseline.runBaseline('Baseline of emitted result (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + outputFile.fileName, () => { + try { + return ts.sys.readFile(getProjectOutputFolder(outputFile.fileName, compilerResult.moduleKind)); + } + catch (e) { + return undefined; + } + }); + }); + } + }); + + + it('SourceMapRecord for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { + if (compilerResult.sourceMapData) { + Harness.Baseline.runBaseline('SourceMapRecord for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.sourcemap.txt', () => { + return Harness.SourceMapRecoder.getSourceMapRecord(compilerResult.sourceMapData, compilerResult.program, + ts.filter(compilerResult.outputFiles, outputFile => Harness.Compiler.isJS(outputFile.emittedFileName))); + }); + } + }); + + // Verify that all the generated .d.ts files compile + + it('Errors in generated Dts files for (' + moduleNameToString(moduleKind) + '): ' + testCaseFileName, () => { + if (!compilerResult.errors.length && testCase.declaration) { + let dTsCompileResult = compileCompileDTsFiles(compilerResult); + if (dTsCompileResult.errors.length) { + Harness.Baseline.runBaseline('Errors in generated Dts files for (' + moduleNameToString(compilerResult.moduleKind) + '): ' + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + '.dts.errors.txt', () => { + return getErrorsBaseline(dTsCompileResult); + }); + } + } + }); + after(() => { + compilerResult = undefined; + }); + } + + verifyCompilerResults(ts.ModuleKind.CommonJS); + verifyCompilerResults(ts.ModuleKind.AMD); + after(() => { - compilerResult = undefined; + // Mocha holds onto the closure environment of the describe callback even after the test is done. + // Therefore we have to clean out large objects after the test is done. + testCase = undefined; + testFileText = undefined; + testCaseJustName = undefined; }); - } - - verifyCompilerResults(ts.ModuleKind.CommonJS); - verifyCompilerResults(ts.ModuleKind.AMD); - - after(() => { - // Mocha holds onto the closure environment of the describe callback even after the test is done. - // Therefore we have to clean out large objects after the test is done. - testCase = undefined; - testFileText = undefined; - testCaseJustName = undefined; }); }); } -} \ No newline at end of file +} diff --git a/src/harness/runner.ts b/src/harness/runner.ts index 13d93302f18..e4ed604e980 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -1,6 +1,6 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -20,26 +20,26 @@ /// /// +let runners: RunnerBase[] = []; +let iterations: number = 1; + function runTests(runners: RunnerBase[]) { - for (var i = iterations; i > 0; i--) { - for (var j = 0; j < runners.length; j++) { + for (let i = iterations; i > 0; i--) { + for (let j = 0; j < runners.length; j++) { runners[j].initializeTests(); } } } -var runners: RunnerBase[] = []; -var iterations: number = 1; - // users can define tests to run in mytest.config that will override cmd line args, otherwise use cmd line args (test.config), otherwise no options -var mytestconfig = 'mytest.config'; -var testconfig = 'test.config'; -var testConfigFile = +let mytestconfig = 'mytest.config'; +let testconfig = 'test.config'; +let testConfigFile = Harness.IO.fileExists(mytestconfig) ? Harness.IO.readFile(mytestconfig) : (Harness.IO.fileExists(testconfig) ? Harness.IO.readFile(testconfig) : ''); if (testConfigFile !== '') { - var testConfig = JSON.parse(testConfigFile); + let testConfig = JSON.parse(testConfigFile); if (testConfig.light) { Harness.lightMode = true; } @@ -99,7 +99,7 @@ if (runners.length === 0) { runners.push(new FourSlashRunner(FourSlashTestType.Native)); runners.push(new FourSlashRunner(FourSlashTestType.Shims)); runners.push(new FourSlashRunner(FourSlashTestType.Server)); - //runners.push(new GeneratedFourslashRunner()); + // runners.push(new GeneratedFourslashRunner()); } ts.sys.newLine = '\r\n'; diff --git a/src/harness/runnerbase.ts b/src/harness/runnerbase.ts index fa8d9d2c597..66438d938dd 100644 --- a/src/harness/runnerbase.ts +++ b/src/harness/runnerbase.ts @@ -24,17 +24,17 @@ class RunnerBase { /** Replaces instances of full paths with fileNames only */ static removeFullPaths(path: string) { - var fixedPath = path; + let fixedPath = path; // full paths either start with a drive letter or / for *nix, shouldn't have \ in the path at this point - var fullPath = /(\w+:|\/)?([\w+\-\.]|\/)*\.tsx?/g; - var fullPathList = fixedPath.match(fullPath); + let fullPath = /(\w+:|\/)?([\w+\-\.]|\/)*\.tsx?/g; + let fullPathList = fixedPath.match(fullPath); if (fullPathList) { fullPathList.forEach((match: string) => fixedPath = fixedPath.replace(match, Harness.Path.getFileName(match))); } // when running in the browser the 'full path' is the host name, shows up in error baselines - var localHost = /http:\/localhost:\d+/g; + let localHost = /http:\/localhost:\d+/g; fixedPath = fixedPath.replace(localHost, ''); return fixedPath; } diff --git a/src/harness/rwcRunner.ts b/src/harness/rwcRunner.ts index 43a118b6aec..bbe80abc887 100644 --- a/src/harness/rwcRunner.ts +++ b/src/harness/rwcRunner.ts @@ -5,9 +5,9 @@ module RWC { function runWithIOLog(ioLog: IOLog, fn: () => void) { - var oldSys = ts.sys; + let oldSys = ts.sys; - var wrappedSys = Playback.wrapSystem(ts.sys); + let wrappedSys = Playback.wrapSystem(ts.sys); wrappedSys.startReplayFromData(ioLog); ts.sys = wrappedSys; @@ -21,17 +21,17 @@ module RWC { export function runRWCTest(jsonPath: string) { describe("Testing a RWC project: " + jsonPath, () => { - var inputFiles: { unitName: string; content: string; }[] = []; - var otherFiles: { unitName: string; content: string; }[] = []; - var compilerResult: Harness.Compiler.CompilerResult; - var compilerOptions: ts.CompilerOptions; - var baselineOpts: Harness.Baseline.BaselineOptions = { + let inputFiles: { unitName: string; content: string; }[] = []; + let otherFiles: { unitName: string; content: string; }[] = []; + let compilerResult: Harness.Compiler.CompilerResult; + let compilerOptions: ts.CompilerOptions; + let baselineOpts: Harness.Baseline.BaselineOptions = { Subfolder: 'rwc', Baselinefolder: 'internal/baselines' }; - var baseName = /(.*)\/(.*).json/.exec(ts.normalizeSlashes(jsonPath))[2]; - var currentDirectory: string; - var useCustomLibraryFile: boolean; + let baseName = /(.*)\/(.*).json/.exec(ts.normalizeSlashes(jsonPath))[2]; + let currentDirectory: string; + let useCustomLibraryFile: boolean; after(() => { // Mocha holds onto the closure environment of the describe callback even after the test is done. @@ -50,10 +50,10 @@ module RWC { }); it('can compile', () => { - var harnessCompiler = Harness.Compiler.getCompiler(); - var opts: ts.ParsedCommandLine; + let harnessCompiler = Harness.Compiler.getCompiler(); + let opts: ts.ParsedCommandLine; - var ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath)); + let ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath)); currentDirectory = ioLog.currentDirectory; useCustomLibraryFile = ioLog.useCustomLibraryFile; runWithIOLog(ioLog, () => { @@ -77,7 +77,7 @@ module RWC { for (let fileRead of ioLog.filesRead) { // Check if the file is already added into the set of input files. var resolvedPath = ts.normalizeSlashes(ts.sys.resolvePath(fileRead.path)); - var inInputList = ts.forEach(inputFiles, inputFile => inputFile.unitName === resolvedPath); + let inInputList = ts.forEach(inputFiles, inputFile => inputFile.unitName === resolvedPath); if (!Harness.isLibraryFile(fileRead.path)) { if (inInputList) { @@ -117,9 +117,10 @@ module RWC { }); function getHarnessCompilerInputUnit(fileName: string) { - var unitName = ts.normalizeSlashes(ts.sys.resolvePath(fileName)); + let unitName = ts.normalizeSlashes(ts.sys.resolvePath(fileName)); + let content: string = null; try { - var content = ts.sys.readFile(unitName); + content = ts.sys.readFile(unitName); } catch (e) { // Leave content undefined. @@ -155,13 +156,13 @@ module RWC { }, false, baselineOpts); }); - //it('has correct source map record', () => { - // if (compilerOptions.sourceMap) { - // Harness.Baseline.runBaseline('has correct source map record', baseName + '.sourcemap.txt', () => { - // return compilerResult.getSourceMapRecord(); - // }, false, baselineOpts); - // } - //}); + /*it('has correct source map record', () => { + if (compilerOptions.sourceMap) { + Harness.Baseline.runBaseline('has correct source map record', baseName + '.sourcemap.txt', () => { + return compilerResult.getSourceMapRecord(); + }, false, baselineOpts); + } + });*/ it('has the expected errors', () => { Harness.Baseline.runBaseline('has the expected errors', baseName + '.errors.txt', () => { @@ -178,7 +179,7 @@ module RWC { it('has the expected errors in generated declaration files', () => { if (compilerOptions.declaration && !compilerResult.errors.length) { Harness.Baseline.runBaseline('has the expected errors in generated declaration files', baseName + '.dts.errors.txt', () => { - var declFileCompilationResult = Harness.Compiler.getCompiler().compileDeclarationFiles(inputFiles, otherFiles, compilerResult, + let declFileCompilationResult = Harness.Compiler.getCompiler().compileDeclarationFiles(inputFiles, otherFiles, compilerResult, /*settingscallback*/ undefined, compilerOptions, currentDirectory); if (declFileCompilationResult.declResult.errors.length === 0) { return null; @@ -204,8 +205,8 @@ class RWCRunner extends RunnerBase { */ public initializeTests(): void { // Read in and evaluate the test list - var testList = Harness.IO.listFiles(RWCRunner.sourcePath, /.+\.json$/); - for (var i = 0; i < testList.length; i++) { + let testList = Harness.IO.listFiles(RWCRunner.sourcePath, /.+\.json$/); + for (let i = 0; i < testList.length; i++) { this.runTest(testList[i]); } } diff --git a/src/harness/sourceMapRecorder.ts b/src/harness/sourceMapRecorder.ts index ed079774d94..767dd37949f 100644 --- a/src/harness/sourceMapRecorder.ts +++ b/src/harness/sourceMapRecorder.ts @@ -1,6 +1,6 @@ // // Copyright (c) Microsoft Corporation. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at @@ -23,12 +23,12 @@ module Harness.SourceMapRecoder { } module SourceMapDecoder { - var sourceMapMappings: string; - var sourceMapNames: string[]; - var decodingIndex: number; - var prevNameIndex: number; - var decodeOfEncodedMapping: ts.SourceMapSpan; - var errorDecodeOfEncodedMapping: string; + let sourceMapMappings: string; + let sourceMapNames: string[]; + let decodingIndex: number; + let prevNameIndex: number; + let decodeOfEncodedMapping: ts.SourceMapSpan; + let errorDecodeOfEncodedMapping: string; export function initializeSourceMapDecoding(sourceMapData: ts.SourceMapData) { sourceMapMappings = sourceMapData.sourceMapMappings; @@ -82,9 +82,9 @@ module Harness.SourceMapRecoder { return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(sourceMapMappings.charAt(decodingIndex)); } - var moreDigits = true; - var shiftCount = 0; - var value = 0; + let moreDigits = true; + let shiftCount = 0; + let value = 0; for (; moreDigits; decodingIndex++) { if (createErrorIfCondition(decodingIndex >= sourceMapMappings.length, "Error in decoding base64VLQFormatDecode, past the mapping string")) { @@ -92,7 +92,7 @@ module Harness.SourceMapRecoder { } // 6 digit number - var currentByte = base64FormatDecode(); + let currentByte = base64FormatDecode(); // If msb is set, we still have more bits to continue moreDigits = (currentByte & 32) !== 0; @@ -143,7 +143,7 @@ module Harness.SourceMapRecoder { return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping }; } - // 2. Relative sourceIndex + // 2. Relative sourceIndex decodeOfEncodedMapping.sourceIndex += base64VLQFormatDecode(); // Incorrect sourceIndex dont support this map if (createErrorIfCondition(decodeOfEncodedMapping.sourceIndex < 0, "Invalid sourceIndex found")) { @@ -165,7 +165,7 @@ module Harness.SourceMapRecoder { return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping }; } - // 4. Relative sourceColumn 0 based + // 4. Relative sourceColumn 0 based decodeOfEncodedMapping.sourceColumn += base64VLQFormatDecode(); // Incorrect sourceColumn dont support this map if (createErrorIfCondition(decodeOfEncodedMapping.sourceColumn < 1, "Invalid sourceLine found")) { @@ -203,19 +203,19 @@ module Harness.SourceMapRecoder { } module SourceMapSpanWriter { - var sourceMapRecoder: Compiler.WriterAggregator; - var sourceMapSources: string[]; - var sourceMapNames: string[]; + let sourceMapRecoder: Compiler.WriterAggregator; + let sourceMapSources: string[]; + let sourceMapNames: string[]; - var jsFile: Compiler.GeneratedFile; - var jsLineMap: number[]; - var tsCode: string; - var tsLineMap: number[]; + let jsFile: Compiler.GeneratedFile; + let jsLineMap: number[]; + let tsCode: string; + let tsLineMap: number[]; - var spansOnSingleLine: SourceMapSpanWithDecodeErrors[]; - var prevWrittenSourcePos: number; - var prevWrittenJsLine: number; - var spanMarkerContinues: boolean; + let spansOnSingleLine: SourceMapSpanWithDecodeErrors[]; + let prevWrittenSourcePos: number; + let prevWrittenJsLine: number; + let spanMarkerContinues: boolean; export function intializeSourceMapSpanWriter(sourceMapRecordWriter: Compiler.WriterAggregator, sourceMapData: ts.SourceMapData, currentJsFile: Compiler.GeneratedFile) { sourceMapRecoder = sourceMapRecordWriter; @@ -244,7 +244,7 @@ module Harness.SourceMapRecoder { } function getSourceMapSpanString(mapEntry: ts.SourceMapSpan, getAbsentNameIndex?: boolean) { - var mapString = "Emitted(" + mapEntry.emittedLine + ", " + mapEntry.emittedColumn + ") Source(" + mapEntry.sourceLine + ", " + mapEntry.sourceColumn + ") + SourceIndex(" + mapEntry.sourceIndex + ")"; + let mapString = "Emitted(" + mapEntry.emittedLine + ", " + mapEntry.emittedColumn + ") Source(" + mapEntry.sourceLine + ", " + mapEntry.sourceColumn + ") + SourceIndex(" + mapEntry.sourceIndex + ")"; if (mapEntry.nameIndex >= 0 && mapEntry.nameIndex < sourceMapNames.length) { mapString += " name (" + sourceMapNames[mapEntry.nameIndex] + ")"; } @@ -259,8 +259,8 @@ module Harness.SourceMapRecoder { export function recordSourceMapSpan(sourceMapSpan: ts.SourceMapSpan) { // verify the decoded span is same as the new span - var decodeResult = SourceMapDecoder.decodeNextEncodedSourceMapSpan(); - var decodedErrors: string[]; + let decodeResult = SourceMapDecoder.decodeNextEncodedSourceMapSpan(); + let decodedErrors: string[]; if (decodeResult.error || decodeResult.sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine || decodeResult.sourceMapSpan.emittedColumn !== sourceMapSpan.emittedColumn @@ -278,7 +278,7 @@ module Harness.SourceMapRecoder { } if (spansOnSingleLine.length && spansOnSingleLine[0].sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine) { - // On different line from the one that we have been recording till now, + // On different line from the one that we have been recording till now, writeRecordedSpans(); spansOnSingleLine = [{ sourceMapSpan: sourceMapSpan, decodeErrors: decodedErrors }]; } @@ -317,8 +317,8 @@ module Harness.SourceMapRecoder { } function getTextOfLine(line: number, lineMap: number[], code: string) { - var startPos = lineMap[line]; - var endPos = lineMap[line + 1]; + let startPos = lineMap[line]; + let endPos = lineMap[line + 1]; return code.substring(startPos, endPos); } @@ -329,14 +329,16 @@ module Harness.SourceMapRecoder { } function writeRecordedSpans() { + let markerIds: string[] = []; + function getMarkerId(markerIndex: number) { - var markerId = ""; + let markerId = ""; if (spanMarkerContinues) { assert.isTrue(markerIndex === 0); markerId = "1->"; } else { - var markerId = "" + (markerIndex + 1); + markerId = "" + (markerIndex + 1); if (markerId.length < 2) { markerId = markerId + " "; } @@ -345,10 +347,10 @@ module Harness.SourceMapRecoder { return markerId; } - var prevEmittedCol: number; + let prevEmittedCol: number; function iterateSpans(fn: (currentSpan: SourceMapSpanWithDecodeErrors, index: number) => void) { prevEmittedCol = 1; - for (var i = 0; i < spansOnSingleLine.length; i++) { + for (let i = 0; i < spansOnSingleLine.length; i++) { fn(spansOnSingleLine[i], i); prevEmittedCol = spansOnSingleLine[i].sourceMapSpan.emittedColumn; } @@ -356,18 +358,18 @@ module Harness.SourceMapRecoder { function writeSourceMapIndent(indentLength: number, indentPrefix: string) { sourceMapRecoder.Write(indentPrefix); - for (var i = 1; i < indentLength; i++) { + for (let i = 1; i < indentLength; i++) { sourceMapRecoder.Write(" "); } } function writeSourceMapMarker(currentSpan: SourceMapSpanWithDecodeErrors, index: number, endColumn = currentSpan.sourceMapSpan.emittedColumn, endContinues?: boolean) { - var markerId = getMarkerId(index); + let markerId = getMarkerId(index); markerIds.push(markerId); writeSourceMapIndent(prevEmittedCol, markerId); - for (var i = prevEmittedCol; i < endColumn; i++) { + for (let i = prevEmittedCol; i < endColumn; i++) { sourceMapRecoder.Write("^"); } if (endContinues) { @@ -378,8 +380,8 @@ module Harness.SourceMapRecoder { } function writeSourceMapSourceText(currentSpan: SourceMapSpanWithDecodeErrors, index: number) { - var sourcePos = tsLineMap[currentSpan.sourceMapSpan.sourceLine - 1] + (currentSpan.sourceMapSpan.sourceColumn - 1); - var sourceText = ""; + let sourcePos = tsLineMap[currentSpan.sourceMapSpan.sourceLine - 1] + (currentSpan.sourceMapSpan.sourceColumn - 1); + let sourceText = ""; if (prevWrittenSourcePos < sourcePos) { // Position that goes forward, get text sourceText = tsCode.substring(prevWrittenSourcePos, sourcePos); @@ -387,14 +389,14 @@ module Harness.SourceMapRecoder { if (currentSpan.decodeErrors) { // If there are decode errors, write - for (var i = 0; i < currentSpan.decodeErrors.length; i++) { + for (let i = 0; i < currentSpan.decodeErrors.length; i++) { writeSourceMapIndent(prevEmittedCol, markerIds[index]); sourceMapRecoder.WriteLine(currentSpan.decodeErrors[i]); } } - var tsCodeLineMap = ts.computeLineStarts(sourceText); - for (var i = 0; i < tsCodeLineMap.length; i++) { + let tsCodeLineMap = ts.computeLineStarts(sourceText); + for (let i = 0; i < tsCodeLineMap.length; i++) { writeSourceMapIndent(prevEmittedCol, i === 0 ? markerIds[index] : " >"); sourceMapRecoder.Write(getTextOfLine(i, tsCodeLineMap, sourceText)); if (i === tsCodeLineMap.length - 1) { @@ -410,16 +412,15 @@ module Harness.SourceMapRecoder { } if (spansOnSingleLine.length) { - var currentJsLine = spansOnSingleLine[0].sourceMapSpan.emittedLine; + let currentJsLine = spansOnSingleLine[0].sourceMapSpan.emittedLine; // Write js line writeJsFileLines(currentJsLine); // Emit markers - var markerIds: string[] = []; iterateSpans(writeSourceMapMarker); - var jsFileText = getTextOfLine(currentJsLine, jsLineMap, jsFile.code); + let 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); @@ -437,16 +438,16 @@ module Harness.SourceMapRecoder { } export function getSourceMapRecord(sourceMapDataList: ts.SourceMapData[], program: ts.Program, jsFiles: Compiler.GeneratedFile[]) { - var sourceMapRecoder = new Compiler.WriterAggregator(); + let sourceMapRecoder = new Compiler.WriterAggregator(); - for (var i = 0; i < sourceMapDataList.length; i++) { - var sourceMapData = sourceMapDataList[i]; - var prevSourceFile: ts.SourceFile = null; + for (let i = 0; i < sourceMapDataList.length; i++) { + let sourceMapData = sourceMapDataList[i]; + let prevSourceFile: ts.SourceFile = null; SourceMapSpanWriter.intializeSourceMapSpanWriter(sourceMapRecoder, sourceMapData, jsFiles[i]); - for (var j = 0; j < sourceMapData.sourceMapDecodedMappings.length; j++) { - var decodedSourceMapping = sourceMapData.sourceMapDecodedMappings[j]; - var currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex]); + for (let j = 0; j < sourceMapData.sourceMapDecodedMappings.length; j++) { + let decodedSourceMapping = sourceMapData.sourceMapDecodedMappings[j]; + let currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex]); if (currentSourceFile !== prevSourceFile) { SourceMapSpanWriter.recordNewSourceFileSpan(decodedSourceMapping, currentSourceFile.text); prevSourceFile = currentSourceFile; @@ -455,7 +456,7 @@ module Harness.SourceMapRecoder { SourceMapSpanWriter.recordSourceMapSpan(decodedSourceMapping); } } - SourceMapSpanWriter.close();// If the last spans werent emitted, emit them + SourceMapSpanWriter.close(); // If the last spans werent emitted, emit them } sourceMapRecoder.Close(); return sourceMapRecoder.lines.join('\r\n'); diff --git a/src/harness/test262Runner.ts b/src/harness/test262Runner.ts index 5f8250c5e23..e34e58844ac 100644 --- a/src/harness/test262Runner.ts +++ b/src/harness/test262Runner.ts @@ -27,7 +27,7 @@ class Test262BaselineRunner extends RunnerBase { describe('test262 test for ' + filePath, () => { // Mocha holds onto the closure environment of the describe callback even after the test is done. // Everything declared here should be cleared out in the "after" callback. - var testState: { + let testState: { filename: string; compilerResult: Harness.Compiler.CompilerResult; inputFiles: { unitName: string; content: string }[]; @@ -35,11 +35,11 @@ class Test262BaselineRunner extends RunnerBase { }; before(() => { - var content = Harness.IO.readFile(filePath); - var testFilename = ts.removeFileExtension(filePath).replace(/\//g, '_') + ".test"; - var testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, testFilename); + let content = Harness.IO.readFile(filePath); + let testFilename = ts.removeFileExtension(filePath).replace(/\//g, '_') + ".test"; + let testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, testFilename); - var inputFiles = testCaseContent.testUnitData.map(unit => { + let inputFiles = testCaseContent.testUnitData.map(unit => { return { unitName: Test262BaselineRunner.getTestFilePath(unit.name), content: unit.content }; }); @@ -63,14 +63,14 @@ class Test262BaselineRunner extends RunnerBase { it('has the expected emitted code', () => { Harness.Baseline.runBaseline('has the expected emitted code', testState.filename + '.output.js', () => { - var files = testState.compilerResult.files.filter(f=> f.fileName !== Test262BaselineRunner.helpersFilePath); + let files = testState.compilerResult.files.filter(f => f.fileName !== Test262BaselineRunner.helpersFilePath); return Harness.Compiler.collateOutputs(files); }, false, Test262BaselineRunner.baselineOptions); }); it('has the expected errors', () => { Harness.Baseline.runBaseline('has the expected errors', testState.filename + '.errors.txt', () => { - var errors = testState.compilerResult.errors; + let errors = testState.compilerResult.errors; if (errors.length === 0) { return null; } @@ -79,14 +79,14 @@ class Test262BaselineRunner extends RunnerBase { }, false, Test262BaselineRunner.baselineOptions); }); - it('satisfies invariants', () => { - var sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename)); + it('satisfies inletiants', () => { + let sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename)); Utils.assertInvariants(sourceFile, /*parent:*/ undefined); }); - it('has the expected AST',() => { - Harness.Baseline.runBaseline('has the expected AST', testState.filename + '.AST.txt',() => { - var sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename)); + it('has the expected AST', () => { + Harness.Baseline.runBaseline('has the expected AST', testState.filename + '.AST.txt', () => { + let sourceFile = testState.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename)); return Utils.sourceFileToJSON(sourceFile); }, false, Test262BaselineRunner.baselineOptions); }); @@ -96,7 +96,7 @@ class Test262BaselineRunner extends RunnerBase { public initializeTests() { // this will set up a series of describe/it blocks to run between the setup and cleanup phases if (this.tests.length === 0) { - var testFiles = this.enumerateFiles(Test262BaselineRunner.basePath, Test262BaselineRunner.testFileExtensionRegex, { recursive: true }); + let testFiles = this.enumerateFiles(Test262BaselineRunner.basePath, Test262BaselineRunner.testFileExtensionRegex, { recursive: true }); testFiles.forEach(fn => { this.runTest(ts.normalizePath(fn)); }); @@ -105,4 +105,4 @@ class Test262BaselineRunner extends RunnerBase { this.tests.forEach(test => this.runTest(test)); } } -} \ No newline at end of file +} diff --git a/src/harness/typeWriter.ts b/src/harness/typeWriter.ts index b68e606c79d..27cb3574473 100644 --- a/src/harness/typeWriter.ts +++ b/src/harness/typeWriter.ts @@ -13,7 +13,7 @@ class TypeWriterWalker { private checker: ts.TypeChecker; constructor(private program: ts.Program, fullTypeCheck: boolean) { - // Consider getting both the diagnostics checker and the non-diagnostics checker to verify + // Consider getting both the diagnostics checker and the non-diagnostics checker to verify // they are consistent. this.checker = fullTypeCheck ? program.getDiagnosticsProducingTypeChecker() @@ -21,7 +21,7 @@ class TypeWriterWalker { } public getTypeAndSymbols(fileName: string): TypeWriterResult[] { - var sourceFile = this.program.getSourceFile(fileName); + let sourceFile = this.program.getSourceFile(fileName); this.currentSourceFile = sourceFile; this.results = []; this.visitNode(sourceFile); @@ -37,19 +37,19 @@ class TypeWriterWalker { } private logTypeAndSymbol(node: ts.Node): void { - var actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos); - var lineAndCharacter = this.currentSourceFile.getLineAndCharacterOfPosition(actualPos); - var sourceText = ts.getTextOfNodeFromSourceText(this.currentSourceFile.text, node); + let actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos); + let lineAndCharacter = this.currentSourceFile.getLineAndCharacterOfPosition(actualPos); + let sourceText = ts.getTextOfNodeFromSourceText(this.currentSourceFile.text, node); // Workaround to ensure we output 'C' instead of 'typeof C' for base class expressions - // var type = this.checker.getTypeAtLocation(node); - var type = node.parent && ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent) && this.checker.getTypeAtLocation(node.parent) || this.checker.getTypeAtLocation(node); + // let type = this.checker.getTypeAtLocation(node); + let type = node.parent && ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent) && this.checker.getTypeAtLocation(node.parent) || this.checker.getTypeAtLocation(node); ts.Debug.assert(type !== undefined, "type doesn't exist"); - var symbol = this.checker.getSymbolAtLocation(node); + let symbol = this.checker.getSymbolAtLocation(node); - var typeString = this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation); - var symbolString: string; + let typeString = this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation); + let symbolString: string; if (symbol) { symbolString = "Symbol(" + this.checker.symbolToString(symbol, node.parent); if (symbol.declarations) { @@ -57,7 +57,7 @@ class TypeWriterWalker { symbolString += ", "; let declSourceFile = declaration.getSourceFile(); let declLineAndCharacter = declSourceFile.getLineAndCharacterOfPosition(declaration.pos); - symbolString += `Decl(${ ts.getBaseFileName(declSourceFile.fileName) }, ${ declLineAndCharacter.line }, ${ declLineAndCharacter.character })` + symbolString += `Decl(${ ts.getBaseFileName(declSourceFile.fileName) }, ${ declLineAndCharacter.line }, ${ declLineAndCharacter.character })`; } } symbolString += ")"; diff --git a/src/server/session.ts b/src/server/session.ts index 3eea095d9d5..ff6f97139cb 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -887,53 +887,53 @@ namespace ts.server { private handlers : Map<(request: protocol.Request) => {response?: any, responseRequired?: boolean}> = { [CommandNames.Exit]: () => { this.exit(); - return {}; + return { responseRequired: false}; }, [CommandNames.Definition]: (request: protocol.Request) => { var defArgs = request.arguments; - return {response: this.getDefinition(defArgs.line, defArgs.offset, defArgs.file)}; + return {response: this.getDefinition(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true}; }, [CommandNames.TypeDefinition]: (request: protocol.Request) => { var defArgs = request.arguments; - return {response: this.getTypeDefinition(defArgs.line, defArgs.offset, defArgs.file)}; + return {response: this.getTypeDefinition(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true}; }, [CommandNames.References]: (request: protocol.Request) => { var defArgs = request.arguments; - return {response: this.getReferences(defArgs.line, defArgs.offset, defArgs.file)}; + return {response: this.getReferences(defArgs.line, defArgs.offset, defArgs.file), responseRequired: true}; }, [CommandNames.Rename]: (request: protocol.Request) => { var renameArgs = request.arguments; - return {response: this.getRenameLocations(renameArgs.line, renameArgs.offset, renameArgs.file, renameArgs.findInComments, renameArgs.findInStrings)} + return {response: this.getRenameLocations(renameArgs.line, renameArgs.offset, renameArgs.file, renameArgs.findInComments, renameArgs.findInStrings), responseRequired: true} }, [CommandNames.Open]: (request: protocol.Request) => { var openArgs = request.arguments; this.openClientFile(openArgs.file); - return {} + return {responseRequired: false} }, [CommandNames.Quickinfo]: (request: protocol.Request) => { var quickinfoArgs = request.arguments; - return {response: this.getQuickInfo(quickinfoArgs.line, quickinfoArgs.offset, quickinfoArgs.file)}; + return {response: this.getQuickInfo(quickinfoArgs.line, quickinfoArgs.offset, quickinfoArgs.file), responseRequired: true}; }, [CommandNames.Format]: (request: protocol.Request) => { var formatArgs = request.arguments; - return {response: this.getFormattingEditsForRange(formatArgs.line, formatArgs.offset, formatArgs.endLine, formatArgs.endOffset, formatArgs.file)}; + return {response: this.getFormattingEditsForRange(formatArgs.line, formatArgs.offset, formatArgs.endLine, formatArgs.endOffset, formatArgs.file), responseRequired: true}; }, [CommandNames.Formatonkey]: (request: protocol.Request) => { var formatOnKeyArgs = request.arguments; - return {response: this.getFormattingEditsAfterKeystroke(formatOnKeyArgs.line, formatOnKeyArgs.offset, formatOnKeyArgs.key, formatOnKeyArgs.file)}; + return {response: this.getFormattingEditsAfterKeystroke(formatOnKeyArgs.line, formatOnKeyArgs.offset, formatOnKeyArgs.key, formatOnKeyArgs.file), responseRequired: true}; }, [CommandNames.Completions]: (request: protocol.Request) => { var completionsArgs = request.arguments; - return {response: this.getCompletions(completionsArgs.line, completionsArgs.offset, completionsArgs.prefix, completionsArgs.file)} + return {response: this.getCompletions(completionsArgs.line, completionsArgs.offset, completionsArgs.prefix, completionsArgs.file), responseRequired: true} }, [CommandNames.CompletionDetails]: (request: protocol.Request) => { var completionDetailsArgs = request.arguments; return {response: this.getCompletionEntryDetails(completionDetailsArgs.line,completionDetailsArgs.offset, - completionDetailsArgs.entryNames,completionDetailsArgs.file)} + completionDetailsArgs.entryNames,completionDetailsArgs.file), responseRequired: true} }, [CommandNames.SignatureHelp]: (request: protocol.Request) => { var signatureHelpArgs = request.arguments; - return {response: this.getSignatureHelpItems(signatureHelpArgs.line, signatureHelpArgs.offset, signatureHelpArgs.file)} + return {response: this.getSignatureHelpItems(signatureHelpArgs.line, signatureHelpArgs.offset, signatureHelpArgs.file), responseRequired: true} }, [CommandNames.Geterr]: (request: protocol.Request) => { var geterrArgs = request.arguments; @@ -972,23 +972,23 @@ namespace ts.server { }, [CommandNames.Navto]: (request: protocol.Request) => { var navtoArgs = request.arguments; - return {response: this.getNavigateToItems(navtoArgs.searchValue, navtoArgs.file, navtoArgs.maxResultCount)}; + return {response: this.getNavigateToItems(navtoArgs.searchValue, navtoArgs.file, navtoArgs.maxResultCount), responseRequired: true}; }, [CommandNames.Brace]: (request: protocol.Request) => { var braceArguments = request.arguments; - return {response: this.getBraceMatching(braceArguments.line, braceArguments.offset, braceArguments.file)}; + return {response: this.getBraceMatching(braceArguments.line, braceArguments.offset, braceArguments.file), responseRequired: true}; }, [CommandNames.NavBar]: (request: protocol.Request) => { var navBarArgs = request.arguments; - return {response: this.getNavigationBarItems(navBarArgs.file)}; + return {response: this.getNavigationBarItems(navBarArgs.file), responseRequired: true}; }, [CommandNames.Occurrences]: (request: protocol.Request) => { var { line, offset, file: fileName } = request.arguments; - return {response: this.getOccurrences(line, offset, fileName)}; + return {response: this.getOccurrences(line, offset, fileName), responseRequired: true}; }, [CommandNames.ProjectInfo]: (request: protocol.Request) => { var { file, needFileNameList } = request.arguments; - return {response: this.getProjectInfo(file, needFileNameList)}; + return {response: this.getProjectInfo(file, needFileNameList), responseRequired: true}; }, }; addProtocolHandler(command: string, handler: (request: protocol.Request) => {response?: any, responseRequired: boolean}) { diff --git a/src/services/services.ts b/src/services/services.ts index c85c10dc411..c2432816f24 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -91,6 +91,9 @@ namespace ts { * not happen and the entire document will be re - parsed. */ getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange; + + /** Releases all resources held by this script snapshot */ + dispose?(): void; } export module ScriptSnapshot { @@ -1863,6 +1866,16 @@ namespace ts { // after incremental parsing nameTable might not be up-to-date // drop it so it can be lazily recreated later newSourceFile.nameTable = undefined; + + // dispose all resources held by old script snapshot + if (sourceFile !== newSourceFile && sourceFile.scriptSnapshot) { + if (sourceFile.scriptSnapshot.dispose) { + sourceFile.scriptSnapshot.dispose(); + } + + sourceFile.scriptSnapshot = undefined; + } + return newSourceFile; } } @@ -3015,17 +3028,17 @@ namespace ts { function tryGetGlobalSymbols(): boolean { let objectLikeContainer: ObjectLiteralExpression | BindingPattern; - let importClause: ImportClause; + let namedImportsOrExports: NamedImportsOrExports; let jsxContainer: JsxOpeningLikeElement; if (objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken)) { return tryGetObjectLikeCompletionSymbols(objectLikeContainer); } - if (importClause = getAncestor(contextToken, SyntaxKind.ImportClause)) { + if (namedImportsOrExports = tryGetNamedImportsOrExportsForCompletion(contextToken)) { // cursor is in an import clause // try to show exported member for imported module - return tryGetImportClauseCompletionSymbols(importClause); + return tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports); } if (jsxContainer = tryGetContainingJsxElement(contextToken)) { @@ -3035,7 +3048,7 @@ namespace ts { attrsType = typeChecker.getJsxElementAttributesType(jsxContainer); if (attrsType) { - symbols = filterJsxAttributes((jsxContainer).attributes, typeChecker.getPropertiesOfType(attrsType)); + symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), (jsxContainer).attributes); isMemberCompletion = true; isNewIdentifierLocation = false; return true; @@ -3104,24 +3117,12 @@ namespace ts { function isCompletionListBlocker(contextToken: Node): boolean { let start = new Date().getTime(); let result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) || - isIdentifierDefinitionLocation(contextToken) || + isSolelyIdentifierDefinitionLocation(contextToken) || isDotOfNumericLiteral(contextToken); log("getCompletionsAtPosition: isCompletionListBlocker: " + (new Date().getTime() - start)); return result; } - function shouldShowCompletionsInImportsClause(node: Node): boolean { - if (node) { - // import {| - // import {a,| - if (node.kind === SyntaxKind.OpenBraceToken || node.kind === SyntaxKind.CommaToken) { - return node.parent.kind === SyntaxKind.NamedImports; - } - } - - return false; - } - function isNewIdentifierDefinitionLocation(previousToken: Node): boolean { if (previousToken) { let containingNodeKind = previousToken.parent.kind; @@ -3233,8 +3234,19 @@ namespace ts { // We are *only* completing on properties from the type being destructured. isNewIdentifierLocation = false; - typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer); - existingMembers = (objectLikeContainer).elements; + let rootDeclaration = getRootDeclaration(objectLikeContainer.parent); + if (isVariableLike(rootDeclaration)) { + // We don't want to complete using the type acquired by the shape + // of the binding pattern; we are only interested in types acquired + // through type declaration or inference. + if (rootDeclaration.initializer || rootDeclaration.type) { + typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer); + existingMembers = (objectLikeContainer).elements; + } + } + else { + Debug.fail("Root declaration is not variable-like.") + } } else { Debug.fail("Expected object literal or binding pattern, got " + objectLikeContainer.kind); @@ -3253,38 +3265,42 @@ namespace ts { } /** - * Aggregates relevant symbols for completion in import clauses; for instance, + * Aggregates relevant symbols for completion in import clauses and export clauses + * whose declarations have a module specifier; for instance, symbols will be aggregated for * - * import { $ } from "moduleName"; + * import { | } from "moduleName"; + * export { a as foo, | } from "moduleName"; + * + * but not for + * + * export { | }; * * Relevant symbols are stored in the captured 'symbols' variable. * * @returns true if 'symbols' was successfully populated; false otherwise. */ - function tryGetImportClauseCompletionSymbols(importClause: ImportClause): boolean { - // cursor is in import clause - // try to show exported member for imported module - if (shouldShowCompletionsInImportsClause(contextToken)) { - isMemberCompletion = true; - isNewIdentifierLocation = false; + function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports: NamedImportsOrExports): boolean { + let declarationKind = namedImportsOrExports.kind === SyntaxKind.NamedImports ? + SyntaxKind.ImportDeclaration : + SyntaxKind.ExportDeclaration; + let importOrExportDeclaration = getAncestor(namedImportsOrExports, declarationKind); + let moduleSpecifier = importOrExportDeclaration.moduleSpecifier; - let importDeclaration = importClause.parent; - Debug.assert(importDeclaration !== undefined && importDeclaration.kind === SyntaxKind.ImportDeclaration); - - let exports: Symbol[]; - let moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importDeclaration.moduleSpecifier); - if (moduleSpecifierSymbol) { - exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol); - } - - //let exports = typeInfoResolver.getExportsOfImportDeclaration(importDeclaration); - symbols = exports ? filterModuleExports(exports, importDeclaration) : emptyArray; + if (!moduleSpecifier) { + return false; } - else { - isMemberCompletion = false; - isNewIdentifierLocation = true; + + isMemberCompletion = true; + isNewIdentifierLocation = false; + + let exports: Symbol[]; + let moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(importOrExportDeclaration.moduleSpecifier); + if (moduleSpecifierSymbol) { + exports = typeChecker.getExportsOfModule(moduleSpecifierSymbol); } + symbols = exports ? filterNamedImportOrExportCompletionItems(exports, namedImportsOrExports.elements) : emptyArray; + return true; } @@ -3308,6 +3324,26 @@ namespace ts { return undefined; } + /** + * Returns the containing list of named imports or exports of a context token, + * on the condition that one exists and that the context implies completion should be given. + */ + function tryGetNamedImportsOrExportsForCompletion(contextToken: Node): NamedImportsOrExports { + if (contextToken) { + switch (contextToken.kind) { + case SyntaxKind.OpenBraceToken: // import { | + case SyntaxKind.CommaToken: // import { a as 0, | + switch (contextToken.parent.kind) { + case SyntaxKind.NamedImports: + case SyntaxKind.NamedExports: + return contextToken.parent; + } + } + } + + return undefined; + } + function tryGetContainingJsxElement(contextToken: Node): JsxOpeningLikeElement { if (contextToken) { let parent = contextToken.parent; @@ -3355,7 +3391,10 @@ namespace ts { return false; } - function isIdentifierDefinitionLocation(contextToken: Node): boolean { + /** + * @returns true if we are certain that the currently edited location must define a new location; false otherwise. + */ + function isSolelyIdentifierDefinitionLocation(contextToken: Node): boolean { let containingNodeKind = contextToken.parent.kind; switch (contextToken.kind) { case SyntaxKind.CommaToken: @@ -3412,6 +3451,11 @@ namespace ts { case SyntaxKind.ProtectedKeyword: return containingNodeKind === SyntaxKind.Parameter; + case SyntaxKind.AsKeyword: + containingNodeKind === SyntaxKind.ImportSpecifier || + containingNodeKind === SyntaxKind.ExportSpecifier || + containingNodeKind === SyntaxKind.NamespaceImport; + case SyntaxKind.ClassKeyword: case SyntaxKind.EnumKeyword: case SyntaxKind.InterfaceKeyword: @@ -3453,33 +3497,41 @@ namespace ts { return false; } - function filterModuleExports(exports: Symbol[], importDeclaration: ImportDeclaration): Symbol[] { - let exisingImports: Map = {}; + /** + * Filters out completion suggestions for named imports or exports. + * + * @param exportsOfModule The list of symbols which a module exposes. + * @param namedImportsOrExports The list of existing import/export specifiers in the import/export clause. + * + * @returns Symbols to be suggested at an import/export clause, barring those whose named imports/exports + * do not occur at the current position and have not otherwise been typed. + */ + function filterNamedImportOrExportCompletionItems(exportsOfModule: Symbol[], namedImportsOrExports: ImportOrExportSpecifier[]): Symbol[] { + let exisingImportsOrExports: Map = {}; - if (!importDeclaration.importClause) { - return exports; + for (let element of namedImportsOrExports) { + // If this is the current item we are editing right now, do not filter it out + if (element.getStart() <= position && position <= element.getEnd()) { + continue; + } + + let name = element.propertyName || element.name; + exisingImportsOrExports[name.text] = true; } - if (importDeclaration.importClause.namedBindings && - importDeclaration.importClause.namedBindings.kind === SyntaxKind.NamedImports) { - - forEach((importDeclaration.importClause.namedBindings).elements, el => { - // If this is the current item we are editing right now, do not filter it out - if (el.getStart() <= position && position <= el.getEnd()) { - return; - } - - let name = el.propertyName || el.name; - exisingImports[name.text] = true; - }); + if (isEmpty(exisingImportsOrExports)) { + return exportsOfModule; } - if (isEmpty(exisingImports)) { - return exports; - } - return filter(exports, e => !lookUp(exisingImports, e.name)); + return filter(exportsOfModule, e => !lookUp(exisingImportsOrExports, e.name)); } + /** + * Filters out completion suggestions for named imports or exports. + * + * @returns Symbols to be suggested in an object binding pattern or object literal expression, barring those whose declarations + * do not occur at the current position and have not otherwise been typed. + */ function filterObjectMembersList(contextualMemberSymbols: Symbol[], existingMembers: Declaration[]): Symbol[] { if (!existingMembers || existingMembers.length === 0) { return contextualMemberSymbols; @@ -3514,17 +3566,16 @@ namespace ts { existingMemberNames[existingName] = true; } - let filteredMembers: Symbol[] = []; - forEach(contextualMemberSymbols, s => { - if (!existingMemberNames[s.name]) { - filteredMembers.push(s); - } - }); - - return filteredMembers; + return filter(contextualMemberSymbols, m => !lookUp(existingMemberNames, m.name)); } - function filterJsxAttributes(attributes: NodeArray, symbols: Symbol[]): Symbol[] { + /** + * Filters out completion suggestions from 'symbols' according to existing JSX attributes. + * + * @returns Symbols to be suggested in a JSX element, barring those whose attributes + * do not occur at the current position and have not otherwise been typed. + */ + function filterJsxAttributes(symbols: Symbol[], attributes: NodeArray): Symbol[] { let seenNames: Map = {}; for (let attr of attributes) { // If this is the current item we are editing right now, do not filter it out @@ -3536,13 +3587,8 @@ namespace ts { seenNames[(attr).name.text] = true; } } - let result: Symbol[] = []; - for (let sym of symbols) { - if (!seenNames[sym.name]) { - result.push(sym); - } - } - return result; + + return filter(symbols, a => !lookUp(seenNames, a.name)); } } @@ -4682,12 +4728,13 @@ namespace ts { // Make sure we only highlight the keyword when it makes sense to do so. if (isAccessibilityModifier(modifier)) { if (!(container.kind === SyntaxKind.ClassDeclaration || + container.kind === SyntaxKind.ClassExpression || (declaration.kind === SyntaxKind.Parameter && hasKind(container, SyntaxKind.Constructor)))) { return undefined; } } else if (modifier === SyntaxKind.StaticKeyword) { - if (container.kind !== SyntaxKind.ClassDeclaration) { + if (!(container.kind === SyntaxKind.ClassDeclaration || container.kind === SyntaxKind.ClassExpression)) { return undefined; } } @@ -4696,6 +4743,11 @@ namespace ts { return undefined; } } + else if (modifier === SyntaxKind.AbstractKeyword) { + if (!(container.kind === SyntaxKind.ClassDeclaration || declaration.kind === SyntaxKind.ClassDeclaration)) { + return undefined; + } + } else { // unsupported modifier return undefined; @@ -4708,19 +4760,26 @@ namespace ts { switch (container.kind) { case SyntaxKind.ModuleBlock: case SyntaxKind.SourceFile: - nodes = (container).statements; + // Container is either a class declaration or the declaration is a classDeclaration + if (modifierFlag & NodeFlags.Abstract) { + nodes = ((declaration).members).concat(declaration); + } + else { + nodes = (container).statements; + } break; case SyntaxKind.Constructor: nodes = ((container).parameters).concat( (container.parent).members); break; case SyntaxKind.ClassDeclaration: - nodes = (container).members; + case SyntaxKind.ClassExpression: + nodes = (container).members; // If we're an accessibility modifier, we're in an instance member and should search // the constructor's parameter list for instance members as well. if (modifierFlag & NodeFlags.AccessibilityModifier) { - let constructor = forEach((container).members, member => { + let constructor = forEach((container).members, member => { return member.kind === SyntaxKind.Constructor && member; }); @@ -4728,6 +4787,9 @@ namespace ts { nodes = nodes.concat(constructor.parameters); } } + else if (modifierFlag & NodeFlags.Abstract) { + nodes = nodes.concat(container); + } break; default: Debug.fail("Invalid container kind.") @@ -4755,6 +4817,8 @@ namespace ts { return NodeFlags.Export; case SyntaxKind.DeclareKeyword: return NodeFlags.Ambient; + case SyntaxKind.AbstractKeyword: + return NodeFlags.Abstract; default: Debug.fail(); } @@ -6575,7 +6639,7 @@ namespace ts { } } - return ClassificationType.text; + return ClassificationType.identifier; } } diff --git a/src/services/shims.ts b/src/services/shims.ts index 6e765eff499..e2055b3de77 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -34,6 +34,9 @@ namespace ts { * Or undefined value if there was no change. */ getChangeRange(oldSnapshot: ScriptSnapshotShim): string; + + /** Releases all resources held by this script snapshot */ + dispose?(): void; } export interface Logger { @@ -61,8 +64,13 @@ namespace ts { /** Public interface of the the of a config service shim instance.*/ export interface CoreServicesShimHost extends Logger { - /** Returns a JSON-encoded value of the type: string[] */ - readDirectory(rootDir: string, extension: string): string; + /** + * Returns a JSON-encoded value of the type: string[] + * + * @param exclude A JSON encoded string[] containing the paths to exclude + * when enumerating the directory. + */ + readDirectory(rootDir: string, extension: string, exclude?: string): string; } /// @@ -243,6 +251,14 @@ namespace ts { return createTextChangeRange( createTextSpan(decoded.span.start, decoded.span.length), decoded.newLength); } + + public dispose(): void { + // if scriptSnapshotShim is a COM object then property check becomes method call with no arguments + // 'in' does not have this effect + if ("dispose" in this.scriptSnapshotShim) { + this.scriptSnapshotShim.dispose(); + } + } } export class LanguageServiceShimHostAdapter implements LanguageServiceHost { @@ -375,8 +391,18 @@ namespace ts { constructor(private shimHost: CoreServicesShimHost) { } - public readDirectory(rootDir: string, extension: string): string[] { - var encoded = this.shimHost.readDirectory(rootDir, extension); + public readDirectory(rootDir: string, extension: string, exclude: string[]): string[] { + // Wrap the API changes for 1.5 release. This try/catch + // should be removed once TypeScript 1.5 has shipped. + // Also consider removing the optional designation for + // the exclude param at this time. + var encoded: string; + try { + encoded = this.shimHost.readDirectory(rootDir, extension, JSON.stringify(exclude)); + } + catch (e) { + encoded = this.shimHost.readDirectory(rootDir, extension); + } return JSON.parse(encoded); } } diff --git a/tests/baselines/reference/arrowFunctionExpressions.symbols b/tests/baselines/reference/arrowFunctionExpressions.symbols index 28945e1179f..61c575933da 100644 --- a/tests/baselines/reference/arrowFunctionExpressions.symbols +++ b/tests/baselines/reference/arrowFunctionExpressions.symbols @@ -70,6 +70,7 @@ var p6 = ({ a }) => { }; var p7 = ({ a: { b } }) => { }; >p7 : Symbol(p7, Decl(arrowFunctionExpressions.ts, 21, 3)) +>a : Symbol(a) >b : Symbol(b, Decl(arrowFunctionExpressions.ts, 21, 16)) var p8 = ({ a = 1 }) => { }; @@ -78,6 +79,7 @@ var p8 = ({ a = 1 }) => { }; var p9 = ({ a: { b = 1 } = { b: 1 } }) => { }; >p9 : Symbol(p9, Decl(arrowFunctionExpressions.ts, 23, 3)) +>a : Symbol(a) >b : Symbol(b, Decl(arrowFunctionExpressions.ts, 23, 16)) >b : Symbol(b, Decl(arrowFunctionExpressions.ts, 23, 28)) diff --git a/tests/baselines/reference/declarationEmitDestructuring1.symbols b/tests/baselines/reference/declarationEmitDestructuring1.symbols index 10920128eee..32755fdef35 100644 --- a/tests/baselines/reference/declarationEmitDestructuring1.symbols +++ b/tests/baselines/reference/declarationEmitDestructuring1.symbols @@ -23,6 +23,7 @@ function bar({a1, b1, c1}: { a1: number, b1: boolean, c1: string }): void { } function baz({a2, b2: {b1, c1}}: { a2: number, b2: { b1: boolean, c1: string } }): void { } >baz : Symbol(baz, Decl(declarationEmitDestructuring1.ts, 2, 77)) >a2 : Symbol(a2, Decl(declarationEmitDestructuring1.ts, 3, 14)) +>b2 : Symbol(b2, Decl(declarationEmitDestructuring1.ts, 3, 46)) >b1 : Symbol(b1, Decl(declarationEmitDestructuring1.ts, 3, 23)) >c1 : Symbol(c1, Decl(declarationEmitDestructuring1.ts, 3, 26)) >a2 : Symbol(a2, Decl(declarationEmitDestructuring1.ts, 3, 34)) diff --git a/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.symbols b/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.symbols index 9e0e48f89e8..0a3c6f4044d 100644 --- a/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.symbols +++ b/tests/baselines/reference/declarationEmitDestructuringArrayPattern2.symbols @@ -17,6 +17,7 @@ var [a2, [b2, { x12, y12: c2 }]=["abc", { x12: 10, y12: false }]] = [1, ["hello" >a2 : Symbol(a2, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 5)) >b2 : Symbol(b2, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 10)) >x12 : Symbol(x12, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 15)) +>y12 : Symbol(y12, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 91)) >c2 : Symbol(c2, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 20)) >x12 : Symbol(x12, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 41)) >y12 : Symbol(y12, Decl(declarationEmitDestructuringArrayPattern2.ts, 5, 50)) diff --git a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.symbols b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.symbols index 3cb4ef28c2b..0a57a93f3d0 100644 --- a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.symbols +++ b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.symbols @@ -21,24 +21,33 @@ var { x6, y6 } = { x6: 5, y6: "hello" }; >y6 : Symbol(y6, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 4, 25)) var { x7: a1 } = { x7: 5, y7: "hello" }; +>x7 : Symbol(x7, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 5, 18)) >a1 : Symbol(a1, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 5, 5)) >x7 : Symbol(x7, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 5, 18)) >y7 : Symbol(y7, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 5, 25)) var { y8: b1 } = { x8: 5, y8: "hello" }; +>y8 : Symbol(y8, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 6, 25)) >b1 : Symbol(b1, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 6, 5)) >x8 : Symbol(x8, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 6, 18)) >y8 : Symbol(y8, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 6, 25)) var { x9: a2, y9: b2 } = { x9: 5, y9: "hello" }; +>x9 : Symbol(x9, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 26)) >a2 : Symbol(a2, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 5)) +>y9 : Symbol(y9, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 33)) >b2 : Symbol(b2, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 13)) >x9 : Symbol(x9, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 26)) >y9 : Symbol(y9, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 7, 33)) var { a: x11, b: { a: y11, b: { a: z11 }}} = { a: 1, b: { a: "hello", b: { a: true } } }; +>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 46)) >x11 : Symbol(x11, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 5)) +>b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 52)) +>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 57)) >y11 : Symbol(y11, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 18)) +>b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 69)) +>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 74)) >z11 : Symbol(z11, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 31)) >a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 46)) >b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern.ts, 9, 52)) diff --git a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern1.symbols b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern1.symbols index a4c43a07bc8..cac2431411e 100644 --- a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern1.symbols +++ b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern1.symbols @@ -21,17 +21,21 @@ var { x6, y6 } = { x6: 5, y6: "hello" }; >y6 : Symbol(y6, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 4, 25)) var { x7: a1 } = { x7: 5, y7: "hello" }; +>x7 : Symbol(x7, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 5, 18)) >a1 : Symbol(a1, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 5, 5)) >x7 : Symbol(x7, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 5, 18)) >y7 : Symbol(y7, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 5, 25)) var { y8: b1 } = { x8: 5, y8: "hello" }; +>y8 : Symbol(y8, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 6, 25)) >b1 : Symbol(b1, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 6, 5)) >x8 : Symbol(x8, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 6, 18)) >y8 : Symbol(y8, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 6, 25)) var { x9: a2, y9: b2 } = { x9: 5, y9: "hello" }; +>x9 : Symbol(x9, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 26)) >a2 : Symbol(a2, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 5)) +>y9 : Symbol(y9, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 33)) >b2 : Symbol(b2, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 13)) >x9 : Symbol(x9, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 26)) >y9 : Symbol(y9, Decl(declarationEmitDestructuringObjectLiteralPattern1.ts, 7, 33)) diff --git a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.symbols b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.symbols index 76440b60038..77e26e2c9b7 100644 --- a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.symbols +++ b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.symbols @@ -1,8 +1,13 @@ === tests/cases/compiler/declarationEmitDestructuringObjectLiteralPattern2.ts === var { a: x11, b: { a: y11, b: { a: z11 }}} = { a: 1, b: { a: "hello", b: { a: true } } }; +>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 46)) >x11 : Symbol(x11, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 5)) +>b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 52)) +>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 57)) >y11 : Symbol(y11, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 18)) +>b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 69)) +>a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 74)) >z11 : Symbol(z11, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 31)) >a : Symbol(a, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 46)) >b : Symbol(b, Decl(declarationEmitDestructuringObjectLiteralPattern2.ts, 1, 52)) diff --git a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.symbols b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.symbols index 017a7f71e61..718af66047d 100644 --- a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.symbols +++ b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES5.symbols @@ -19,6 +19,7 @@ var { b1, } = { b1:1, }; >b1 : Symbol(b1, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 11, 15)) var { b2: { b21 } = { b21: "string" } } = { b2: { b21: "world" } }; +>b2 : Symbol(b2, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 12, 44)) >b21 : Symbol(b21, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 12, 11)) >b21 : Symbol(b21, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 12, 21)) >b2 : Symbol(b2, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 12, 44)) @@ -32,6 +33,7 @@ var {b4 = 1}: any = { b4: 100000 }; >b4 : Symbol(b4, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 14, 21)) var {b5: { b52 } } = { b5: { b52 } }; +>b5 : Symbol(b5, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 15, 23)) >b52 : Symbol(b52, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 15, 10)) >b5 : Symbol(b5, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 15, 23)) >b52 : Symbol(b52, Decl(destructuringObjectBindingPatternAndAssignment1ES5.ts, 15, 29)) diff --git a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.symbols b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.symbols index 11289210ee4..57d739cbbfc 100644 --- a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.symbols +++ b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment1ES6.symbols @@ -19,6 +19,7 @@ var { b1, } = { b1:1, }; >b1 : Symbol(b1, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 11, 15)) var { b2: { b21 } = { b21: "string" } } = { b2: { b21: "world" } }; +>b2 : Symbol(b2, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 12, 44)) >b21 : Symbol(b21, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 12, 11)) >b21 : Symbol(b21, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 12, 21)) >b2 : Symbol(b2, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 12, 44)) @@ -32,6 +33,7 @@ var {b4 = 1}: any = { b4: 100000 }; >b4 : Symbol(b4, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 14, 21)) var {b5: { b52 } } = { b5: { b52 } }; +>b5 : Symbol(b5, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 15, 23)) >b52 : Symbol(b52, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 15, 10)) >b5 : Symbol(b5, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 15, 23)) >b52 : Symbol(b52, Decl(destructuringObjectBindingPatternAndAssignment1ES6.ts, 15, 29)) diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt index 269d2b5640d..8e51c2b6111 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt @@ -1,16 +1,8 @@ -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(32,4): error TS2345: Argument of type '[string, number, number]' is not assignable to parameter of type '[undefined, null, undefined]'. - Types of property '0' are incompatible. - Type 'string' is not assignable to type 'undefined'. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(33,4): error TS2345: Argument of type '[[string], number, [[boolean, boolean]]]' is not assignable to parameter of type '[[undefined], undefined, [[undefined, undefined]]]'. - Types of property '0' are incompatible. - Type '[string]' is not assignable to type '[undefined]'. - Types of property '0' are incompatible. - Type 'string' is not assignable to type 'undefined'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(62,10): error TS2393: Duplicate function implementation. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(63,10): error TS2393: Duplicate function implementation. -==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts (4 errors) ==== +==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts (2 errors) ==== // A parameter declaration may specify either an identifier or a binding pattern. // The identifiers specified in parameter declarations and binding patterns // in a parameter list must be unique within that parameter list. @@ -43,17 +35,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5. b2("string", { x: 200, y: "string" }); b2("string", { x: 200, y: true }); b6(["string", 1, 2]); // Shouldn't be an error - ~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[string, number, number]' is not assignable to parameter of type '[undefined, null, undefined]'. -!!! error TS2345: Types of property '0' are incompatible. -!!! error TS2345: Type 'string' is not assignable to type 'undefined'. b7([["string"], 1, [[true, false]]]); // Shouldn't be an error - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[[string], number, [[boolean, boolean]]]' is not assignable to parameter of type '[[undefined], undefined, [[undefined, undefined]]]'. -!!! error TS2345: Types of property '0' are incompatible. -!!! error TS2345: Type '[string]' is not assignable to type '[undefined]'. -!!! error TS2345: Types of property '0' are incompatible. -!!! error TS2345: Type 'string' is not assignable to type 'undefined'. // If the declaration specifies a binding pattern, the parameter type is the implied type of that binding pattern (section 5.1.3) diff --git a/tests/baselines/reference/destructuringVariableDeclaration1ES5.symbols b/tests/baselines/reference/destructuringVariableDeclaration1ES5.symbols index 2a2f2a358ca..924527bf1b4 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration1ES5.symbols +++ b/tests/baselines/reference/destructuringVariableDeclaration1ES5.symbols @@ -17,6 +17,7 @@ var [a3, [[a4]], a5]: [number, [[string]], boolean] = [1, [["hello"]], true]; // The type T associated with a destructuring variable declaration is determined as follows: // Otherwise, if the declaration includes an initializer expression, T is the type of that initializer expression. var { b1: { b11 } = { b11: "string" } } = { b1: { b11: "world" } }; +>b1 : Symbol(b1, Decl(destructuringVariableDeclaration1ES5.ts, 7, 44)) >b11 : Symbol(b11, Decl(destructuringVariableDeclaration1ES5.ts, 7, 11)) >b11 : Symbol(b11, Decl(destructuringVariableDeclaration1ES5.ts, 7, 21)) >b1 : Symbol(b1, Decl(destructuringVariableDeclaration1ES5.ts, 7, 44)) @@ -74,6 +75,7 @@ var [d3, d4] = [1, "string", ...temp1]; // Combining both forms of destructuring, var {e: [e1, e2, e3 = { b1: 1000, b4: 200 }]} = { e: [1, 2, { b1: 4, b4: 0 }] }; +>e : Symbol(e, Decl(destructuringVariableDeclaration1ES5.ts, 31, 49)) >e1 : Symbol(e1, Decl(destructuringVariableDeclaration1ES5.ts, 31, 9)) >e2 : Symbol(e2, Decl(destructuringVariableDeclaration1ES5.ts, 31, 12)) >e3 : Symbol(e3, Decl(destructuringVariableDeclaration1ES5.ts, 31, 16)) @@ -84,8 +86,10 @@ var {e: [e1, e2, e3 = { b1: 1000, b4: 200 }]} = { e: [1, 2, { b1: 4, b4: 0 }] }; >b4 : Symbol(b4, Decl(destructuringVariableDeclaration1ES5.ts, 31, 68)) var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; +>f : Symbol(f, Decl(destructuringVariableDeclaration1ES5.ts, 32, 41)) >f1 : Symbol(f1, Decl(destructuringVariableDeclaration1ES5.ts, 32, 9)) >f2 : Symbol(f2, Decl(destructuringVariableDeclaration1ES5.ts, 32, 12)) +>f3 : Symbol(f3, Decl(destructuringVariableDeclaration1ES5.ts, 32, 53)) >f4 : Symbol(f4, Decl(destructuringVariableDeclaration1ES5.ts, 32, 18)) >f5 : Symbol(f5, Decl(destructuringVariableDeclaration1ES5.ts, 32, 26)) >f : Symbol(f, Decl(destructuringVariableDeclaration1ES5.ts, 32, 41)) @@ -96,6 +100,7 @@ var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; // an initializer expression, the type of the initializer expression is required to be assignable // to the widened form of the type associated with the destructuring variable declaration, binding property, or binding element. var {g: {g1 = [undefined, null]}}: { g: { g1: any[] } } = { g: { g1: [1, 2] } }; +>g : Symbol(g, Decl(destructuringVariableDeclaration1ES5.ts, 37, 36)) >g1 : Symbol(g1, Decl(destructuringVariableDeclaration1ES5.ts, 37, 9)) >undefined : Symbol(undefined) >g : Symbol(g, Decl(destructuringVariableDeclaration1ES5.ts, 37, 36)) @@ -104,6 +109,7 @@ var {g: {g1 = [undefined, null]}}: { g: { g1: any[] } } = { g: { g1: [1, 2] } }; >g1 : Symbol(g1, Decl(destructuringVariableDeclaration1ES5.ts, 37, 64)) var {h: {h1 = [undefined, null]}}: { h: { h1: number[] } } = { h: { h1: [1, 2] } }; +>h : Symbol(h, Decl(destructuringVariableDeclaration1ES5.ts, 38, 36)) >h1 : Symbol(h1, Decl(destructuringVariableDeclaration1ES5.ts, 38, 9)) >undefined : Symbol(undefined) >h : Symbol(h, Decl(destructuringVariableDeclaration1ES5.ts, 38, 36)) diff --git a/tests/baselines/reference/destructuringVariableDeclaration1ES6.symbols b/tests/baselines/reference/destructuringVariableDeclaration1ES6.symbols index 0350ff35251..ee4f391eb7a 100644 --- a/tests/baselines/reference/destructuringVariableDeclaration1ES6.symbols +++ b/tests/baselines/reference/destructuringVariableDeclaration1ES6.symbols @@ -17,6 +17,7 @@ var [a3, [[a4]], a5]: [number, [[string]], boolean] = [1, [["hello"]], true]; // The type T associated with a destructuring variable declaration is determined as follows: // Otherwise, if the declaration includes an initializer expression, T is the type of that initializer expression. var { b1: { b11 } = { b11: "string" } } = { b1: { b11: "world" } }; +>b1 : Symbol(b1, Decl(destructuringVariableDeclaration1ES6.ts, 7, 44)) >b11 : Symbol(b11, Decl(destructuringVariableDeclaration1ES6.ts, 7, 11)) >b11 : Symbol(b11, Decl(destructuringVariableDeclaration1ES6.ts, 7, 21)) >b1 : Symbol(b1, Decl(destructuringVariableDeclaration1ES6.ts, 7, 44)) @@ -74,6 +75,7 @@ var [d3, d4] = [1, "string", ...temp1]; // Combining both forms of destructuring, var {e: [e1, e2, e3 = { b1: 1000, b4: 200 }]} = { e: [1, 2, { b1: 4, b4: 0 }] }; +>e : Symbol(e, Decl(destructuringVariableDeclaration1ES6.ts, 31, 49)) >e1 : Symbol(e1, Decl(destructuringVariableDeclaration1ES6.ts, 31, 9)) >e2 : Symbol(e2, Decl(destructuringVariableDeclaration1ES6.ts, 31, 12)) >e3 : Symbol(e3, Decl(destructuringVariableDeclaration1ES6.ts, 31, 16)) @@ -84,8 +86,10 @@ var {e: [e1, e2, e3 = { b1: 1000, b4: 200 }]} = { e: [1, 2, { b1: 4, b4: 0 }] }; >b4 : Symbol(b4, Decl(destructuringVariableDeclaration1ES6.ts, 31, 68)) var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; +>f : Symbol(f, Decl(destructuringVariableDeclaration1ES6.ts, 32, 41)) >f1 : Symbol(f1, Decl(destructuringVariableDeclaration1ES6.ts, 32, 9)) >f2 : Symbol(f2, Decl(destructuringVariableDeclaration1ES6.ts, 32, 12)) +>f3 : Symbol(f3, Decl(destructuringVariableDeclaration1ES6.ts, 32, 53)) >f4 : Symbol(f4, Decl(destructuringVariableDeclaration1ES6.ts, 32, 18)) >f5 : Symbol(f5, Decl(destructuringVariableDeclaration1ES6.ts, 32, 26)) >f : Symbol(f, Decl(destructuringVariableDeclaration1ES6.ts, 32, 41)) @@ -96,6 +100,7 @@ var {f: [f1, f2, { f3: f4, f5 }, , ]} = { f: [1, 2, { f3: 4, f5: 0 }] }; // an initializer expression, the type of the initializer expression is required to be assignable // to the widened form of the type associated with the destructuring variable declaration, binding property, or binding element. var {g: {g1 = [undefined, null]}}: { g: { g1: any[] } } = { g: { g1: [1, 2] } }; +>g : Symbol(g, Decl(destructuringVariableDeclaration1ES6.ts, 37, 36)) >g1 : Symbol(g1, Decl(destructuringVariableDeclaration1ES6.ts, 37, 9)) >undefined : Symbol(undefined) >g : Symbol(g, Decl(destructuringVariableDeclaration1ES6.ts, 37, 36)) @@ -104,6 +109,7 @@ var {g: {g1 = [undefined, null]}}: { g: { g1: any[] } } = { g: { g1: [1, 2] } }; >g1 : Symbol(g1, Decl(destructuringVariableDeclaration1ES6.ts, 37, 64)) var {h: {h1 = [undefined, null]}}: { h: { h1: number[] } } = { h: { h1: [1, 2] } }; +>h : Symbol(h, Decl(destructuringVariableDeclaration1ES6.ts, 38, 36)) >h1 : Symbol(h1, Decl(destructuringVariableDeclaration1ES6.ts, 38, 9)) >undefined : Symbol(undefined) >h : Symbol(h, Decl(destructuringVariableDeclaration1ES6.ts, 38, 36)) diff --git a/tests/baselines/reference/downlevelLetConst12.symbols b/tests/baselines/reference/downlevelLetConst12.symbols index d1c7fe3ea5b..97d6d5eebf8 100644 --- a/tests/baselines/reference/downlevelLetConst12.symbols +++ b/tests/baselines/reference/downlevelLetConst12.symbols @@ -12,6 +12,7 @@ let [baz] = []; >baz : Symbol(baz, Decl(downlevelLetConst12.ts, 6, 5)) let {a: baz2} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst12.ts, 7, 17)) >baz2 : Symbol(baz2, Decl(downlevelLetConst12.ts, 7, 5)) >a : Symbol(a, Decl(downlevelLetConst12.ts, 7, 17)) @@ -19,6 +20,7 @@ const [baz3] = [] >baz3 : Symbol(baz3, Decl(downlevelLetConst12.ts, 9, 7)) const {a: baz4} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst12.ts, 10, 19)) >baz4 : Symbol(baz4, Decl(downlevelLetConst12.ts, 10, 7)) >a : Symbol(a, Decl(downlevelLetConst12.ts, 10, 19)) diff --git a/tests/baselines/reference/downlevelLetConst13.symbols b/tests/baselines/reference/downlevelLetConst13.symbols index 1b06184f2b3..f8cd2e548a9 100644 --- a/tests/baselines/reference/downlevelLetConst13.symbols +++ b/tests/baselines/reference/downlevelLetConst13.symbols @@ -16,10 +16,12 @@ export const [bar2] = [2]; >bar2 : Symbol(bar2, Decl(downlevelLetConst13.ts, 7, 14)) export let {a: bar3} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst13.ts, 8, 24)) >bar3 : Symbol(bar3, Decl(downlevelLetConst13.ts, 8, 12)) >a : Symbol(a, Decl(downlevelLetConst13.ts, 8, 24)) export const {a: bar4} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst13.ts, 9, 26)) >bar4 : Symbol(bar4, Decl(downlevelLetConst13.ts, 9, 14)) >a : Symbol(a, Decl(downlevelLetConst13.ts, 9, 26)) @@ -39,10 +41,12 @@ export module M { >bar6 : Symbol(bar6, Decl(downlevelLetConst13.ts, 15, 18)) export let {a: bar7} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst13.ts, 16, 28)) >bar7 : Symbol(bar7, Decl(downlevelLetConst13.ts, 16, 16)) >a : Symbol(a, Decl(downlevelLetConst13.ts, 16, 28)) export const {a: bar8} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst13.ts, 17, 30)) >bar8 : Symbol(bar8, Decl(downlevelLetConst13.ts, 17, 18)) >a : Symbol(a, Decl(downlevelLetConst13.ts, 17, 30)) } diff --git a/tests/baselines/reference/downlevelLetConst14.symbols b/tests/baselines/reference/downlevelLetConst14.symbols index bf3450af71c..135f3c1417d 100644 --- a/tests/baselines/reference/downlevelLetConst14.symbols +++ b/tests/baselines/reference/downlevelLetConst14.symbols @@ -35,6 +35,7 @@ var z0, z1, z2, z3; >z1 : Symbol(z1, Decl(downlevelLetConst14.ts, 11, 9)) let {a: z2} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst14.ts, 13, 19)) >z2 : Symbol(z2, Decl(downlevelLetConst14.ts, 13, 9)) >a : Symbol(a, Decl(downlevelLetConst14.ts, 13, 19)) @@ -43,6 +44,7 @@ var z0, z1, z2, z3; >z2 : Symbol(z2, Decl(downlevelLetConst14.ts, 13, 9)) let {a: z3} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst14.ts, 15, 19)) >z3 : Symbol(z3, Decl(downlevelLetConst14.ts, 15, 9)) >a : Symbol(a, Decl(downlevelLetConst14.ts, 15, 19)) @@ -86,6 +88,7 @@ var y = true; >y : Symbol(y, Decl(downlevelLetConst14.ts, 29, 11)) let {a: z6} = {a: 1} +>a : Symbol(a, Decl(downlevelLetConst14.ts, 30, 23)) >z6 : Symbol(z6, Decl(downlevelLetConst14.ts, 30, 13)) >a : Symbol(a, Decl(downlevelLetConst14.ts, 30, 23)) @@ -129,6 +132,7 @@ var z5 = 1; >_z : Symbol(_z, Decl(downlevelLetConst14.ts, 46, 11)) let {a: _z5} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst14.ts, 47, 24)) >_z5 : Symbol(_z5, Decl(downlevelLetConst14.ts, 47, 13)) >a : Symbol(a, Decl(downlevelLetConst14.ts, 47, 24)) diff --git a/tests/baselines/reference/downlevelLetConst15.symbols b/tests/baselines/reference/downlevelLetConst15.symbols index 159e5a6d676..00c7e122eb2 100644 --- a/tests/baselines/reference/downlevelLetConst15.symbols +++ b/tests/baselines/reference/downlevelLetConst15.symbols @@ -28,6 +28,7 @@ var z0, z1, z2, z3; >z0 : Symbol(z0, Decl(downlevelLetConst15.ts, 9, 11)) const [{a: z1}] = [{a: 1}] +>a : Symbol(a, Decl(downlevelLetConst15.ts, 11, 24)) >z1 : Symbol(z1, Decl(downlevelLetConst15.ts, 11, 12)) >a : Symbol(a, Decl(downlevelLetConst15.ts, 11, 24)) @@ -36,6 +37,7 @@ var z0, z1, z2, z3; >z1 : Symbol(z1, Decl(downlevelLetConst15.ts, 11, 12)) const {a: z2} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst15.ts, 13, 21)) >z2 : Symbol(z2, Decl(downlevelLetConst15.ts, 13, 11)) >a : Symbol(a, Decl(downlevelLetConst15.ts, 13, 21)) @@ -44,6 +46,8 @@ var z0, z1, z2, z3; >z2 : Symbol(z2, Decl(downlevelLetConst15.ts, 13, 11)) const {a: {b: z3}} = { a: {b: 1} }; +>a : Symbol(a, Decl(downlevelLetConst15.ts, 15, 26)) +>b : Symbol(b, Decl(downlevelLetConst15.ts, 15, 31)) >z3 : Symbol(z3, Decl(downlevelLetConst15.ts, 15, 15)) >a : Symbol(a, Decl(downlevelLetConst15.ts, 15, 26)) >b : Symbol(b, Decl(downlevelLetConst15.ts, 15, 31)) @@ -88,6 +92,7 @@ var y = true; >y : Symbol(y, Decl(downlevelLetConst15.ts, 29, 13)) const {a: z6} = { a: 1 } +>a : Symbol(a, Decl(downlevelLetConst15.ts, 30, 25)) >z6 : Symbol(z6, Decl(downlevelLetConst15.ts, 30, 15)) >a : Symbol(a, Decl(downlevelLetConst15.ts, 30, 25)) @@ -131,6 +136,7 @@ var z5 = 1; >_z : Symbol(_z, Decl(downlevelLetConst15.ts, 46, 13)) const {a: _z5} = { a: 1 }; +>a : Symbol(a, Decl(downlevelLetConst15.ts, 47, 26)) >_z5 : Symbol(_z5, Decl(downlevelLetConst15.ts, 47, 15)) >a : Symbol(a, Decl(downlevelLetConst15.ts, 47, 26)) diff --git a/tests/baselines/reference/emitArrowFunctionES6.symbols b/tests/baselines/reference/emitArrowFunctionES6.symbols index 06f83f7f6f0..8d1603cfd82 100644 --- a/tests/baselines/reference/emitArrowFunctionES6.symbols +++ b/tests/baselines/reference/emitArrowFunctionES6.symbols @@ -56,6 +56,7 @@ var p6 = ({ a }) => { }; var p7 = ({ a: { b } }) => { }; >p7 : Symbol(p7, Decl(emitArrowFunctionES6.ts, 15, 3)) +>a : Symbol(a) >b : Symbol(b, Decl(emitArrowFunctionES6.ts, 15, 16)) var p8 = ({ a = 1 }) => { }; @@ -64,6 +65,7 @@ var p8 = ({ a = 1 }) => { }; var p9 = ({ a: { b = 1 } = { b: 1 } }) => { }; >p9 : Symbol(p9, Decl(emitArrowFunctionES6.ts, 17, 3)) +>a : Symbol(a) >b : Symbol(b, Decl(emitArrowFunctionES6.ts, 17, 16)) >b : Symbol(b, Decl(emitArrowFunctionES6.ts, 17, 28)) diff --git a/tests/baselines/reference/emitArrowFunctionWhenUsingArguments18_ES6.symbols b/tests/baselines/reference/emitArrowFunctionWhenUsingArguments18_ES6.symbols index 4ac60f9b429..707b99c82c1 100644 --- a/tests/baselines/reference/emitArrowFunctionWhenUsingArguments18_ES6.symbols +++ b/tests/baselines/reference/emitArrowFunctionWhenUsingArguments18_ES6.symbols @@ -4,6 +4,7 @@ function f() { >f : Symbol(f, Decl(emitArrowFunctionWhenUsingArguments18_ES6.ts, 0, 0)) var { arguments: args } = { arguments }; +>arguments : Symbol(arguments, Decl(emitArrowFunctionWhenUsingArguments18_ES6.ts, 2, 31)) >args : Symbol(args, Decl(emitArrowFunctionWhenUsingArguments18_ES6.ts, 2, 9)) >arguments : Symbol(arguments, Decl(emitArrowFunctionWhenUsingArguments18_ES6.ts, 2, 31)) diff --git a/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.js b/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.js new file mode 100644 index 00000000000..a6700fb5e59 --- /dev/null +++ b/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.js @@ -0,0 +1,34 @@ +//// [tests/cases/compiler/exportDeclarationWithModuleSpecifierNameOnNextLine1.ts] //// + +//// [t1.ts] + +export var x = "x"; + +//// [t2.ts] +export { x } from + "./t1"; + +//// [t3.ts] +export { } from + "./t1"; + +//// [t4.ts] +export { x as a } from + "./t1"; + +//// [t5.ts] +export { x as a, } from + "./t1"; + +//// [t1.js] +exports.x = "x"; +//// [t2.js] +var t1_1 = require("./t1"); +exports.x = t1_1.x; +//// [t3.js] +//// [t4.js] +var t1_1 = require("./t1"); +exports.a = t1_1.x; +//// [t5.js] +var t1_1 = require("./t1"); +exports.a = t1_1.x; diff --git a/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.symbols b/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.symbols new file mode 100644 index 00000000000..331766f7712 --- /dev/null +++ b/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.symbols @@ -0,0 +1,28 @@ +=== tests/cases/compiler/t1.ts === + +export var x = "x"; +>x : Symbol(x, Decl(t1.ts, 1, 10)) + +=== tests/cases/compiler/t2.ts === +export { x } from +>x : Symbol(x, Decl(t2.ts, 0, 8)) + + "./t1"; + +=== tests/cases/compiler/t3.ts === +export { } from +No type information for this code. "./t1"; +No type information for this code. +No type information for this code.=== tests/cases/compiler/t4.ts === +export { x as a } from +>x : Symbol(a, Decl(t4.ts, 0, 8)) +>a : Symbol(a, Decl(t4.ts, 0, 8)) + + "./t1"; + +=== tests/cases/compiler/t5.ts === +export { x as a, } from +>x : Symbol(a, Decl(t5.ts, 0, 8)) +>a : Symbol(a, Decl(t5.ts, 0, 8)) + + "./t1"; diff --git a/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.types b/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.types new file mode 100644 index 00000000000..1ad841fe947 --- /dev/null +++ b/tests/baselines/reference/exportDeclarationWithModuleSpecifierNameOnNextLine1.types @@ -0,0 +1,29 @@ +=== tests/cases/compiler/t1.ts === + +export var x = "x"; +>x : string +>"x" : string + +=== tests/cases/compiler/t2.ts === +export { x } from +>x : string + + "./t1"; + +=== tests/cases/compiler/t3.ts === +export { } from +No type information for this code. "./t1"; +No type information for this code. +No type information for this code.=== tests/cases/compiler/t4.ts === +export { x as a } from +>x : string +>a : string + + "./t1"; + +=== tests/cases/compiler/t5.ts === +export { x as a, } from +>x : string +>a : string + + "./t1"; diff --git a/tests/baselines/reference/for-of41.symbols b/tests/baselines/reference/for-of41.symbols index cf8db913919..046361653bb 100644 --- a/tests/baselines/reference/for-of41.symbols +++ b/tests/baselines/reference/for-of41.symbols @@ -6,7 +6,9 @@ var array = [{x: [0], y: {p: ""}}] >p : Symbol(p, Decl(for-of41.ts, 0, 26)) for (var {x: [a], y: {p}} of array) { +>x : Symbol(x, Decl(for-of41.ts, 0, 14)) >a : Symbol(a, Decl(for-of41.ts, 1, 14)) +>y : Symbol(y, Decl(for-of41.ts, 0, 21)) >p : Symbol(p, Decl(for-of41.ts, 1, 22)) >array : Symbol(array, Decl(for-of41.ts, 0, 3)) diff --git a/tests/baselines/reference/for-of42.symbols b/tests/baselines/reference/for-of42.symbols index b310fb1044f..5310f4970b9 100644 --- a/tests/baselines/reference/for-of42.symbols +++ b/tests/baselines/reference/for-of42.symbols @@ -5,7 +5,9 @@ var array = [{ x: "", y: 0 }] >y : Symbol(y, Decl(for-of42.ts, 0, 21)) for (var {x: a, y: b} of array) { +>x : Symbol(x, Decl(for-of42.ts, 0, 14)) >a : Symbol(a, Decl(for-of42.ts, 1, 10)) +>y : Symbol(y, Decl(for-of42.ts, 0, 21)) >b : Symbol(b, Decl(for-of42.ts, 1, 15)) >array : Symbol(array, Decl(for-of42.ts, 0, 3)) diff --git a/tests/baselines/reference/initializePropertiesWithRenamedLet.symbols b/tests/baselines/reference/initializePropertiesWithRenamedLet.symbols index 203508ddf98..f16d8cfc9e0 100644 --- a/tests/baselines/reference/initializePropertiesWithRenamedLet.symbols +++ b/tests/baselines/reference/initializePropertiesWithRenamedLet.symbols @@ -24,6 +24,7 @@ var x, y, z; if (true) { let { x: x } = { x: 0 }; +>x : Symbol(x, Decl(initializePropertiesWithRenamedLet.ts, 10, 20)) >x : Symbol(x, Decl(initializePropertiesWithRenamedLet.ts, 10, 9)) >x : Symbol(x, Decl(initializePropertiesWithRenamedLet.ts, 10, 20)) diff --git a/tests/baselines/reference/letInNonStrictMode.symbols b/tests/baselines/reference/letInNonStrictMode.symbols index 2b854a8c03f..47ba4465d1b 100644 --- a/tests/baselines/reference/letInNonStrictMode.symbols +++ b/tests/baselines/reference/letInNonStrictMode.symbols @@ -3,6 +3,7 @@ let [x] = [1]; >x : Symbol(x, Decl(letInNonStrictMode.ts, 0, 5)) let {a: y} = {a: 1}; +>a : Symbol(a, Decl(letInNonStrictMode.ts, 1, 14)) >y : Symbol(y, Decl(letInNonStrictMode.ts, 1, 5)) >a : Symbol(a, Decl(letInNonStrictMode.ts, 1, 14)) diff --git a/tests/baselines/reference/objectBindingPatternKeywordIdentifiers06.symbols b/tests/baselines/reference/objectBindingPatternKeywordIdentifiers06.symbols index 7cee5f3009b..f0546012498 100644 --- a/tests/baselines/reference/objectBindingPatternKeywordIdentifiers06.symbols +++ b/tests/baselines/reference/objectBindingPatternKeywordIdentifiers06.symbols @@ -1,6 +1,7 @@ === tests/cases/conformance/es6/destructuring/objectBindingPatternKeywordIdentifiers06.ts === var { as: as } = { as: 1 } +>as : Symbol(as, Decl(objectBindingPatternKeywordIdentifiers06.ts, 1, 18)) >as : Symbol(as, Decl(objectBindingPatternKeywordIdentifiers06.ts, 1, 5)) >as : Symbol(as, Decl(objectBindingPatternKeywordIdentifiers06.ts, 1, 18)) diff --git a/tests/baselines/reference/strictModeInConstructor.js b/tests/baselines/reference/strictModeInConstructor.js index 7fd74aa108f..7d1adc48fa0 100644 --- a/tests/baselines/reference/strictModeInConstructor.js +++ b/tests/baselines/reference/strictModeInConstructor.js @@ -74,8 +74,8 @@ var A = (function () { var B = (function (_super) { __extends(B, _super); function B() { - this.s = 9; "use strict"; // No error + this.s = 9; _super.call(this); } return B; diff --git a/tests/baselines/reference/superSymbolIndexedAccess1.js b/tests/baselines/reference/superSymbolIndexedAccess1.js new file mode 100644 index 00000000000..411158bcc7d --- /dev/null +++ b/tests/baselines/reference/superSymbolIndexedAccess1.js @@ -0,0 +1,27 @@ +//// [superSymbolIndexedAccess1.ts] +var symbol = Symbol.for('myThing'); + +class Foo { + [symbol]() { + return 0; + } +} + +class Bar extends Foo { + [symbol]() { + return super[symbol](); + } +} + +//// [superSymbolIndexedAccess1.js] +var symbol = Symbol.for('myThing'); +class Foo { + [symbol]() { + return 0; + } +} +class Bar extends Foo { + [symbol]() { + return super[symbol](); + } +} diff --git a/tests/baselines/reference/superSymbolIndexedAccess1.symbols b/tests/baselines/reference/superSymbolIndexedAccess1.symbols new file mode 100644 index 00000000000..818d0ac52af --- /dev/null +++ b/tests/baselines/reference/superSymbolIndexedAccess1.symbols @@ -0,0 +1,29 @@ +=== tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess1.ts === +var symbol = Symbol.for('myThing'); +>symbol : Symbol(symbol, Decl(superSymbolIndexedAccess1.ts, 0, 3)) +>Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.d.ts, 1221, 42)) +>Symbol : Symbol(Symbol, Decl(lib.d.ts, 1199, 52), Decl(lib.d.ts, 1305, 11)) +>for : Symbol(SymbolConstructor.for, Decl(lib.d.ts, 1221, 42)) + +class Foo { +>Foo : Symbol(Foo, Decl(superSymbolIndexedAccess1.ts, 0, 35)) + + [symbol]() { +>symbol : Symbol(symbol, Decl(superSymbolIndexedAccess1.ts, 0, 3)) + + return 0; + } +} + +class Bar extends Foo { +>Bar : Symbol(Bar, Decl(superSymbolIndexedAccess1.ts, 6, 1)) +>Foo : Symbol(Foo, Decl(superSymbolIndexedAccess1.ts, 0, 35)) + + [symbol]() { +>symbol : Symbol(symbol, Decl(superSymbolIndexedAccess1.ts, 0, 3)) + + return super[symbol](); +>super : Symbol(Foo, Decl(superSymbolIndexedAccess1.ts, 0, 35)) +>symbol : Symbol(symbol, Decl(superSymbolIndexedAccess1.ts, 0, 3)) + } +} diff --git a/tests/baselines/reference/superSymbolIndexedAccess1.types b/tests/baselines/reference/superSymbolIndexedAccess1.types new file mode 100644 index 00000000000..af2c6cab156 --- /dev/null +++ b/tests/baselines/reference/superSymbolIndexedAccess1.types @@ -0,0 +1,34 @@ +=== tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess1.ts === +var symbol = Symbol.for('myThing'); +>symbol : symbol +>Symbol.for('myThing') : symbol +>Symbol.for : (key: string) => symbol +>Symbol : SymbolConstructor +>for : (key: string) => symbol +>'myThing' : string + +class Foo { +>Foo : Foo + + [symbol]() { +>symbol : symbol + + return 0; +>0 : number + } +} + +class Bar extends Foo { +>Bar : Bar +>Foo : Foo + + [symbol]() { +>symbol : symbol + + return super[symbol](); +>super[symbol]() : any +>super[symbol] : any +>super : Foo +>symbol : symbol + } +} diff --git a/tests/baselines/reference/superSymbolIndexedAccess2.js b/tests/baselines/reference/superSymbolIndexedAccess2.js new file mode 100644 index 00000000000..bc42addc41f --- /dev/null +++ b/tests/baselines/reference/superSymbolIndexedAccess2.js @@ -0,0 +1,25 @@ +//// [superSymbolIndexedAccess2.ts] + +class Foo { + [Symbol.isConcatSpreadable]() { + return 0; + } +} + +class Bar extends Foo { + [Symbol.isConcatSpreadable]() { + return super[Symbol.isConcatSpreadable](); + } +} + +//// [superSymbolIndexedAccess2.js] +class Foo { + [Symbol.isConcatSpreadable]() { + return 0; + } +} +class Bar extends Foo { + [Symbol.isConcatSpreadable]() { + return super[Symbol.isConcatSpreadable](); + } +} diff --git a/tests/baselines/reference/superSymbolIndexedAccess2.symbols b/tests/baselines/reference/superSymbolIndexedAccess2.symbols new file mode 100644 index 00000000000..3865b920647 --- /dev/null +++ b/tests/baselines/reference/superSymbolIndexedAccess2.symbols @@ -0,0 +1,30 @@ +=== tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess2.ts === + +class Foo { +>Foo : Symbol(Foo, Decl(superSymbolIndexedAccess2.ts, 0, 0)) + + [Symbol.isConcatSpreadable]() { +>Symbol.isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.d.ts, 1243, 24)) +>Symbol : Symbol(Symbol, Decl(lib.d.ts, 1199, 52), Decl(lib.d.ts, 1305, 11)) +>isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.d.ts, 1243, 24)) + + return 0; + } +} + +class Bar extends Foo { +>Bar : Symbol(Bar, Decl(superSymbolIndexedAccess2.ts, 5, 1)) +>Foo : Symbol(Foo, Decl(superSymbolIndexedAccess2.ts, 0, 0)) + + [Symbol.isConcatSpreadable]() { +>Symbol.isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.d.ts, 1243, 24)) +>Symbol : Symbol(Symbol, Decl(lib.d.ts, 1199, 52), Decl(lib.d.ts, 1305, 11)) +>isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.d.ts, 1243, 24)) + + return super[Symbol.isConcatSpreadable](); +>super : Symbol(Foo, Decl(superSymbolIndexedAccess2.ts, 0, 0)) +>Symbol.isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.d.ts, 1243, 24)) +>Symbol : Symbol(Symbol, Decl(lib.d.ts, 1199, 52), Decl(lib.d.ts, 1305, 11)) +>isConcatSpreadable : Symbol(SymbolConstructor.isConcatSpreadable, Decl(lib.d.ts, 1243, 24)) + } +} diff --git a/tests/baselines/reference/superSymbolIndexedAccess2.types b/tests/baselines/reference/superSymbolIndexedAccess2.types new file mode 100644 index 00000000000..72bb6914d3e --- /dev/null +++ b/tests/baselines/reference/superSymbolIndexedAccess2.types @@ -0,0 +1,33 @@ +=== tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess2.ts === + +class Foo { +>Foo : Foo + + [Symbol.isConcatSpreadable]() { +>Symbol.isConcatSpreadable : symbol +>Symbol : SymbolConstructor +>isConcatSpreadable : symbol + + return 0; +>0 : number + } +} + +class Bar extends Foo { +>Bar : Bar +>Foo : Foo + + [Symbol.isConcatSpreadable]() { +>Symbol.isConcatSpreadable : symbol +>Symbol : SymbolConstructor +>isConcatSpreadable : symbol + + return super[Symbol.isConcatSpreadable](); +>super[Symbol.isConcatSpreadable]() : number +>super[Symbol.isConcatSpreadable] : () => number +>super : Foo +>Symbol.isConcatSpreadable : symbol +>Symbol : SymbolConstructor +>isConcatSpreadable : symbol + } +} diff --git a/tests/baselines/reference/superSymbolIndexedAccess3.errors.txt b/tests/baselines/reference/superSymbolIndexedAccess3.errors.txt new file mode 100644 index 00000000000..7f25510e00b --- /dev/null +++ b/tests/baselines/reference/superSymbolIndexedAccess3.errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess3.ts(11,16): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. + + +==== tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess3.ts (1 errors) ==== + var symbol = Symbol.for('myThing'); + + class Foo { + [symbol]() { + return 0; + } + } + + class Bar extends Foo { + [symbol]() { + return super[Bar](); + ~~~~~~~~~~ +!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/superSymbolIndexedAccess3.js b/tests/baselines/reference/superSymbolIndexedAccess3.js new file mode 100644 index 00000000000..439a13c6e6e --- /dev/null +++ b/tests/baselines/reference/superSymbolIndexedAccess3.js @@ -0,0 +1,27 @@ +//// [superSymbolIndexedAccess3.ts] +var symbol = Symbol.for('myThing'); + +class Foo { + [symbol]() { + return 0; + } +} + +class Bar extends Foo { + [symbol]() { + return super[Bar](); + } +} + +//// [superSymbolIndexedAccess3.js] +var symbol = Symbol.for('myThing'); +class Foo { + [symbol]() { + return 0; + } +} +class Bar extends Foo { + [symbol]() { + return super[Bar](); + } +} diff --git a/tests/baselines/reference/superSymbolIndexedAccess4.errors.txt b/tests/baselines/reference/superSymbolIndexedAccess4.errors.txt new file mode 100644 index 00000000000..dbf18c3d00d --- /dev/null +++ b/tests/baselines/reference/superSymbolIndexedAccess4.errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess4.ts(5,16): error TS2335: 'super' can only be referenced in a derived class. + + +==== tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess4.ts (1 errors) ==== + var symbol = Symbol.for('myThing'); + + class Bar { + [symbol]() { + return super[symbol](); + ~~~~~ +!!! error TS2335: 'super' can only be referenced in a derived class. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/superSymbolIndexedAccess4.js b/tests/baselines/reference/superSymbolIndexedAccess4.js new file mode 100644 index 00000000000..8d966511fc6 --- /dev/null +++ b/tests/baselines/reference/superSymbolIndexedAccess4.js @@ -0,0 +1,16 @@ +//// [superSymbolIndexedAccess4.ts] +var symbol = Symbol.for('myThing'); + +class Bar { + [symbol]() { + return super[symbol](); + } +} + +//// [superSymbolIndexedAccess4.js] +var symbol = Symbol.for('myThing'); +class Bar { + [symbol]() { + return super[symbol](); + } +} diff --git a/tests/baselines/reference/superSymbolIndexedAccess5.js b/tests/baselines/reference/superSymbolIndexedAccess5.js new file mode 100644 index 00000000000..64a8ac5094c --- /dev/null +++ b/tests/baselines/reference/superSymbolIndexedAccess5.js @@ -0,0 +1,40 @@ +//// [superSymbolIndexedAccess5.ts] +var symbol: any; + +class Foo { + [symbol]() { + return 0; + } +} + +class Bar extends Foo { + [symbol]() { + return super[symbol](); + } +} + +//// [superSymbolIndexedAccess5.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var symbol; +var Foo = (function () { + function Foo() { + } + Foo.prototype[symbol] = function () { + return 0; + }; + return Foo; +})(); +var Bar = (function (_super) { + __extends(Bar, _super); + function Bar() { + _super.apply(this, arguments); + } + Bar.prototype[symbol] = function () { + return _super.prototype[symbol](); + }; + return Bar; +})(Foo); diff --git a/tests/baselines/reference/superSymbolIndexedAccess5.symbols b/tests/baselines/reference/superSymbolIndexedAccess5.symbols new file mode 100644 index 00000000000..98ff04a25cd --- /dev/null +++ b/tests/baselines/reference/superSymbolIndexedAccess5.symbols @@ -0,0 +1,26 @@ +=== tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess5.ts === +var symbol: any; +>symbol : Symbol(symbol, Decl(superSymbolIndexedAccess5.ts, 0, 3)) + +class Foo { +>Foo : Symbol(Foo, Decl(superSymbolIndexedAccess5.ts, 0, 16)) + + [symbol]() { +>symbol : Symbol(symbol, Decl(superSymbolIndexedAccess5.ts, 0, 3)) + + return 0; + } +} + +class Bar extends Foo { +>Bar : Symbol(Bar, Decl(superSymbolIndexedAccess5.ts, 6, 1)) +>Foo : Symbol(Foo, Decl(superSymbolIndexedAccess5.ts, 0, 16)) + + [symbol]() { +>symbol : Symbol(symbol, Decl(superSymbolIndexedAccess5.ts, 0, 3)) + + return super[symbol](); +>super : Symbol(Foo, Decl(superSymbolIndexedAccess5.ts, 0, 16)) +>symbol : Symbol(symbol, Decl(superSymbolIndexedAccess5.ts, 0, 3)) + } +} diff --git a/tests/baselines/reference/superSymbolIndexedAccess5.types b/tests/baselines/reference/superSymbolIndexedAccess5.types new file mode 100644 index 00000000000..abc3ba364b0 --- /dev/null +++ b/tests/baselines/reference/superSymbolIndexedAccess5.types @@ -0,0 +1,29 @@ +=== tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess5.ts === +var symbol: any; +>symbol : any + +class Foo { +>Foo : Foo + + [symbol]() { +>symbol : any + + return 0; +>0 : number + } +} + +class Bar extends Foo { +>Bar : Bar +>Foo : Foo + + [symbol]() { +>symbol : any + + return super[symbol](); +>super[symbol]() : any +>super[symbol] : any +>super : Foo +>symbol : any + } +} diff --git a/tests/baselines/reference/superSymbolIndexedAccess6.js b/tests/baselines/reference/superSymbolIndexedAccess6.js new file mode 100644 index 00000000000..e014cf47c1a --- /dev/null +++ b/tests/baselines/reference/superSymbolIndexedAccess6.js @@ -0,0 +1,40 @@ +//// [superSymbolIndexedAccess6.ts] +var symbol: any; + +class Foo { + static [symbol]() { + return 0; + } +} + +class Bar extends Foo { + static [symbol]() { + return super[symbol](); + } +} + +//// [superSymbolIndexedAccess6.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var symbol; +var Foo = (function () { + function Foo() { + } + Foo[symbol] = function () { + return 0; + }; + return Foo; +})(); +var Bar = (function (_super) { + __extends(Bar, _super); + function Bar() { + _super.apply(this, arguments); + } + Bar[symbol] = function () { + return _super[symbol](); + }; + return Bar; +})(Foo); diff --git a/tests/baselines/reference/superSymbolIndexedAccess6.symbols b/tests/baselines/reference/superSymbolIndexedAccess6.symbols new file mode 100644 index 00000000000..a79a6552674 --- /dev/null +++ b/tests/baselines/reference/superSymbolIndexedAccess6.symbols @@ -0,0 +1,26 @@ +=== tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess6.ts === +var symbol: any; +>symbol : Symbol(symbol, Decl(superSymbolIndexedAccess6.ts, 0, 3)) + +class Foo { +>Foo : Symbol(Foo, Decl(superSymbolIndexedAccess6.ts, 0, 16)) + + static [symbol]() { +>symbol : Symbol(symbol, Decl(superSymbolIndexedAccess6.ts, 0, 3)) + + return 0; + } +} + +class Bar extends Foo { +>Bar : Symbol(Bar, Decl(superSymbolIndexedAccess6.ts, 6, 1)) +>Foo : Symbol(Foo, Decl(superSymbolIndexedAccess6.ts, 0, 16)) + + static [symbol]() { +>symbol : Symbol(symbol, Decl(superSymbolIndexedAccess6.ts, 0, 3)) + + return super[symbol](); +>super : Symbol(Foo, Decl(superSymbolIndexedAccess6.ts, 0, 16)) +>symbol : Symbol(symbol, Decl(superSymbolIndexedAccess6.ts, 0, 3)) + } +} diff --git a/tests/baselines/reference/superSymbolIndexedAccess6.types b/tests/baselines/reference/superSymbolIndexedAccess6.types new file mode 100644 index 00000000000..830ade0c685 --- /dev/null +++ b/tests/baselines/reference/superSymbolIndexedAccess6.types @@ -0,0 +1,29 @@ +=== tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess6.ts === +var symbol: any; +>symbol : any + +class Foo { +>Foo : Foo + + static [symbol]() { +>symbol : any + + return 0; +>0 : number + } +} + +class Bar extends Foo { +>Bar : Bar +>Foo : Foo + + static [symbol]() { +>symbol : any + + return super[symbol](); +>super[symbol]() : any +>super[symbol] : any +>super : typeof Foo +>symbol : any + } +} diff --git a/tests/baselines/reference/systemModule13.symbols b/tests/baselines/reference/systemModule13.symbols index d9e64335c2b..8245029e006 100644 --- a/tests/baselines/reference/systemModule13.symbols +++ b/tests/baselines/reference/systemModule13.symbols @@ -6,7 +6,10 @@ export let [x,y,z] = [1, 2, 3]; >z : Symbol(z, Decl(systemModule13.ts, 1, 16)) export const {a: z0, b: {c: z1}} = {a: true, b: {c: "123"}}; +>a : Symbol(a, Decl(systemModule13.ts, 2, 36)) >z0 : Symbol(z0, Decl(systemModule13.ts, 2, 14)) +>b : Symbol(b, Decl(systemModule13.ts, 2, 44)) +>c : Symbol(c, Decl(systemModule13.ts, 2, 49)) >z1 : Symbol(z1, Decl(systemModule13.ts, 2, 25)) >a : Symbol(a, Decl(systemModule13.ts, 2, 36)) >b : Symbol(b, Decl(systemModule13.ts, 2, 44)) diff --git a/tests/baselines/reference/systemModule8.symbols b/tests/baselines/reference/systemModule8.symbols index 3365ce7e37d..719d48e4592 100644 --- a/tests/baselines/reference/systemModule8.symbols +++ b/tests/baselines/reference/systemModule8.symbols @@ -78,7 +78,10 @@ export let [y] = [1]; >y : Symbol(y, Decl(systemModule8.ts, 27, 12)) export const {a: z0, b: {c: z1}} = {a: true, b: {c: "123"}}; +>a : Symbol(a, Decl(systemModule8.ts, 28, 36)) >z0 : Symbol(z0, Decl(systemModule8.ts, 28, 14)) +>b : Symbol(b, Decl(systemModule8.ts, 28, 44)) +>c : Symbol(c, Decl(systemModule8.ts, 28, 49)) >z1 : Symbol(z1, Decl(systemModule8.ts, 28, 25)) >a : Symbol(a, Decl(systemModule8.ts, 28, 36)) >b : Symbol(b, Decl(systemModule8.ts, 28, 44)) diff --git a/tests/baselines/reference/typeArgumentInferenceApparentType1.js b/tests/baselines/reference/typeArgumentInferenceApparentType1.js new file mode 100644 index 00000000000..7a4f1ea19f5 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceApparentType1.js @@ -0,0 +1,12 @@ +//// [typeArgumentInferenceApparentType1.ts] +function method(iterable: Iterable): T { + return; +} + +var res: string = method("test"); + +//// [typeArgumentInferenceApparentType1.js] +function method(iterable) { + return; +} +var res = method("test"); diff --git a/tests/baselines/reference/typeArgumentInferenceApparentType1.symbols b/tests/baselines/reference/typeArgumentInferenceApparentType1.symbols new file mode 100644 index 00000000000..abcb8fdfc68 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceApparentType1.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/typeArgumentInferenceApparentType1.ts === +function method(iterable: Iterable): T { +>method : Symbol(method, Decl(typeArgumentInferenceApparentType1.ts, 0, 0)) +>T : Symbol(T, Decl(typeArgumentInferenceApparentType1.ts, 0, 16)) +>iterable : Symbol(iterable, Decl(typeArgumentInferenceApparentType1.ts, 0, 19)) +>Iterable : Symbol(Iterable, Decl(lib.d.ts, 1681, 1)) +>T : Symbol(T, Decl(typeArgumentInferenceApparentType1.ts, 0, 16)) +>T : Symbol(T, Decl(typeArgumentInferenceApparentType1.ts, 0, 16)) + + return; +} + +var res: string = method("test"); +>res : Symbol(res, Decl(typeArgumentInferenceApparentType1.ts, 4, 3)) +>method : Symbol(method, Decl(typeArgumentInferenceApparentType1.ts, 0, 0)) + diff --git a/tests/baselines/reference/typeArgumentInferenceApparentType1.types b/tests/baselines/reference/typeArgumentInferenceApparentType1.types new file mode 100644 index 00000000000..29fd1aeca18 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceApparentType1.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/typeArgumentInferenceApparentType1.ts === +function method(iterable: Iterable): T { +>method : (iterable: Iterable) => T +>T : T +>iterable : Iterable +>Iterable : Iterable +>T : T +>T : T + + return; +} + +var res: string = method("test"); +>res : string +>method("test") : string +>method : (iterable: Iterable) => T +>"test" : string + diff --git a/tests/baselines/reference/typeArgumentInferenceApparentType2.js b/tests/baselines/reference/typeArgumentInferenceApparentType2.js new file mode 100644 index 00000000000..cf9f3bca00e --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceApparentType2.js @@ -0,0 +1,17 @@ +//// [typeArgumentInferenceApparentType2.ts] +function method(iterable: Iterable): T { + function inner>() { + var u: U; + var res: T = method(u); + } + return; +} + +//// [typeArgumentInferenceApparentType2.js] +function method(iterable) { + function inner() { + var u; + var res = method(u); + } + return; +} diff --git a/tests/baselines/reference/typeArgumentInferenceApparentType2.symbols b/tests/baselines/reference/typeArgumentInferenceApparentType2.symbols new file mode 100644 index 00000000000..86cf8e7cdcd --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceApparentType2.symbols @@ -0,0 +1,27 @@ +=== tests/cases/compiler/typeArgumentInferenceApparentType2.ts === +function method(iterable: Iterable): T { +>method : Symbol(method, Decl(typeArgumentInferenceApparentType2.ts, 0, 0)) +>T : Symbol(T, Decl(typeArgumentInferenceApparentType2.ts, 0, 16)) +>iterable : Symbol(iterable, Decl(typeArgumentInferenceApparentType2.ts, 0, 19)) +>Iterable : Symbol(Iterable, Decl(lib.d.ts, 1681, 1)) +>T : Symbol(T, Decl(typeArgumentInferenceApparentType2.ts, 0, 16)) +>T : Symbol(T, Decl(typeArgumentInferenceApparentType2.ts, 0, 16)) + + function inner>() { +>inner : Symbol(inner, Decl(typeArgumentInferenceApparentType2.ts, 0, 46)) +>U : Symbol(U, Decl(typeArgumentInferenceApparentType2.ts, 1, 19)) +>Iterable : Symbol(Iterable, Decl(lib.d.ts, 1681, 1)) +>T : Symbol(T, Decl(typeArgumentInferenceApparentType2.ts, 0, 16)) + + var u: U; +>u : Symbol(u, Decl(typeArgumentInferenceApparentType2.ts, 2, 11)) +>U : Symbol(U, Decl(typeArgumentInferenceApparentType2.ts, 1, 19)) + + var res: T = method(u); +>res : Symbol(res, Decl(typeArgumentInferenceApparentType2.ts, 3, 11)) +>T : Symbol(T, Decl(typeArgumentInferenceApparentType2.ts, 0, 16)) +>method : Symbol(method, Decl(typeArgumentInferenceApparentType2.ts, 0, 0)) +>u : Symbol(u, Decl(typeArgumentInferenceApparentType2.ts, 2, 11)) + } + return; +} diff --git a/tests/baselines/reference/typeArgumentInferenceApparentType2.types b/tests/baselines/reference/typeArgumentInferenceApparentType2.types new file mode 100644 index 00000000000..6a0e6ae6454 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceApparentType2.types @@ -0,0 +1,28 @@ +=== tests/cases/compiler/typeArgumentInferenceApparentType2.ts === +function method(iterable: Iterable): T { +>method : (iterable: Iterable) => T +>T : T +>iterable : Iterable +>Iterable : Iterable +>T : T +>T : T + + function inner>() { +>inner : >() => void +>U : U +>Iterable : Iterable +>T : T + + var u: U; +>u : U +>U : U + + var res: T = method(u); +>res : T +>T : T +>method(u) : T +>method : (iterable: Iterable) => T +>u : U + } + return; +} diff --git a/tests/baselines/reference/unclosedExportClause01.errors.txt b/tests/baselines/reference/unclosedExportClause01.errors.txt new file mode 100644 index 00000000000..6590bc5cfed --- /dev/null +++ b/tests/baselines/reference/unclosedExportClause01.errors.txt @@ -0,0 +1,44 @@ +tests/cases/compiler/t2.ts(1,13): error TS2305: Module '"tests/cases/compiler/t1"' has no exported member 'from'. +tests/cases/compiler/t2.ts(1,18): error TS1005: ',' expected. +tests/cases/compiler/t3.ts(1,10): error TS2305: Module '"tests/cases/compiler/t1"' has no exported member 'from'. +tests/cases/compiler/t3.ts(1,15): error TS1005: ',' expected. +tests/cases/compiler/t4.ts(1,17): error TS1005: ',' expected. +tests/cases/compiler/t4.ts(1,17): error TS2305: Module '"tests/cases/compiler/t1"' has no exported member 'from'. +tests/cases/compiler/t4.ts(1,22): error TS1005: ',' expected. +tests/cases/compiler/t5.ts(1,18): error TS2305: Module '"tests/cases/compiler/t1"' has no exported member 'from'. +tests/cases/compiler/t5.ts(1,23): error TS1005: ',' expected. + + +==== tests/cases/compiler/t1.ts (0 errors) ==== + + export var x = "x"; + +==== tests/cases/compiler/t2.ts (2 errors) ==== + export { x, from "./t1" + ~~~~ +!!! error TS2305: Module '"tests/cases/compiler/t1"' has no exported member 'from'. + ~~~~~~ +!!! error TS1005: ',' expected. + +==== tests/cases/compiler/t3.ts (2 errors) ==== + export { from "./t1" + ~~~~ +!!! error TS2305: Module '"tests/cases/compiler/t1"' has no exported member 'from'. + ~~~~~~ +!!! error TS1005: ',' expected. + +==== tests/cases/compiler/t4.ts (3 errors) ==== + export { x as a from "./t1" + ~~~~ +!!! error TS1005: ',' expected. + ~~~~ +!!! error TS2305: Module '"tests/cases/compiler/t1"' has no exported member 'from'. + ~~~~~~ +!!! error TS1005: ',' expected. + +==== tests/cases/compiler/t5.ts (2 errors) ==== + export { x as a, from "./t1" + ~~~~ +!!! error TS2305: Module '"tests/cases/compiler/t1"' has no exported member 'from'. + ~~~~~~ +!!! error TS1005: ',' expected. \ No newline at end of file diff --git a/tests/baselines/reference/unclosedExportClause01.js b/tests/baselines/reference/unclosedExportClause01.js new file mode 100644 index 00000000000..a683f8d987d --- /dev/null +++ b/tests/baselines/reference/unclosedExportClause01.js @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/unclosedExportClause01.ts] //// + +//// [t1.ts] + +export var x = "x"; + +//// [t2.ts] +export { x, from "./t1" + +//// [t3.ts] +export { from "./t1" + +//// [t4.ts] +export { x as a from "./t1" + +//// [t5.ts] +export { x as a, from "./t1" + +//// [t1.js] +exports.x = "x"; +//// [t2.js] +var t1_1 = require("./t1"); +exports.x = t1_1.x; +//// [t3.js] +//// [t4.js] +var t1_1 = require("./t1"); +exports.a = t1_1.x; +//// [t5.js] +var t1_1 = require("./t1"); +exports.a = t1_1.x; diff --git a/tests/baselines/reference/unclosedExportClause02.errors.txt b/tests/baselines/reference/unclosedExportClause02.errors.txt new file mode 100644 index 00000000000..a4809e2c0c3 --- /dev/null +++ b/tests/baselines/reference/unclosedExportClause02.errors.txt @@ -0,0 +1,57 @@ +tests/cases/compiler/t2.ts(1,10): error TS2304: Cannot find name 'x'. +tests/cases/compiler/t2.ts(1,13): error TS2304: Cannot find name 'from'. +tests/cases/compiler/t2.ts(2,5): error TS1005: ',' expected. +tests/cases/compiler/t3.ts(1,10): error TS2304: Cannot find name 'from'. +tests/cases/compiler/t3.ts(2,5): error TS1005: ',' expected. +tests/cases/compiler/t4.ts(1,10): error TS2304: Cannot find name 'x'. +tests/cases/compiler/t4.ts(1,17): error TS1005: ',' expected. +tests/cases/compiler/t4.ts(1,17): error TS2304: Cannot find name 'from'. +tests/cases/compiler/t4.ts(2,5): error TS1005: ',' expected. +tests/cases/compiler/t5.ts(1,10): error TS2304: Cannot find name 'x'. +tests/cases/compiler/t5.ts(1,18): error TS2304: Cannot find name 'from'. +tests/cases/compiler/t5.ts(2,5): error TS1005: ',' expected. + + +==== tests/cases/compiler/t1.ts (0 errors) ==== + + export var x = "x"; + +==== tests/cases/compiler/t2.ts (3 errors) ==== + export { x, from + ~ +!!! error TS2304: Cannot find name 'x'. + ~~~~ +!!! error TS2304: Cannot find name 'from'. + "./t1"; + ~~~~~~ +!!! error TS1005: ',' expected. + +==== tests/cases/compiler/t3.ts (2 errors) ==== + export { from + ~~~~ +!!! error TS2304: Cannot find name 'from'. + "./t1"; + ~~~~~~ +!!! error TS1005: ',' expected. + +==== tests/cases/compiler/t4.ts (4 errors) ==== + export { x as a from + ~ +!!! error TS2304: Cannot find name 'x'. + ~~~~ +!!! error TS1005: ',' expected. + ~~~~ +!!! error TS2304: Cannot find name 'from'. + "./t1"; + ~~~~~~ +!!! error TS1005: ',' expected. + +==== tests/cases/compiler/t5.ts (3 errors) ==== + export { x as a, from + ~ +!!! error TS2304: Cannot find name 'x'. + ~~~~ +!!! error TS2304: Cannot find name 'from'. + "./t1"; + ~~~~~~ +!!! error TS1005: ',' expected. \ No newline at end of file diff --git a/tests/baselines/reference/unclosedExportClause02.js b/tests/baselines/reference/unclosedExportClause02.js new file mode 100644 index 00000000000..964cc29899c --- /dev/null +++ b/tests/baselines/reference/unclosedExportClause02.js @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/unclosedExportClause02.ts] //// + +//// [t1.ts] + +export var x = "x"; + +//// [t2.ts] +export { x, from + "./t1"; + +//// [t3.ts] +export { from + "./t1"; + +//// [t4.ts] +export { x as a from + "./t1"; + +//// [t5.ts] +export { x as a, from + "./t1"; + +//// [t1.js] +exports.x = "x"; +//// [t2.js] +"./t1"; +//// [t3.js] +"./t1"; +//// [t4.js] +"./t1"; +//// [t5.js] +"./t1"; diff --git a/tests/baselines/reference/wideningTuples1.js b/tests/baselines/reference/wideningTuples1.js new file mode 100644 index 00000000000..ed39a735bfe --- /dev/null +++ b/tests/baselines/reference/wideningTuples1.js @@ -0,0 +1,9 @@ +//// [wideningTuples1.ts] +declare function foo(x: T): T; + +var y = foo([undefined]); +y = [""]; + +//// [wideningTuples1.js] +var y = foo([undefined]); +y = [""]; diff --git a/tests/baselines/reference/wideningTuples1.symbols b/tests/baselines/reference/wideningTuples1.symbols new file mode 100644 index 00000000000..819510b7319 --- /dev/null +++ b/tests/baselines/reference/wideningTuples1.symbols @@ -0,0 +1,16 @@ +=== tests/cases/conformance/types/tuple/wideningTuples1.ts === +declare function foo(x: T): T; +>foo : Symbol(foo, Decl(wideningTuples1.ts, 0, 0)) +>T : Symbol(T, Decl(wideningTuples1.ts, 0, 21)) +>x : Symbol(x, Decl(wideningTuples1.ts, 0, 38)) +>T : Symbol(T, Decl(wideningTuples1.ts, 0, 21)) +>T : Symbol(T, Decl(wideningTuples1.ts, 0, 21)) + +var y = foo([undefined]); +>y : Symbol(y, Decl(wideningTuples1.ts, 2, 3)) +>foo : Symbol(foo, Decl(wideningTuples1.ts, 0, 0)) +>undefined : Symbol(undefined) + +y = [""]; +>y : Symbol(y, Decl(wideningTuples1.ts, 2, 3)) + diff --git a/tests/baselines/reference/wideningTuples1.types b/tests/baselines/reference/wideningTuples1.types new file mode 100644 index 00000000000..1fdd4a6cb53 --- /dev/null +++ b/tests/baselines/reference/wideningTuples1.types @@ -0,0 +1,21 @@ +=== tests/cases/conformance/types/tuple/wideningTuples1.ts === +declare function foo(x: T): T; +>foo : (x: T) => T +>T : T +>x : T +>T : T +>T : T + +var y = foo([undefined]); +>y : [any] +>foo([undefined]) : [any] +>foo : (x: T) => T +>[undefined] : [undefined] +>undefined : undefined + +y = [""]; +>y = [""] : [string] +>y : [any] +>[""] : [string] +>"" : string + diff --git a/tests/baselines/reference/wideningTuples2.js b/tests/baselines/reference/wideningTuples2.js new file mode 100644 index 00000000000..fa74e089961 --- /dev/null +++ b/tests/baselines/reference/wideningTuples2.js @@ -0,0 +1,13 @@ +//// [wideningTuples2.ts] +var foo: () => [any] = function bar() { + let intermediate = bar(); + intermediate = [""]; + return [undefined]; +}; + +//// [wideningTuples2.js] +var foo = function bar() { + var intermediate = bar(); + intermediate = [""]; + return [undefined]; +}; diff --git a/tests/baselines/reference/wideningTuples2.symbols b/tests/baselines/reference/wideningTuples2.symbols new file mode 100644 index 00000000000..74186045e90 --- /dev/null +++ b/tests/baselines/reference/wideningTuples2.symbols @@ -0,0 +1,16 @@ +=== tests/cases/conformance/types/tuple/wideningTuples2.ts === +var foo: () => [any] = function bar() { +>foo : Symbol(foo, Decl(wideningTuples2.ts, 0, 3)) +>bar : Symbol(bar, Decl(wideningTuples2.ts, 0, 22)) + + let intermediate = bar(); +>intermediate : Symbol(intermediate, Decl(wideningTuples2.ts, 1, 7)) +>bar : Symbol(bar, Decl(wideningTuples2.ts, 0, 22)) + + intermediate = [""]; +>intermediate : Symbol(intermediate, Decl(wideningTuples2.ts, 1, 7)) + + return [undefined]; +>undefined : Symbol(undefined) + +}; diff --git a/tests/baselines/reference/wideningTuples2.types b/tests/baselines/reference/wideningTuples2.types new file mode 100644 index 00000000000..c07166c53f0 --- /dev/null +++ b/tests/baselines/reference/wideningTuples2.types @@ -0,0 +1,22 @@ +=== tests/cases/conformance/types/tuple/wideningTuples2.ts === +var foo: () => [any] = function bar() { +>foo : () => [any] +>function bar() { let intermediate = bar(); intermediate = [""]; return [undefined];} : () => [any] +>bar : () => [any] + + let intermediate = bar(); +>intermediate : [any] +>bar() : [any] +>bar : () => [any] + + intermediate = [""]; +>intermediate = [""] : [string] +>intermediate : [any] +>[""] : [string] +>"" : string + + return [undefined]; +>[undefined] : [undefined] +>undefined : undefined + +}; diff --git a/tests/baselines/reference/wideningTuples3.errors.txt b/tests/baselines/reference/wideningTuples3.errors.txt new file mode 100644 index 00000000000..43c7e349a0c --- /dev/null +++ b/tests/baselines/reference/wideningTuples3.errors.txt @@ -0,0 +1,9 @@ +tests/cases/conformance/types/tuple/wideningTuples3.ts(3,5): error TS7005: Variable 'b' implicitly has an '[any, any]' type. + + +==== tests/cases/conformance/types/tuple/wideningTuples3.ts (1 errors) ==== + var a: [any]; + + var b = a = [undefined, null]; + ~ +!!! error TS7005: Variable 'b' implicitly has an '[any, any]' type. \ No newline at end of file diff --git a/tests/baselines/reference/wideningTuples3.js b/tests/baselines/reference/wideningTuples3.js new file mode 100644 index 00000000000..dfeaae745d4 --- /dev/null +++ b/tests/baselines/reference/wideningTuples3.js @@ -0,0 +1,8 @@ +//// [wideningTuples3.ts] +var a: [any]; + +var b = a = [undefined, null]; + +//// [wideningTuples3.js] +var a; +var b = a = [undefined, null]; diff --git a/tests/baselines/reference/wideningTuples4.js b/tests/baselines/reference/wideningTuples4.js new file mode 100644 index 00000000000..b4d16a3058b --- /dev/null +++ b/tests/baselines/reference/wideningTuples4.js @@ -0,0 +1,10 @@ +//// [wideningTuples4.ts] +var a: [any]; + +var b = a = [undefined, null]; +b = ["", ""]; + +//// [wideningTuples4.js] +var a; +var b = a = [undefined, null]; +b = ["", ""]; diff --git a/tests/baselines/reference/wideningTuples4.symbols b/tests/baselines/reference/wideningTuples4.symbols new file mode 100644 index 00000000000..95e7cc3cff8 --- /dev/null +++ b/tests/baselines/reference/wideningTuples4.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/types/tuple/wideningTuples4.ts === +var a: [any]; +>a : Symbol(a, Decl(wideningTuples4.ts, 0, 3)) + +var b = a = [undefined, null]; +>b : Symbol(b, Decl(wideningTuples4.ts, 2, 3)) +>a : Symbol(a, Decl(wideningTuples4.ts, 0, 3)) +>undefined : Symbol(undefined) + +b = ["", ""]; +>b : Symbol(b, Decl(wideningTuples4.ts, 2, 3)) + diff --git a/tests/baselines/reference/wideningTuples4.types b/tests/baselines/reference/wideningTuples4.types new file mode 100644 index 00000000000..6d101dd1e01 --- /dev/null +++ b/tests/baselines/reference/wideningTuples4.types @@ -0,0 +1,19 @@ +=== tests/cases/conformance/types/tuple/wideningTuples4.ts === +var a: [any]; +>a : [any] + +var b = a = [undefined, null]; +>b : [any, any] +>a = [undefined, null] : [undefined, null] +>a : [any] +>[undefined, null] : [undefined, null] +>undefined : undefined +>null : null + +b = ["", ""]; +>b = ["", ""] : [string, string] +>b : [any, any] +>["", ""] : [string, string] +>"" : string +>"" : string + diff --git a/tests/baselines/reference/wideningTuples5.errors.txt b/tests/baselines/reference/wideningTuples5.errors.txt new file mode 100644 index 00000000000..bfd72079f55 --- /dev/null +++ b/tests/baselines/reference/wideningTuples5.errors.txt @@ -0,0 +1,10 @@ +tests/cases/conformance/types/tuple/wideningTuples5.ts(1,6): error TS7005: Variable 'a' implicitly has an 'any' type. +tests/cases/conformance/types/tuple/wideningTuples5.ts(1,9): error TS7005: Variable 'b' implicitly has an 'any' type. + + +==== tests/cases/conformance/types/tuple/wideningTuples5.ts (2 errors) ==== + var [a, b] = [undefined, null]; + ~ +!!! error TS7005: Variable 'a' implicitly has an 'any' type. + ~ +!!! error TS7005: Variable 'b' implicitly has an 'any' type. \ No newline at end of file diff --git a/tests/baselines/reference/wideningTuples5.js b/tests/baselines/reference/wideningTuples5.js new file mode 100644 index 00000000000..5763fb3340f --- /dev/null +++ b/tests/baselines/reference/wideningTuples5.js @@ -0,0 +1,5 @@ +//// [wideningTuples5.ts] +var [a, b] = [undefined, null]; + +//// [wideningTuples5.js] +var _a = [undefined, null], a = _a[0], b = _a[1]; diff --git a/tests/baselines/reference/wideningTuples6.js b/tests/baselines/reference/wideningTuples6.js new file mode 100644 index 00000000000..b1d5e8ec0bd --- /dev/null +++ b/tests/baselines/reference/wideningTuples6.js @@ -0,0 +1,9 @@ +//// [wideningTuples6.ts] +var [a, b] = [undefined, null]; +a = ""; +b = ""; + +//// [wideningTuples6.js] +var _a = [undefined, null], a = _a[0], b = _a[1]; +a = ""; +b = ""; diff --git a/tests/baselines/reference/wideningTuples6.symbols b/tests/baselines/reference/wideningTuples6.symbols new file mode 100644 index 00000000000..88de6a7b9b7 --- /dev/null +++ b/tests/baselines/reference/wideningTuples6.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/types/tuple/wideningTuples6.ts === +var [a, b] = [undefined, null]; +>a : Symbol(a, Decl(wideningTuples6.ts, 0, 5)) +>b : Symbol(b, Decl(wideningTuples6.ts, 0, 7)) +>undefined : Symbol(undefined) + +a = ""; +>a : Symbol(a, Decl(wideningTuples6.ts, 0, 5)) + +b = ""; +>b : Symbol(b, Decl(wideningTuples6.ts, 0, 7)) + diff --git a/tests/baselines/reference/wideningTuples6.types b/tests/baselines/reference/wideningTuples6.types new file mode 100644 index 00000000000..d75c0b49e9e --- /dev/null +++ b/tests/baselines/reference/wideningTuples6.types @@ -0,0 +1,18 @@ +=== tests/cases/conformance/types/tuple/wideningTuples6.ts === +var [a, b] = [undefined, null]; +>a : any +>b : any +>[undefined, null] : [undefined, null] +>undefined : undefined +>null : null + +a = ""; +>a = "" : string +>a : any +>"" : string + +b = ""; +>b = "" : string +>b : any +>"" : string + diff --git a/tests/baselines/reference/wideningTuples7.errors.txt b/tests/baselines/reference/wideningTuples7.errors.txt new file mode 100644 index 00000000000..25fd1f58e64 --- /dev/null +++ b/tests/baselines/reference/wideningTuples7.errors.txt @@ -0,0 +1,10 @@ +tests/cases/conformance/types/tuple/wideningTuples7.ts(1,20): error TS7010: 'bar', which lacks return-type annotation, implicitly has an '[any]' return type. + + +==== tests/cases/conformance/types/tuple/wideningTuples7.ts (1 errors) ==== + var foo = function bar() { + ~~~ +!!! error TS7010: 'bar', which lacks return-type annotation, implicitly has an '[any]' return type. + let intermediate: [string]; + return intermediate = [undefined]; + }; \ No newline at end of file diff --git a/tests/baselines/reference/wideningTuples7.js b/tests/baselines/reference/wideningTuples7.js new file mode 100644 index 00000000000..4d94a1909ad --- /dev/null +++ b/tests/baselines/reference/wideningTuples7.js @@ -0,0 +1,11 @@ +//// [wideningTuples7.ts] +var foo = function bar() { + let intermediate: [string]; + return intermediate = [undefined]; +}; + +//// [wideningTuples7.js] +var foo = function bar() { + var intermediate; + return intermediate = [undefined]; +}; diff --git a/tests/cases/compiler/exportDeclarationWithModuleSpecifierNameOnNextLine1.ts b/tests/cases/compiler/exportDeclarationWithModuleSpecifierNameOnNextLine1.ts new file mode 100644 index 00000000000..ea3f55db16b --- /dev/null +++ b/tests/cases/compiler/exportDeclarationWithModuleSpecifierNameOnNextLine1.ts @@ -0,0 +1,20 @@ +// @module: commonjs + +// @filename: t1.ts +export var x = "x"; + +// @filename: t2.ts +export { x } from + "./t1"; + +// @filename: t3.ts +export { } from + "./t1"; + +// @filename: t4.ts +export { x as a } from + "./t1"; + +// @filename: t5.ts +export { x as a, } from + "./t1"; \ No newline at end of file diff --git a/tests/cases/compiler/typeArgumentInferenceApparentType1.ts b/tests/cases/compiler/typeArgumentInferenceApparentType1.ts new file mode 100644 index 00000000000..4cc4a0dd4e5 --- /dev/null +++ b/tests/cases/compiler/typeArgumentInferenceApparentType1.ts @@ -0,0 +1,6 @@ +//@target: ES6 +function method(iterable: Iterable): T { + return; +} + +var res: string = method("test"); \ No newline at end of file diff --git a/tests/cases/compiler/typeArgumentInferenceApparentType2.ts b/tests/cases/compiler/typeArgumentInferenceApparentType2.ts new file mode 100644 index 00000000000..88ae4df8c4c --- /dev/null +++ b/tests/cases/compiler/typeArgumentInferenceApparentType2.ts @@ -0,0 +1,8 @@ +//@target: ES6 +function method(iterable: Iterable): T { + function inner>() { + var u: U; + var res: T = method(u); + } + return; +} \ No newline at end of file diff --git a/tests/cases/compiler/unclosedExportClause01.ts b/tests/cases/compiler/unclosedExportClause01.ts new file mode 100644 index 00000000000..3bcbc713d61 --- /dev/null +++ b/tests/cases/compiler/unclosedExportClause01.ts @@ -0,0 +1,16 @@ +// @module: commonjs + +// @filename: t1.ts +export var x = "x"; + +// @filename: t2.ts +export { x, from "./t1" + +// @filename: t3.ts +export { from "./t1" + +// @filename: t4.ts +export { x as a from "./t1" + +// @filename: t5.ts +export { x as a, from "./t1" \ No newline at end of file diff --git a/tests/cases/compiler/unclosedExportClause02.ts b/tests/cases/compiler/unclosedExportClause02.ts new file mode 100644 index 00000000000..45dcb65a4cb --- /dev/null +++ b/tests/cases/compiler/unclosedExportClause02.ts @@ -0,0 +1,20 @@ +// @module: commonjs + +// @filename: t1.ts +export var x = "x"; + +// @filename: t2.ts +export { x, from + "./t1"; + +// @filename: t3.ts +export { from + "./t1"; + +// @filename: t4.ts +export { x as a from + "./t1"; + +// @filename: t5.ts +export { x as a, from + "./t1"; \ No newline at end of file diff --git a/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess1.ts b/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess1.ts new file mode 100644 index 00000000000..160a76f5c61 --- /dev/null +++ b/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess1.ts @@ -0,0 +1,14 @@ +//@target: ES6 +var symbol = Symbol.for('myThing'); + +class Foo { + [symbol]() { + return 0; + } +} + +class Bar extends Foo { + [symbol]() { + return super[symbol](); + } +} \ No newline at end of file diff --git a/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess2.ts b/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess2.ts new file mode 100644 index 00000000000..3f399d41629 --- /dev/null +++ b/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess2.ts @@ -0,0 +1,13 @@ +//@target: ES6 + +class Foo { + [Symbol.isConcatSpreadable]() { + return 0; + } +} + +class Bar extends Foo { + [Symbol.isConcatSpreadable]() { + return super[Symbol.isConcatSpreadable](); + } +} \ No newline at end of file diff --git a/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess3.ts b/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess3.ts new file mode 100644 index 00000000000..2fbbbdc63e6 --- /dev/null +++ b/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess3.ts @@ -0,0 +1,14 @@ +//@target: ES6 +var symbol = Symbol.for('myThing'); + +class Foo { + [symbol]() { + return 0; + } +} + +class Bar extends Foo { + [symbol]() { + return super[Bar](); + } +} \ No newline at end of file diff --git a/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess4.ts b/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess4.ts new file mode 100644 index 00000000000..095fcc1dbb7 --- /dev/null +++ b/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess4.ts @@ -0,0 +1,8 @@ +//@target: ES6 +var symbol = Symbol.for('myThing'); + +class Bar { + [symbol]() { + return super[symbol](); + } +} \ No newline at end of file diff --git a/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess5.ts b/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess5.ts new file mode 100644 index 00000000000..3c1a376eab6 --- /dev/null +++ b/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess5.ts @@ -0,0 +1,14 @@ +//@target: ES5 +var symbol: any; + +class Foo { + [symbol]() { + return 0; + } +} + +class Bar extends Foo { + [symbol]() { + return super[symbol](); + } +} \ No newline at end of file diff --git a/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess6.ts b/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess6.ts new file mode 100644 index 00000000000..3850821e9f3 --- /dev/null +++ b/tests/cases/conformance/expressions/superPropertyAccess/superSymbolIndexedAccess6.ts @@ -0,0 +1,14 @@ +//@target: ES5 +var symbol: any; + +class Foo { + static [symbol]() { + return 0; + } +} + +class Bar extends Foo { + static [symbol]() { + return super[symbol](); + } +} \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/wideningTuples1.ts b/tests/cases/conformance/types/tuple/wideningTuples1.ts new file mode 100644 index 00000000000..f4885435dcf --- /dev/null +++ b/tests/cases/conformance/types/tuple/wideningTuples1.ts @@ -0,0 +1,5 @@ +//@noImplicitAny: true +declare function foo(x: T): T; + +var y = foo([undefined]); +y = [""]; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/wideningTuples2.ts b/tests/cases/conformance/types/tuple/wideningTuples2.ts new file mode 100644 index 00000000000..d8bf1248546 --- /dev/null +++ b/tests/cases/conformance/types/tuple/wideningTuples2.ts @@ -0,0 +1,6 @@ +//@noImplicitAny: true +var foo: () => [any] = function bar() { + let intermediate = bar(); + intermediate = [""]; + return [undefined]; +}; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/wideningTuples3.ts b/tests/cases/conformance/types/tuple/wideningTuples3.ts new file mode 100644 index 00000000000..a6837be2a0f --- /dev/null +++ b/tests/cases/conformance/types/tuple/wideningTuples3.ts @@ -0,0 +1,4 @@ +//@noImplicitAny: true +var a: [any]; + +var b = a = [undefined, null]; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/wideningTuples4.ts b/tests/cases/conformance/types/tuple/wideningTuples4.ts new file mode 100644 index 00000000000..550ba07f600 --- /dev/null +++ b/tests/cases/conformance/types/tuple/wideningTuples4.ts @@ -0,0 +1,4 @@ +var a: [any]; + +var b = a = [undefined, null]; +b = ["", ""]; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/wideningTuples5.ts b/tests/cases/conformance/types/tuple/wideningTuples5.ts new file mode 100644 index 00000000000..36434c6eafe --- /dev/null +++ b/tests/cases/conformance/types/tuple/wideningTuples5.ts @@ -0,0 +1,2 @@ +//@noImplicitAny: true +var [a, b] = [undefined, null]; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/wideningTuples6.ts b/tests/cases/conformance/types/tuple/wideningTuples6.ts new file mode 100644 index 00000000000..cac228ecb4d --- /dev/null +++ b/tests/cases/conformance/types/tuple/wideningTuples6.ts @@ -0,0 +1,3 @@ +var [a, b] = [undefined, null]; +a = ""; +b = ""; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/wideningTuples7.ts b/tests/cases/conformance/types/tuple/wideningTuples7.ts new file mode 100644 index 00000000000..1a4d212d362 --- /dev/null +++ b/tests/cases/conformance/types/tuple/wideningTuples7.ts @@ -0,0 +1,5 @@ +//@noImplicitAny: true +var foo = function bar() { + let intermediate: [string]; + return intermediate = [undefined]; +}; \ No newline at end of file diff --git a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_destructuring.ts b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_destructuring.ts index 0812cb138d2..7f8ef32e1ad 100644 --- a/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_destructuring.ts +++ b/tests/cases/fourslash/completionListAtIdentifierDefinitionLocations_destructuring.ts @@ -16,7 +16,7 @@ //// function func2({ a, b/*parameter2*/ -test.markers().forEach((m) => { +test.markers().forEach(m => { goTo.position(m.position, m.fileName); verify.completionListIsEmpty(); }); diff --git a/tests/cases/fourslash/completionListInExportClause01.ts b/tests/cases/fourslash/completionListInExportClause01.ts new file mode 100644 index 00000000000..12726444bd2 --- /dev/null +++ b/tests/cases/fourslash/completionListInExportClause01.ts @@ -0,0 +1,40 @@ +/// + +// @Filename: m1.ts +////export var foo: number = 1; +////export function bar() { return 10; } +////export function baz() { return 10; } + +// @Filename: m2.ts +////export {/*1*/, /*2*/ from "m1" +////export {/*3*/} from "m1" +////export {foo,/*4*/ from "m1" +////export {bar as /*5*/, /*6*/ from "m1" +////export {foo, bar, baz as b,/*7*/} from "m1" + +function verifyCompletionAtMarker(marker: string, showBuilder: boolean, ...completions: string[]) { + goTo.marker(marker); + if (completions.length) { + for (let completion of completions) { + verify.completionListContains(completion); + } + } + else { + verify.completionListIsEmpty(); + } + + if (showBuilder) { + verify.completionListAllowsNewIdentifier(); + } + else { + verify.not.completionListAllowsNewIdentifier(); + } +} + +verifyCompletionAtMarker("1", /*showBuilder*/ false, "foo", "bar", "baz"); +verifyCompletionAtMarker("2", /*showBuilder*/ false, "foo", "bar", "baz"); +verifyCompletionAtMarker("3", /*showBuilder*/ false, "foo", "bar", "baz"); +verifyCompletionAtMarker("4", /*showBuilder*/ false, "bar", "baz"); +verifyCompletionAtMarker("5", /*showBuilder*/ true); +verifyCompletionAtMarker("6", /*showBuilder*/ false, "foo", "baz"); +verifyCompletionAtMarker("7", /*showBuilder*/ false); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListInExportClause02.ts b/tests/cases/fourslash/completionListInExportClause02.ts new file mode 100644 index 00000000000..4b40976f521 --- /dev/null +++ b/tests/cases/fourslash/completionListInExportClause02.ts @@ -0,0 +1,14 @@ +/// + +////declare module "M1" { +//// export var V; +////} +////var W; +////declare module "M2" { +//// export { /**/ } from "M1" +////} + +goTo.marker(); +verify.completionListContains("V"); +verify.not.completionListContains("W"); +verify.not.completionListAllowsNewIdentifier(); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListInExportClause03.ts b/tests/cases/fourslash/completionListInExportClause03.ts new file mode 100644 index 00000000000..426c85d02ea --- /dev/null +++ b/tests/cases/fourslash/completionListInExportClause03.ts @@ -0,0 +1,16 @@ +/// + +////declare module "M1" { +//// export var abc: number; +//// export var def: string; +////} +//// +////declare module "M2" { +//// export { abc/**/ } from "M1"; +////} + +// Ensure we don't filter out the current item. +goTo.marker(); +verify.completionListContains("abc"); +verify.completionListContains("def"); +verify.not.completionListAllowsNewIdentifier(); \ No newline at end of file diff --git a/tests/cases/fourslash/completionListInImportClause01.ts b/tests/cases/fourslash/completionListInImportClause01.ts index 1191216baf1..2b679ffe550 100644 --- a/tests/cases/fourslash/completionListInImportClause01.ts +++ b/tests/cases/fourslash/completionListInImportClause01.ts @@ -11,6 +11,7 @@ ////import {foo,/*4*/ from "m1" ////import {bar as /*5*/, /*6*/ from "m1" ////import {foo, bar, baz as b,/*7*/} from "m1" + function verifyCompletionAtMarker(marker: string, showBuilder: boolean, ...completions: string[]) { goTo.marker(marker); if (completions.length) { diff --git a/tests/cases/fourslash/completionListInNamespaceImportName01.ts b/tests/cases/fourslash/completionListInNamespaceImportName01.ts new file mode 100644 index 00000000000..ac1c0e13e07 --- /dev/null +++ b/tests/cases/fourslash/completionListInNamespaceImportName01.ts @@ -0,0 +1,11 @@ +/// + +// @Filename: m1.ts +////export var foo: number = 1; + +// @Filename: m2.ts +////import * as /**/ from "m1" + +goTo.marker(); +verify.completionListIsEmpty(); +verify.completionListAllowsNewIdentifier(); \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName01.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName01.ts new file mode 100644 index 00000000000..0d03561515d --- /dev/null +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName01.ts @@ -0,0 +1,19 @@ +/// + +////interface I { +//// [|property1|]: number; +//// property2: string; +////} +//// +////var foo: I; +////var { [|property1|]: prop1 } = foo; + +let ranges = test.ranges(); +for (let range of ranges) { + goTo.position(range.start); + + verify.referencesCountIs(ranges.length); + for (let expectedRange of ranges) { + verify.referencesAtPositionContains(expectedRange); + } +} \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName02.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName02.ts new file mode 100644 index 00000000000..86514051557 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName02.ts @@ -0,0 +1,19 @@ +/// + +////interface I { +//// [|property1|]: number; +//// property2: string; +////} +//// +////var foo: I; +////var { [|property1|]: {} } = foo; + +let ranges = test.ranges(); +for (let range of ranges) { + goTo.position(range.start); + + verify.referencesCountIs(ranges.length); + for (let expectedRange of ranges) { + verify.referencesAtPositionContains(expectedRange); + } +} \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName03.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName03.ts new file mode 100644 index 00000000000..304fa9e42e9 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName03.ts @@ -0,0 +1,19 @@ +/// + +////interface I { +//// [|property1|]: number; +//// property2: string; +////} +//// +////var foo: I; +////var [{ [|property1|]: prop1 }, { property1, property2 } ] = [foo, foo]; + +let ranges = test.ranges(); +for (let range of ranges) { + goTo.position(range.start); + + verify.referencesCountIs(ranges.length); + for (let expectedRange of ranges) { + verify.referencesAtPositionContains(expectedRange); + } +} \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName04.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName04.ts new file mode 100644 index 00000000000..bdb37525f71 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName04.ts @@ -0,0 +1,23 @@ +/// + +////interface I { +//// [|property1|]: number; +//// property2: string; +////} +//// +////function f({ /**/[|property1|]: p1 }: I, +//// { /*SHOULD_BE_A_REFERENCE*/property1 }: I, +//// { property1: p2 }) { +//// +//// return property1 + 1; +////} + +// NOTE: In the future, the identifier at +// SHOULD_BE_A_REFERENCE should be in the set of ranges. +goTo.marker(); + +let ranges = test.ranges(); +verify.referencesCountIs(ranges.length); +for (let expectedRange of ranges) { + verify.referencesAtPositionContains(expectedRange); +} \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName05.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName05.ts new file mode 100644 index 00000000000..f7e3b80fe45 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName05.ts @@ -0,0 +1,13 @@ +/// + +////interface I { +//// property1: number; +//// property2: string; +////} +//// +////function f({ /**/property1: p }, { property1 }) { +//// let x = property1; +////} + +goTo.marker(); +verify.referencesCountIs(0); \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts new file mode 100644 index 00000000000..67c7029861e --- /dev/null +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts @@ -0,0 +1,30 @@ +/// + +////interface I { +//// [|property1|]: number; +//// property2: string; +////} +//// +////var elems: I[]; +////for (let { [|property1|]: p } of elems) { +////} +////for (let { property1 } of elems) { +////} +////for (var { [|property1|]: p1 } of elems) { +////} +////var p2; +////for ({ property1 : p2 } of elems) { +////} + +// Note: if this test ever changes, consider updating +// 'quickInfoForObjectBindingElementPropertyName05.ts' + +let ranges = test.ranges(); +for (let range of ranges) { + goTo.position(range.start); + + verify.referencesCountIs(ranges.length); + for (let expectedRange of ranges) { + verify.referencesAtPositionContains(expectedRange); + } +} \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts new file mode 100644 index 00000000000..6448d2396b3 --- /dev/null +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts @@ -0,0 +1,15 @@ +/// + +////let p, b; +//// +////p, [{ [|a|]: p, b }] = [{ [|a|]: 10, b: true }]; + +let ranges = test.ranges(); +for (let range of ranges) { + goTo.position(range.start); + + verify.referencesCountIs(ranges.length); + for (let expectedRange of ranges) { + verify.referencesAtPositionContains(expectedRange); + } +} \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName09.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName09.ts new file mode 100644 index 00000000000..e45359bcf1c --- /dev/null +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName09.ts @@ -0,0 +1,23 @@ +/// + +////interface I { +//// /*SHOULD_BE_A_REFERENCE1*/property1: number; +//// property2: string; +////} +//// +////function f({ /*SHOULD_BE_A_REFERENCE2*/property1: p1 }: I, +//// { /**/[|property1|] }: I, +//// { property1: p2 }) { +//// +//// return [|property1|] + 1; +////} + +// NOTE: In the future, the identifiers at +// SHOULD_BE_A_REFERENCE[1/2] should be in the set of ranges. +goTo.marker(); + +let ranges = test.ranges(); +verify.referencesCountIs(ranges.length); +for (let expectedRange of ranges) { + verify.referencesAtPositionContains(expectedRange); +} \ No newline at end of file diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName10.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName10.ts new file mode 100644 index 00000000000..7b8be1aa91c --- /dev/null +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName10.ts @@ -0,0 +1,19 @@ +/// + +////interface Recursive { +//// [|next|]?: Recursive; +//// value: any; +////} +//// +////function f ({ [|next|]: { [|next|]: x} }: Recursive) { +////} + +let ranges = test.ranges(); +for (let range of ranges) { + goTo.position(range.start); + + verify.referencesCountIs(ranges.length); + for (let expectedRange of ranges) { + verify.referencesAtPositionContains(expectedRange); + } +} \ No newline at end of file diff --git a/tests/cases/fourslash/getOccurrencesAbstract01.ts b/tests/cases/fourslash/getOccurrencesAbstract01.ts new file mode 100644 index 00000000000..3e48ba4841a --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesAbstract01.ts @@ -0,0 +1,24 @@ +/// + +////[|abstract|] class Animal { +//// [|abstract|] prop1; // Does not compile +//// [|abstract|] abstract(); +//// [|abstract|] walk(): void; +//// [|abstract|] makeSound(): void; +////} +////// Abstract class below should not get highlighted +////abstract class Foo { +//// abstract foo(): void; +//// abstract bar(): void; +////} + +const ranges = test.ranges(); + +for (let r of ranges) { + goTo.position(r.start); + verify.occurrencesAtPositionCount(ranges.length); + + for (let range of ranges) { + verify.occurrencesAtPositionContains(range, false); + } +} diff --git a/tests/cases/fourslash/getOccurrencesAbstract02.ts b/tests/cases/fourslash/getOccurrencesAbstract02.ts new file mode 100644 index 00000000000..8daafdbdc8e --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesAbstract02.ts @@ -0,0 +1,29 @@ +/// + +////// Not valid TS (abstract methods can only appear in abstract classes) +////class Animal { +//// [|abstract|] walk(): void; +//// [|abstract|] makeSound(): void; +////} +////// abstract cannot appear here, won't get highlighted +////let c = /*1*/abstract class Foo { +//// /*2*/abstract foo(): void; +//// abstract bar(): void; +////} + +const ranges = test.ranges(); + +for (let r of ranges) { + goTo.position(r.start); + verify.occurrencesAtPositionCount(ranges.length); + + for (let range of ranges) { + verify.occurrencesAtPositionContains(range, false); + } +} + +goTo.marker("1"); +verify.occurrencesAtPositionCount(0); + +goTo.marker("2"); +verify.occurrencesAtPositionCount(2); diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionConstructor.ts b/tests/cases/fourslash/getOccurrencesClassExpressionConstructor.ts new file mode 100644 index 00000000000..5fa778ef8cd --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesClassExpressionConstructor.ts @@ -0,0 +1,23 @@ +/// + +////let A = class Foo { +//// [|constructor|](); +//// [|constructor|](x: number); +//// [|constructor|](y: string); +//// [|constructor|](a?: any) { +//// } +////} +//// +////let B = class D { +//// constructor(x: number) { +//// } +////} + +const ranges = test.ranges(); +for (let r of ranges) { + goTo.position(r.start); + + for (let range of ranges) { + verify.occurrencesAtPositionContains(range, false); + } +} diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionPrivate.ts b/tests/cases/fourslash/getOccurrencesClassExpressionPrivate.ts new file mode 100644 index 00000000000..b008ec237b8 --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesClassExpressionPrivate.ts @@ -0,0 +1,27 @@ +/// + +////let A = class Foo { +//// [|private|] foo; +//// [|private|] private; +//// constructor([|private|] y: string, public x: string) { +//// } +//// [|private|] method() { } +//// public method2() { } +//// [|private|] static static() { } +////} +//// +////let B = class D { +//// constructor(private x: number) { +//// } +//// private test() {} +//// public test2() {} +////} + +const ranges = test.ranges(); +for (let r of ranges) { + goTo.position(r.start); + + for (let range of ranges) { + verify.occurrencesAtPositionContains(range, false); + } +} diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionPublic.ts b/tests/cases/fourslash/getOccurrencesClassExpressionPublic.ts new file mode 100644 index 00000000000..3070fd4f6ca --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesClassExpressionPublic.ts @@ -0,0 +1,27 @@ +/// + +////let A = class Foo { +//// [|public|] foo; +//// [|public|] public; +//// constructor([|public|] y: string, private x: string) { +//// } +//// [|public|] method() { } +//// private method2() {} +//// [|public|] static static() { } +////} +//// +////let B = class D { +//// constructor(private x: number) { +//// } +//// private test() {} +//// public test2() {} +////} + +const ranges = test.ranges(); +for (let r of ranges) { + goTo.position(r.start); + + for (let range of ranges) { + verify.occurrencesAtPositionContains(range, false); + } +} diff --git a/tests/cases/fourslash/getOccurrencesClassExpressionStatic.ts b/tests/cases/fourslash/getOccurrencesClassExpressionStatic.ts new file mode 100644 index 00000000000..567c0c4eccd --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesClassExpressionStatic.ts @@ -0,0 +1,29 @@ +/// + +////let A = class Foo { +//// public static foo; +//// [|static|] a; +//// constructor(public y: string, private x: string) { +//// } +//// public method() { } +//// private method2() {} +//// public [|static|] static() { } +//// private [|static|] static2() { } +////} +//// +////let B = class D { +//// static a; +//// constructor(private x: number) { +//// } +//// private static test() {} +//// public static test2() {} +////} + +const ranges = test.ranges(); +for (let r of ranges) { + goTo.position(r.start); + + for (let range of ranges) { + verify.occurrencesAtPositionContains(range, false); + } +} diff --git a/tests/cases/fourslash/goToDefinitionObjectBindingElementPropertyName01.ts b/tests/cases/fourslash/goToDefinitionObjectBindingElementPropertyName01.ts new file mode 100644 index 00000000000..9348ba05678 --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionObjectBindingElementPropertyName01.ts @@ -0,0 +1,14 @@ +/// + +////interface I { +//// /*def*/property1: number; +//// property2: string; +////} +//// +////var foo: I; +////var { /*use*/property1: prop1 } = foo; + +goTo.marker("use"); +verify.definitionLocationExists(); +goTo.definition(); +verify.caretAtMarker("def"); \ No newline at end of file diff --git a/tests/cases/fourslash/quickInfoForObjectBindingElementName01.ts b/tests/cases/fourslash/quickInfoForObjectBindingElementName01.ts new file mode 100644 index 00000000000..5cba9554b80 --- /dev/null +++ b/tests/cases/fourslash/quickInfoForObjectBindingElementName01.ts @@ -0,0 +1,12 @@ +/// + +////interface I { +//// property1: number; +//// property2: string; +////} +//// +////var foo: I; +////var { /**/property1 } = foo; + +goTo.marker(); +verify.quickInfoIs("var property1: number"); \ No newline at end of file diff --git a/tests/cases/fourslash/quickInfoForObjectBindingElementName02.ts b/tests/cases/fourslash/quickInfoForObjectBindingElementName02.ts new file mode 100644 index 00000000000..e861d3db8fb --- /dev/null +++ b/tests/cases/fourslash/quickInfoForObjectBindingElementName02.ts @@ -0,0 +1,12 @@ +/// + +////interface I { +//// property1: number; +//// property2: string; +////} +//// +////var foo: I; +////var { property1: /**/prop1 } = foo; + +goTo.marker(); +verify.quickInfoIs("var prop1: number"); \ No newline at end of file diff --git a/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName01.ts b/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName01.ts new file mode 100644 index 00000000000..52a9af258b3 --- /dev/null +++ b/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName01.ts @@ -0,0 +1,12 @@ +/// + +////interface I { +//// property1: number; +//// property2: string; +////} +//// +////var foo: I; +////var { /**/property1: prop1 } = foo; + +goTo.marker(); +verify.quickInfoIs("(property) I.property1: number"); \ No newline at end of file diff --git a/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName02.ts b/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName02.ts new file mode 100644 index 00000000000..5a166037f1c --- /dev/null +++ b/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName02.ts @@ -0,0 +1,12 @@ +/// + +////interface I { +//// property1: number; +//// property2: string; +////} +//// +////var foo: I; +////var { /**/property1: {} } = foo; + +goTo.marker(); +verify.quickInfoIs("(property) I.property1: number"); \ No newline at end of file diff --git a/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName03.ts b/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName03.ts new file mode 100644 index 00000000000..cfdeef111dc --- /dev/null +++ b/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName03.ts @@ -0,0 +1,14 @@ +/// + +////interface Recursive { +//// next?: Recursive; +//// value: any; +////} +//// +////function f ({ /*1*/next: { /*2*/next: x} }: Recursive) { +////} + +for (let { position } of test.markers()) { + goTo.position(position) + verify.quickInfoIs("(property) Recursive.next: Recursive"); +} \ No newline at end of file diff --git a/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName04.ts b/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName04.ts new file mode 100644 index 00000000000..8b152740861 --- /dev/null +++ b/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName04.ts @@ -0,0 +1,17 @@ +/// + +////interface Recursive { +//// next?: Recursive; +//// value: any; +////} +//// +////function f ({ /*1*/next: { /*2*/next: x} }) { +////} + +goTo.marker("1"); +verify.quickInfoIs(`(property) next: { + next: any; +}`); + +goTo.marker("2"); +verify.quickInfoIs("(property) next: any"); \ No newline at end of file diff --git a/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts b/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts new file mode 100644 index 00000000000..535dbd3d5a3 --- /dev/null +++ b/tests/cases/fourslash/renameObjectBindingElementPropertyName01.ts @@ -0,0 +1,14 @@ +/// + +////interface I { +//// [|property1|]: number; +//// property2: string; +////} +//// +////var foo: I; +////var { [|property1|]: prop1 } = foo; + +for (let range of test.ranges()) { + goTo.position(range.start); + verify.renameLocations(/*findInStrings*/ false, /*findInComments*/ false); +} \ No newline at end of file diff --git a/tests/cases/fourslash/shims/getSyntacticClassifications.ts b/tests/cases/fourslash/shims/getSyntacticClassifications.ts index 88f655683a3..1dbe2944b8a 100644 --- a/tests/cases/fourslash/shims/getSyntacticClassifications.ts +++ b/tests/cases/fourslash/shims/getSyntacticClassifications.ts @@ -22,8 +22,8 @@ var c = classification; verify.syntacticClassificationsAre( c.comment("// comment"), c.keyword("module"), c.moduleName("M"), c.punctuation("{"), - c.keyword("var"), c.text("v"), c.operator("="), c.numericLiteral("0"), c.operator("+"), c.numericLiteral("1"), c.punctuation(";"), - c.keyword("var"), c.text("s"), c.operator("="), c.stringLiteral('"string"'), c.punctuation(";"), + c.keyword("var"), c.identifier("v"), c.operator("="), c.numericLiteral("0"), c.operator("+"), c.numericLiteral("1"), c.punctuation(";"), + c.keyword("var"), c.identifier("s"), c.operator("="), c.stringLiteral('"string"'), c.punctuation(";"), c.keyword("class"), c.className("C"), c.punctuation("<"), c.typeParameterName("T"), c.punctuation(">"), c.punctuation("{"), c.punctuation("}"), c.keyword("enum"), c.enumName("E"), c.punctuation("{"), diff --git a/tests/cases/fourslash/syntacticClassificationWithErrors.ts b/tests/cases/fourslash/syntacticClassificationWithErrors.ts index b4572d3e620..166a22a1a51 100644 --- a/tests/cases/fourslash/syntacticClassificationWithErrors.ts +++ b/tests/cases/fourslash/syntacticClassificationWithErrors.ts @@ -8,7 +8,7 @@ let c = classification verify.syntacticClassificationsAre( c.keyword("class"), c.className("A"), c.punctuation("{"), - c.text("a"), c.punctuation(":"), + c.identifier("a"), c.punctuation(":"), c.punctuation("}"), - c.text("c"), c.operator("=") + c.identifier("c"), c.operator("=") ); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassifications1.ts b/tests/cases/fourslash/syntacticClassifications1.ts index 88f655683a3..1dbe2944b8a 100644 --- a/tests/cases/fourslash/syntacticClassifications1.ts +++ b/tests/cases/fourslash/syntacticClassifications1.ts @@ -22,8 +22,8 @@ var c = classification; verify.syntacticClassificationsAre( c.comment("// comment"), c.keyword("module"), c.moduleName("M"), c.punctuation("{"), - c.keyword("var"), c.text("v"), c.operator("="), c.numericLiteral("0"), c.operator("+"), c.numericLiteral("1"), c.punctuation(";"), - c.keyword("var"), c.text("s"), c.operator("="), c.stringLiteral('"string"'), c.punctuation(";"), + c.keyword("var"), c.identifier("v"), c.operator("="), c.numericLiteral("0"), c.operator("+"), c.numericLiteral("1"), c.punctuation(";"), + c.keyword("var"), c.identifier("s"), c.operator("="), c.stringLiteral('"string"'), c.punctuation(";"), c.keyword("class"), c.className("C"), c.punctuation("<"), c.typeParameterName("T"), c.punctuation(">"), c.punctuation("{"), c.punctuation("}"), c.keyword("enum"), c.enumName("E"), c.punctuation("{"), diff --git a/tests/cases/fourslash/syntacticClassificationsConflictMarkers1.ts b/tests/cases/fourslash/syntacticClassificationsConflictMarkers1.ts index 7f26038c33e..99db7443a4c 100644 --- a/tests/cases/fourslash/syntacticClassificationsConflictMarkers1.ts +++ b/tests/cases/fourslash/syntacticClassificationsConflictMarkers1.ts @@ -12,8 +12,8 @@ var c = classification; verify.syntacticClassificationsAre( c.keyword("class"), c.className("C"), c.punctuation("{"), c.comment("<<<<<<< HEAD"), - c.text("v"), c.operator("="), c.numericLiteral("1"), c.punctuation(";"), + c.identifier("v"), c.operator("="), c.numericLiteral("1"), c.punctuation(";"), c.comment("======="), - c.text("v"), c.punctuation("="), c.numericLiteral("2"), c.punctuation(";"), + c.identifier("v"), c.punctuation("="), c.numericLiteral("2"), c.punctuation(";"), c.comment(">>>>>>> Branch - a"), c.punctuation("}")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsConflictMarkers2.ts b/tests/cases/fourslash/syntacticClassificationsConflictMarkers2.ts index 92ede0d104b..18363c0389e 100644 --- a/tests/cases/fourslash/syntacticClassificationsConflictMarkers2.ts +++ b/tests/cases/fourslash/syntacticClassificationsConflictMarkers2.ts @@ -11,5 +11,5 @@ verify.syntacticClassificationsAre( c.comment("<<<<<<< HEAD"), c.keyword("class"), c.className("C"), c.punctuation("{"), c.punctuation("}"), c.comment("======="), - c.keyword("class"), c.text("D"), c.punctuation("{"), c.punctuation("}"), + c.keyword("class"), c.identifier("D"), c.punctuation("{"), c.punctuation("}"), c.comment(">>>>>>> Branch - a")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsDocComment1.ts b/tests/cases/fourslash/syntacticClassificationsDocComment1.ts index fe812b4c780..1ea3bf9684a 100644 --- a/tests/cases/fourslash/syntacticClassificationsDocComment1.ts +++ b/tests/cases/fourslash/syntacticClassificationsDocComment1.ts @@ -13,5 +13,5 @@ verify.syntacticClassificationsAre( c.punctuation("}"), c.comment(" */"), c.keyword("var"), - c.text("v"), + c.identifier("v"), c.punctuation(";")); diff --git a/tests/cases/fourslash/syntacticClassificationsDocComment2.ts b/tests/cases/fourslash/syntacticClassificationsDocComment2.ts index 201251dde6d..38dca4edcf2 100644 --- a/tests/cases/fourslash/syntacticClassificationsDocComment2.ts +++ b/tests/cases/fourslash/syntacticClassificationsDocComment2.ts @@ -15,12 +15,12 @@ verify.syntacticClassificationsAre( c.punctuation("{"), c.keyword("function"), c.punctuation("("), - c.text("x"), + c.identifier("x"), c.punctuation(")"), c.punctuation(":"), c.keyword("string"), c.punctuation("}"), c.comment(" */"), c.keyword("var"), - c.text("v"), + c.identifier("v"), c.punctuation(";")); diff --git a/tests/cases/fourslash/syntacticClassificationsDocComment3.ts b/tests/cases/fourslash/syntacticClassificationsDocComment3.ts index 6aca8cc415f..d7996fbbc54 100644 --- a/tests/cases/fourslash/syntacticClassificationsDocComment3.ts +++ b/tests/cases/fourslash/syntacticClassificationsDocComment3.ts @@ -15,5 +15,5 @@ verify.syntacticClassificationsAre( c.keyword("number"), c.comment(" /* } */"), c.keyword("var"), - c.text("v"), + c.identifier("v"), c.punctuation(";")); diff --git a/tests/cases/fourslash/syntacticClassificationsForOfKeyword.ts b/tests/cases/fourslash/syntacticClassificationsForOfKeyword.ts index a7a8c704ce6..22d7aa8ba94 100644 --- a/tests/cases/fourslash/syntacticClassificationsForOfKeyword.ts +++ b/tests/cases/fourslash/syntacticClassificationsForOfKeyword.ts @@ -7,9 +7,9 @@ verify.syntacticClassificationsAre( c.keyword("for"), c.punctuation("("), c.keyword("var"), - c.text("of"), + c.identifier("of"), c.keyword("of"), - c.text("of"), + c.identifier("of"), c.punctuation(")"), c.punctuation("{"), c.punctuation("}") diff --git a/tests/cases/fourslash/syntacticClassificationsForOfKeyword2.ts b/tests/cases/fourslash/syntacticClassificationsForOfKeyword2.ts index 30cfaea51e0..190663caa99 100644 --- a/tests/cases/fourslash/syntacticClassificationsForOfKeyword2.ts +++ b/tests/cases/fourslash/syntacticClassificationsForOfKeyword2.ts @@ -7,9 +7,9 @@ verify.syntacticClassificationsAre( c.keyword("for"), c.punctuation("("), c.keyword("var"), - c.text("of"), + c.identifier("of"), c.keyword("in"), - c.text("of"), + c.identifier("of"), c.punctuation(")"), c.punctuation("{"), c.punctuation("}") diff --git a/tests/cases/fourslash/syntacticClassificationsForOfKeyword3.ts b/tests/cases/fourslash/syntacticClassificationsForOfKeyword3.ts index 3af4733f3b2..ef96c99fed4 100644 --- a/tests/cases/fourslash/syntacticClassificationsForOfKeyword3.ts +++ b/tests/cases/fourslash/syntacticClassificationsForOfKeyword3.ts @@ -7,11 +7,11 @@ verify.syntacticClassificationsAre( c.keyword("for"), c.punctuation("("), c.keyword("var"), - c.text("of"), + c.identifier("of"), c.punctuation(";"), - c.text("of"), + c.identifier("of"), c.punctuation(";"), - c.text("of"), + c.identifier("of"), c.punctuation(")"), c.punctuation("{"), c.punctuation("}") diff --git a/tests/cases/fourslash/syntacticClassificationsFunctionWithComments.ts b/tests/cases/fourslash/syntacticClassificationsFunctionWithComments.ts index f7e5b7355a7..05a5aaa173e 100644 --- a/tests/cases/fourslash/syntacticClassificationsFunctionWithComments.ts +++ b/tests/cases/fourslash/syntacticClassificationsFunctionWithComments.ts @@ -19,7 +19,7 @@ var firstCommentText = var c = classification; verify.syntacticClassificationsAre( c.comment(firstCommentText), - c.keyword("function"), c.text("myFunction"), c.punctuation("("), c.comment("/* x */"), c.parameterName("x"), c.punctuation(":"), c.keyword("any"), c.punctuation(")"), c.punctuation("{"), - c.keyword("var"), c.text("y"), c.operator("="), c.text("x"), c.operator("?"), c.text("x"), c.operator("++"), c.operator(":"), c.operator("++"), c.text("x"), c.punctuation(";"), + c.keyword("function"), c.identifier("myFunction"), c.punctuation("("), c.comment("/* x */"), c.parameterName("x"), c.punctuation(":"), c.keyword("any"), c.punctuation(")"), c.punctuation("{"), + c.keyword("var"), c.identifier("y"), c.operator("="), c.identifier("x"), c.operator("?"), c.identifier("x"), c.operator("++"), c.operator(":"), c.operator("++"), c.identifier("x"), c.punctuation(";"), c.punctuation("}"), c.comment("// end of file")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsObjectLiteral.ts b/tests/cases/fourslash/syntacticClassificationsObjectLiteral.ts index 59642468ce9..c5bab5181a3 100644 --- a/tests/cases/fourslash/syntacticClassificationsObjectLiteral.ts +++ b/tests/cases/fourslash/syntacticClassificationsObjectLiteral.ts @@ -13,13 +13,13 @@ var c = classification; verify.syntacticClassificationsAre( - c.keyword("var"), c.text("v"), c.operator("="), c.numericLiteral("10e0"), c.punctuation(";"), - c.keyword("var"), c.text("x"), c.operator("="), c.punctuation("{"), - c.text("p1"), c.punctuation(":"), c.numericLiteral("1"), c.punctuation(","), - c.text("p2"), c.punctuation(":"), c.numericLiteral("2"), c.punctuation(","), - c.text("any"), c.punctuation(":"), c.numericLiteral("3"), c.punctuation(","), - c.text("function"), c.punctuation(":"), c.numericLiteral("4"), c.punctuation(","), - c.text("var"), c.punctuation(":"), c.numericLiteral("5"), c.punctuation(","), - c.text("void"), c.punctuation(":"), c.keyword("void"), c.numericLiteral("0"), c.punctuation(","), - c.text("v"), c.punctuation(":"), c.text("v"), c.operator("+="), c.text("v"), c.punctuation(","), + c.keyword("var"), c.identifier("v"), c.operator("="), c.numericLiteral("10e0"), c.punctuation(";"), + c.keyword("var"), c.identifier("x"), c.operator("="), c.punctuation("{"), + c.identifier("p1"), c.punctuation(":"), c.numericLiteral("1"), c.punctuation(","), + c.identifier("p2"), c.punctuation(":"), c.numericLiteral("2"), c.punctuation(","), + c.identifier("any"), c.punctuation(":"), c.numericLiteral("3"), c.punctuation(","), + c.identifier("function"), c.punctuation(":"), c.numericLiteral("4"), c.punctuation(","), + c.identifier("var"), c.punctuation(":"), c.numericLiteral("5"), c.punctuation(","), + c.identifier("void"), c.punctuation(":"), c.keyword("void"), c.numericLiteral("0"), c.punctuation(","), + c.identifier("v"), c.punctuation(":"), c.identifier("v"), c.operator("+="), c.identifier("v"), c.punctuation(","), c.punctuation("}"), c.punctuation(";")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsTemplates1.ts b/tests/cases/fourslash/syntacticClassificationsTemplates1.ts index 8ee48fb8a11..6c27aab3f40 100644 --- a/tests/cases/fourslash/syntacticClassificationsTemplates1.ts +++ b/tests/cases/fourslash/syntacticClassificationsTemplates1.ts @@ -8,8 +8,8 @@ var c = classification; verify.syntacticClassificationsAre( - c.keyword("var"), c.text("v"), c.operator("="), c.numericLiteral("10e0"), c.punctuation(";"), - c.keyword("var"), c.text("x"), c.operator("="), c.punctuation("{"), - c.text("p1"), c.punctuation(":"), c.stringLiteral("`hello world`"), c.punctuation(","), - c.text("p2"), c.punctuation(":"), c.stringLiteral("`goodbye ${"), c.numericLiteral("0"), c.stringLiteral("} cruel ${"), c.numericLiteral("0"), c.stringLiteral("} world`"), c.punctuation(","), + c.keyword("var"), c.identifier("v"), c.operator("="), c.numericLiteral("10e0"), c.punctuation(";"), + c.keyword("var"), c.identifier("x"), c.operator("="), c.punctuation("{"), + c.identifier("p1"), c.punctuation(":"), c.stringLiteral("`hello world`"), c.punctuation(","), + c.identifier("p2"), c.punctuation(":"), c.stringLiteral("`goodbye ${"), c.numericLiteral("0"), c.stringLiteral("} cruel ${"), c.numericLiteral("0"), c.stringLiteral("} world`"), c.punctuation(","), c.punctuation("}"), c.punctuation(";")); \ No newline at end of file diff --git a/tests/cases/fourslash/syntacticClassificationsTemplates2.ts b/tests/cases/fourslash/syntacticClassificationsTemplates2.ts index 913dc039012..25bb64e78ba 100644 --- a/tests/cases/fourslash/syntacticClassificationsTemplates2.ts +++ b/tests/cases/fourslash/syntacticClassificationsTemplates2.ts @@ -6,6 +6,6 @@ var c = classification; verify.syntacticClassificationsAre( - c.keyword("var"), c.text("tiredOfCanonicalExamples"), c.operator("="), + c.keyword("var"), c.identifier("tiredOfCanonicalExamples"), c.operator("="), c.stringLiteral("`goodbye \"${"), c.stringLiteral("`hello world`"), c.stringLiteral("}\" \nand ${"), c.stringLiteral("`good${"), c.stringLiteral("\" \""), c.stringLiteral("}riddance`"), c.stringLiteral("}`"), c.punctuation(";")); \ No newline at end of file From 2dd71e063a78692e4a20c630847cd873fddf271c Mon Sep 17 00:00:00 2001 From: zhengbli Date: Thu, 16 Jul 2015 16:42:25 -0700 Subject: [PATCH 8/8] Fix fourslash test --- src/harness/fourslash.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 5c8e6bc8981..68a154b4cd4 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1884,7 +1884,7 @@ module FourSlash { ); assert.equal( expected.join(","), - actual.fileNameList.map( file => { + actual.fileNames.map( file => { return file.replace(this.basePath + "/", ""); }).join(",") );