From 4de96abd8fc5d678d6b494a953d3127dd2acf871 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 16 Jun 2017 14:37:39 -0700 Subject: [PATCH 001/312] Use the same logic of getting current directory as the one used when emitting files through project It means we would use currentDirectory as project Root or script info's directory as the current directory Fixes issue reported in https://developercommunity.visualstudio.com/content/problem/57099/typescript-generated-source-maps-have-invalid-path.html --- src/compiler/program.ts | 12 +++---- src/compiler/types.ts | 6 +++- src/harness/unittests/compileOnSave.ts | 45 +++++++++++++++++++++++++- src/server/builder.ts | 4 +-- src/server/project.ts | 11 ++++++- src/services/services.ts | 4 +-- src/services/transpile.ts | 2 +- src/services/types.ts | 2 +- 8 files changed, 71 insertions(+), 15 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index bbc0fa09780..30c61f50dff 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -874,12 +874,12 @@ namespace ts { return oldProgram.structureIsReused = StructureIsReused.Completely; } - function getEmitHost(writeFileCallback?: WriteFileCallback): EmitHost { + function getEmitHost(writeFileCallback?: WriteFileCallback, getCurrentDirectoryCallback?: GetCurrentDirectoryCallback): EmitHost { return { getCanonicalFileName, getCommonSourceDirectory: program.getCommonSourceDirectory, getCompilerOptions: program.getCompilerOptions, - getCurrentDirectory: () => currentDirectory, + getCurrentDirectory: getCurrentDirectoryCallback || (() => currentDirectory), getNewLine: () => host.getNewLine(), getSourceFile: program.getSourceFile, getSourceFileByPath: program.getSourceFileByPath, @@ -907,15 +907,15 @@ namespace ts { return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = createTypeChecker(program, /*produceDiagnostics:*/ false)); } - function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, transformers?: CustomTransformers): EmitResult { - return runWithCancellationToken(() => emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers)); + function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, transformers?: CustomTransformers, getCurrentDirectoryCallback?: GetCurrentDirectoryCallback): EmitResult { + return runWithCancellationToken(() => emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers, getCurrentDirectoryCallback)); } function isEmitBlocked(emitFileName: string): boolean { return hasEmitBlockingDiagnostics.contains(toPath(emitFileName, currentDirectory, getCanonicalFileName)); } - function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult { + function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers, getCurrentDirectoryCallback?: GetCurrentDirectoryCallback): EmitResult { let declarationDiagnostics: Diagnostic[] = []; if (options.noEmit) { @@ -960,7 +960,7 @@ namespace ts { const transformers = emitOnlyDtsFiles ? [] : getTransformers(options, customTransformers); const emitResult = emitFiles( emitResolver, - getEmitHost(writeFileCallback), + getEmitHost(writeFileCallback, getCurrentDirectoryCallback), sourceFile, emitOnlyDtsFiles, transformers); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ac64624e1a6..ac5de153226 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2405,6 +2405,10 @@ namespace ts { (fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void, sourceFiles?: SourceFile[]): void; } + export interface GetCurrentDirectoryCallback { + (): string; + } + export class OperationCanceledException { } export interface CancellationToken { @@ -2436,7 +2440,7 @@ namespace ts { * used for writing the JavaScript and declaration files. Otherwise, the writeFile parameter * will be invoked when writing the JavaScript and declaration files. */ - emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult; + emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers, getCurrentDirectoryCallback?: GetCurrentDirectoryCallback): EmitResult; getOptionsDiagnostics(cancellationToken?: CancellationToken): Diagnostic[]; getGlobalDiagnostics(cancellationToken?: CancellationToken): Diagnostic[]; diff --git a/src/harness/unittests/compileOnSave.ts b/src/harness/unittests/compileOnSave.ts index 7e262a1b257..3183ffd71b0 100644 --- a/src/harness/unittests/compileOnSave.ts +++ b/src/harness/unittests/compileOnSave.ts @@ -600,5 +600,48 @@ namespace ts.projectSystem { assert.isTrue(outFileContent.indexOf(file2.content) === -1); assert.isTrue(outFileContent.indexOf(file3.content) === -1); }); + + it("should use project root as current directory so that compile on save results in correct file mapping", () => { + const inputFileName = "Foo.ts"; + const file1 = { + path: `/root/TypeScriptProject3/TypeScriptProject3/${inputFileName}`, + content: "consonle.log('file1');" + }; + const externalProjectName = "/root/TypeScriptProject3/TypeScriptProject3/TypeScriptProject3.csproj"; + const host = createServerHost([file1, libFile]); + const session = createSession(host); + const projectService = session.getProjectService(); + + const outFileName = "bar.js"; + projectService.openExternalProject({ + rootFiles: toExternalFiles([file1.path]), + options: { + outFile: outFileName, + sourceMap: true, + compileOnSave: true + }, + projectFileName: externalProjectName + }); + + const emitRequest = makeSessionRequest(CommandNames.CompileOnSaveEmitFile, { file: file1.path }); + session.executeCommand(emitRequest); + + // Verify js file + const expectedOutFileName = "/root/TypeScriptProject3/TypeScriptProject3/" + outFileName; + assert.isTrue(host.fileExists(expectedOutFileName)); + const outFileContent = host.readFile(expectedOutFileName); + verifyContentHasString(outFileContent, file1.content); + verifyContentHasString(outFileContent, `//# sourceMappingURL=${outFileName}.map`); + + // Verify map file + const expectedMapFileName = expectedOutFileName + ".map"; + assert.isTrue(host.fileExists(expectedMapFileName)); + const mapFileContent = host.readFile(expectedMapFileName); + verifyContentHasString(mapFileContent, `"sources":["${inputFileName}"]`); + + function verifyContentHasString(content: string, string: string) { + assert.isTrue(content.indexOf(string) !== -1, `Expected "${content}" to have "${string}"`); + } + }); }); -} \ No newline at end of file +} diff --git a/src/server/builder.ts b/src/server/builder.ts index 895732ebece..711045d0ae6 100644 --- a/src/server/builder.ts +++ b/src/server/builder.ts @@ -148,9 +148,9 @@ namespace ts.server { const { emitSkipped, outputFiles } = this.project.getFileEmitOutput(fileInfo.scriptInfo, /*emitOnlyDtsFiles*/ false); if (!emitSkipped) { - const projectRootPath = this.project.getProjectRootPath(); + const currentDirectoryForEmit = this.project.getCurrentDirectoryForScriptInfoEmit(scriptInfo); for (const outputFile of outputFiles) { - const outputFileAbsoluteFileName = getNormalizedAbsolutePath(outputFile.name, projectRootPath ? projectRootPath : getDirectoryPath(scriptInfo.fileName)); + const outputFileAbsoluteFileName = getNormalizedAbsolutePath(outputFile.name, currentDirectoryForEmit); writeFile(outputFileAbsoluteFileName, outputFile.text, outputFile.writeByteOrderMark); } } diff --git a/src/server/project.ts b/src/server/project.ts index ac040a77ace..a7d8605315b 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -367,7 +367,16 @@ namespace ts.server { if (!this.languageServiceEnabled) { return undefined; } - return this.getLanguageService().getEmitOutput(info.fileName, emitOnlyDtsFiles); + + const getCurrentDirectoryCallback = memoize( + () => this.getCurrentDirectoryForScriptInfoEmit(info) + ); + return this.getLanguageService().getEmitOutput(info.fileName, emitOnlyDtsFiles, getCurrentDirectoryCallback); + } + + getCurrentDirectoryForScriptInfoEmit(info: ScriptInfo) { + const projectRootPath = this.getProjectRootPath(); + return projectRootPath || getDirectoryPath(info.fileName); } getFileNames(excludeFilesFromExternalLibraries?: boolean, excludeConfigFiles?: boolean) { diff --git a/src/services/services.ts b/src/services/services.ts index b508285b182..11061181ee6 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1528,7 +1528,7 @@ namespace ts { return ts.NavigateTo.getNavigateToItems(sourceFiles, program.getTypeChecker(), cancellationToken, searchValue, maxResultCount, excludeDtsFiles); } - function getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput { + function getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean, getCurrentDirectoryCallback?: GetCurrentDirectoryCallback): EmitOutput { synchronizeHostData(); const sourceFile = getValidSourceFile(fileName); @@ -1543,7 +1543,7 @@ namespace ts { } const customTransformers = host.getCustomTransformers && host.getCustomTransformers(); - const emitOutput = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers); + const emitOutput = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers, getCurrentDirectoryCallback); return { outputFiles, diff --git a/src/services/transpile.ts b/src/services/transpile.ts index 561c188c6cd..5ba393a90c9 100644 --- a/src/services/transpile.ts +++ b/src/services/transpile.ts @@ -104,7 +104,7 @@ namespace ts { addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics()); } // Emit - program.emit(/*targetSourceFile*/ undefined, /*writeFile*/ undefined, /*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ undefined, transpileOptions.transformers); + program.emit(/*targetSourceFile*/ undefined, /*writeFile*/ undefined, /*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ undefined, transpileOptions.transformers, /*getCurrentDirectoryCallback*/ undefined); Debug.assert(outputText !== undefined, "Output generation failed"); diff --git a/src/services/types.ts b/src/services/types.ts index 2d47da2fd1d..07aaaeeb4b4 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -269,7 +269,7 @@ namespace ts { getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; - getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; + getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean, getCurrentDirectoryCallBack?: GetCurrentDirectoryCallback): EmitOutput; getProgram(): Program; From 0bd3d8c2eb01a0e881177c59e1f3a9136533de05 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Wed, 21 Jun 2017 15:03:20 -0700 Subject: [PATCH 002/312] unspoof call expression start in iife --- src/services/formatting/smartIndenter.ts | 53 ++++++++++++++++-------- src/services/services.ts | 2 +- src/services/textChanges.ts | 2 +- src/services/utilities.ts | 5 ++- 4 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 18b0479c85a..7609296ccf5 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -9,18 +9,21 @@ namespace ts.formatting { } /** - * Computed indentation for a given position in source file - * @param position - position in file - * @param sourceFile - target source file - * @param options - set of editor options that control indentation - * @param assumeNewLineBeforeCloseBrace - false when getIndentation is called on the text from the real source file. - * true - when we need to assume that position is on the newline. This is usefult for codefixes, i.e. + * @param assumeNewLineBeforeCloseBrace + * `false` when called on text from a real source file. + * `true` when we need to assume `position` is on a newline. + * + * This is useful for codefixes. Consider + * ``` * function f() { * |} - * when inserting some text after open brace we would like to get the value of indentation as if newline was already there. - * However by default indentation at position | will be 0 so 'assumeNewLineBeforeCloseBrace' allows to override this behavior, + * ``` + * with `position` at `|`. + * + * When inserting some text after an open brace, we would like to get indentation as if a newline was already there. + * By default indentation at `position` will be 0 so 'assumeNewLineBeforeCloseBrace' overrides this behavior, */ - export function getIndentation(position: number, sourceFile: SourceFile, options: EditorSettings, assumeNewLineBeforeCloseBrace = false): number { + export function getIndentationAtPosition(position: number, sourceFile: SourceFile, options: EditorSettings, assumeNewLineBeforeCloseBrace = false): number { if (position > sourceFile.text.length) { return getBaseIndentation(options); // past EOF } @@ -136,8 +139,10 @@ namespace ts.formatting { let parent: Node = current.parent; let parentStart: LineAndCharacter; - // walk upwards and collect indentations for pairs of parent-child nodes - // indentation is not added if parent and child nodes start on the same line or if parent is IfStatement and child starts on the same line with 'else clause' + // Walk up the tree and collect indentation for pairs of parent-child nodes. + // indentation is not added if + // * parent and child nodes start on the same line + // * parent is IfStatement and child starts on the same line with 'else clause' while (parent) { let useActualIndentation = true; if (ignoreActualIndentationRange) { @@ -174,22 +179,24 @@ namespace ts.formatting { indentationDelta += options.indentSize; } + // Update current and parent. + + const callExpressionUsesTrueStart = + isParameterAndStartLineOverlapsExpressionBeingCalled(parent, current, currentStart.line, sourceFile); + current = parent; - currentStart = parentStart; parent = current.parent; + currentStart = callExpressionUsesTrueStart ? sourceFile.getLineAndCharacterOfPosition(current.getStart()) : parentStart; + parentStart = undefined; } return indentationDelta + getBaseIndentation(options); } - function getParentStart(parent: Node, child: Node, sourceFile: SourceFile): LineAndCharacter { const containingList = getContainingList(child, sourceFile); - if (containingList) { - return sourceFile.getLineAndCharacterOfPosition(containingList.pos); - } - - return sourceFile.getLineAndCharacterOfPosition(parent.getStart(sourceFile)); + const startPos = containingList ? containingList.pos : parent.getStart(sourceFile); + return sourceFile.getLineAndCharacterOfPosition(startPos); } /* @@ -268,6 +275,16 @@ namespace ts.formatting { return sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile)); } + export function isParameterAndStartLineOverlapsExpressionBeingCalled(parent: Node, child: Node, childStartLine: number, sourceFile: SourceFileLike): boolean { + if (!(isCallExpression(parent) && contains(parent.arguments, child))) { + return false; + } + + const callExpressionEnd = parent.expression.getEnd(); + const expressionEndLine = getLineAndCharacterOfPosition(sourceFile, callExpressionEnd).line; + return expressionEndLine === childStartLine; + } + export function childStartsOnTheSameLineWithElseInIfStatement(parent: Node, child: TextRangeWithKind, childStartLine: number, sourceFile: SourceFileLike): boolean { if (parent.kind === SyntaxKind.IfStatement && (parent).elseStatement === child) { const elseKeyword = findChildOfKind(parent, SyntaxKind.ElseKeyword, sourceFile); diff --git a/src/services/services.ts b/src/services/services.ts index b508285b182..13e6e2a2e4b 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1742,7 +1742,7 @@ namespace ts { start = timestamp(); - const result = formatting.SmartIndenter.getIndentation(position, sourceFile, settings); + const result = formatting.SmartIndenter.getIndentationAtPosition(position, sourceFile, settings); log("getIndentationAtPosition: computeIndentation : " + (timestamp() - start)); return result; diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 5aa4ebca7d0..e0d96d26a55 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -465,7 +465,7 @@ namespace ts.textChanges { change.options.indentation !== undefined ? change.options.indentation : change.useIndentationFromFile - ? formatting.SmartIndenter.getIndentation(change.range.pos, sourceFile, formatOptions, posStartsLine || (change.options.prefix === this.newLineCharacter)) + ? formatting.SmartIndenter.getIndentationAtPosition(change.range.pos, sourceFile, formatOptions, posStartsLine || (change.options.prefix === this.newLineCharacter)) : 0; const delta = change.options.delta !== undefined diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 78c71403736..f0a0c3ee758 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -402,8 +402,11 @@ namespace ts { return start < end; } + /** + * Assumes `candidate.start <= position` holds. + */ export function positionBelongsToNode(candidate: Node, position: number, sourceFile: SourceFile): boolean { - return candidate.end > position || !isCompletedNode(candidate, sourceFile); + return position < candidate.end || !isCompletedNode(candidate, sourceFile); } export function isCompletedNode(n: Node, sourceFile: SourceFile): boolean { From d1423739cdaea03f1e27f9522816e52517581dbe Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Wed, 21 Jun 2017 15:05:15 -0700 Subject: [PATCH 003/312] add test --- tests/cases/fourslash/indentationInAmdIife.ts | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 tests/cases/fourslash/indentationInAmdIife.ts diff --git a/tests/cases/fourslash/indentationInAmdIife.ts b/tests/cases/fourslash/indentationInAmdIife.ts new file mode 100644 index 00000000000..46169334463 --- /dev/null +++ b/tests/cases/fourslash/indentationInAmdIife.ts @@ -0,0 +1,52 @@ +/// + +//// function foo(a?,b?) { b(a); } +//// +//// (foo)(1, function() {/*4_0*/ +//// }); +//// +//// ///////////// +//// +//// ( +//// foo)(1, function () {/*4_1*/ +//// }); +//// (foo) +//// (1, function () {/*8_0*/ +//// }); +//// (foo)(1, +//// function () {/*8_1*/ +//// }); +//// (foo)(1, function() +//// {/*4_2*/ +//// }); +//// +//// ////////////////////// +//// +//// (foo +//// )(1, function () {/*4_3*/ +//// }); +//// (foo +//// ) +//// (1, function () {/*8_2*/ +//// }); +//// (foo +//// )(1, +//// function () {/*8_3*/ +//// }); +//// (foo +//// )(1, function() +//// {/*4_4*/ +//// }); + + +for (let i = 0; i < 5; ++i) { + goTo.marker(`4_${i}`); + edit.insertLine(""); + verify.indentationIs(4); +} + +for (let i = 1; i < 4; ++i) { + goTo.marker(`8_${i}`); + edit.insertLine(""); + verify.indentationIs(8); +} \ No newline at end of file From 902d0f501803af9d6e24ffe6ca85751386efd6ba Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Wed, 21 Jun 2017 17:04:39 -0700 Subject: [PATCH 004/312] cleanup --- src/services/formatting/smartIndenter.ts | 22 +++++++++---------- tests/cases/fourslash/indentationInAmdIife.ts | 13 +++++------ 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 7609296ccf5..e1e440a9505 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -21,7 +21,7 @@ namespace ts.formatting { * with `position` at `|`. * * When inserting some text after an open brace, we would like to get indentation as if a newline was already there. - * By default indentation at `position` will be 0 so 'assumeNewLineBeforeCloseBrace' overrides this behavior, + * By default indentation at `position` will be 0 so 'assumeNewLineBeforeCloseBrace' overrides this behavior. */ export function getIndentationAtPosition(position: number, sourceFile: SourceFile, options: EditorSettings, assumeNewLineBeforeCloseBrace = false): number { if (position > sourceFile.text.length) { @@ -139,10 +139,9 @@ namespace ts.formatting { let parent: Node = current.parent; let parentStart: LineAndCharacter; - // Walk up the tree and collect indentation for pairs of parent-child nodes. - // indentation is not added if - // * parent and child nodes start on the same line - // * parent is IfStatement and child starts on the same line with 'else clause' + // Walk up the tree and collect indentation for parent-child node pairs. Indentation is not added if + // * parent and child nodes start on the same line, or + // * parent is an IfStatement and child starts on the same line as an 'else clause'. while (parent) { let useActualIndentation = true; if (ignoreActualIndentationRange) { @@ -157,6 +156,7 @@ namespace ts.formatting { return actualIndentation + indentationDelta; } } + parentStart = getParentStart(parent, current, sourceFile); const parentAndChildShareLine = parentStart.line === currentStart.line || @@ -179,14 +179,14 @@ namespace ts.formatting { indentationDelta += options.indentSize; } - // Update current and parent. + // Update `current` and `parent`. - const callExpressionUsesTrueStart = + const useTrueStart = isParameterAndStartLineOverlapsExpressionBeingCalled(parent, current, currentStart.line, sourceFile); current = parent; parent = current.parent; - currentStart = callExpressionUsesTrueStart ? sourceFile.getLineAndCharacterOfPosition(current.getStart()) : parentStart; + currentStart = useTrueStart ? sourceFile.getLineAndCharacterOfPosition(current.getStart()) : parentStart; parentStart = undefined; } @@ -280,9 +280,9 @@ namespace ts.formatting { return false; } - const callExpressionEnd = parent.expression.getEnd(); - const expressionEndLine = getLineAndCharacterOfPosition(sourceFile, callExpressionEnd).line; - return expressionEndLine === childStartLine; + const expressionOfCallExpressionEnd = parent.expression.getEnd(); + const expressionOfCallExpressionEndLine = getLineAndCharacterOfPosition(sourceFile, expressionOfCallExpressionEnd).line; + return expressionOfCallExpressionEndLine === childStartLine; } export function childStartsOnTheSameLineWithElseInIfStatement(parent: Node, child: TextRangeWithKind, childStartLine: number, sourceFile: SourceFileLike): boolean { diff --git a/tests/cases/fourslash/indentationInAmdIife.ts b/tests/cases/fourslash/indentationInAmdIife.ts index 46169334463..f735ae57eb2 100644 --- a/tests/cases/fourslash/indentationInAmdIife.ts +++ b/tests/cases/fourslash/indentationInAmdIife.ts @@ -5,11 +5,8 @@ //// (foo)(1, function() {/*4_0*/ //// }); //// -//// ///////////// +//// // No line-breaks in the expression part of the call expression //// -//// ( -//// foo)(1, function () {/*4_1*/ -//// }); //// (foo) //// (1, function () {/*8_0*/ //// }); @@ -20,8 +17,11 @@ //// {/*4_2*/ //// }); //// -//// ////////////////////// -//// +//// // Contains line-breaks in the expression part of the call expression. +//// +//// ( +//// foo)(1, function () {/*4_1*/ +//// }); //// (foo //// )(1, function () {/*4_3*/ //// }); @@ -38,7 +38,6 @@ //// {/*4_4*/ //// }); - for (let i = 0; i < 5; ++i) { goTo.marker(`4_${i}`); edit.insertLine(""); From 1251668342775f00c5f2654490e6078289eb35af Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 22 Jun 2017 10:32:04 -0700 Subject: [PATCH 005/312] rename variables --- src/services/formatting/smartIndenter.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index e1e440a9505..7900f8bb8c3 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -137,7 +137,7 @@ namespace ts.formatting { options: EditorSettings): number { let parent: Node = current.parent; - let parentStart: LineAndCharacter; + let containingListOrParentStart: LineAndCharacter; // Walk up the tree and collect indentation for parent-child node pairs. Indentation is not added if // * parent and child nodes start on the same line, or @@ -157,9 +157,9 @@ namespace ts.formatting { } } - parentStart = getParentStart(parent, current, sourceFile); + containingListOrParentStart = getContainingListOrParentStart(parent, current, sourceFile); const parentAndChildShareLine = - parentStart.line === currentStart.line || + containingListOrParentStart.line === currentStart.line || childStartsOnTheSameLineWithElseInIfStatement(parent, current, currentStart.line, sourceFile); if (useActualIndentation) { @@ -182,18 +182,18 @@ namespace ts.formatting { // Update `current` and `parent`. const useTrueStart = - isParameterAndStartLineOverlapsExpressionBeingCalled(parent, current, currentStart.line, sourceFile); + isArgumentAndStartLineOverlapsExpressionBeingCalled(parent, current, currentStart.line, sourceFile); current = parent; parent = current.parent; - currentStart = useTrueStart ? sourceFile.getLineAndCharacterOfPosition(current.getStart()) : parentStart; - parentStart = undefined; + currentStart = useTrueStart ? sourceFile.getLineAndCharacterOfPosition(current.getStart()) : containingListOrParentStart; + containingListOrParentStart = undefined; } return indentationDelta + getBaseIndentation(options); } - function getParentStart(parent: Node, child: Node, sourceFile: SourceFile): LineAndCharacter { + function getContainingListOrParentStart(parent: Node, child: Node, sourceFile: SourceFile): LineAndCharacter { const containingList = getContainingList(child, sourceFile); const startPos = containingList ? containingList.pos : parent.getStart(sourceFile); return sourceFile.getLineAndCharacterOfPosition(startPos); @@ -275,7 +275,7 @@ namespace ts.formatting { return sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile)); } - export function isParameterAndStartLineOverlapsExpressionBeingCalled(parent: Node, child: Node, childStartLine: number, sourceFile: SourceFileLike): boolean { + export function isArgumentAndStartLineOverlapsExpressionBeingCalled(parent: Node, child: Node, childStartLine: number, sourceFile: SourceFileLike): boolean { if (!(isCallExpression(parent) && contains(parent.arguments, child))) { return false; } From ad62037f25cf09092a08aef21b2791f751f63a35 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 15 Aug 2017 11:42:25 -0700 Subject: [PATCH 006/312] Use checkExpression to resolve symbols --- src/compiler/checker.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1c41be84ba7..cfa76c0315a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16376,9 +16376,7 @@ namespace ts { // in a JS file // Note:JS inferred classes might come from a variable declaration instead of a function declaration. // In this case, using getResolvedSymbol directly is required to avoid losing the members from the declaration. - let funcSymbol = node.expression.kind === SyntaxKind.Identifier ? - getResolvedSymbol(node.expression as Identifier) : - checkExpression(node.expression).symbol; + let funcSymbol = checkExpression(node.expression).symbol; if (funcSymbol && isDeclarationOfFunctionOrClassExpression(funcSymbol)) { funcSymbol = getSymbolOfNode((funcSymbol.valueDeclaration).initializer); } From 17994588b22f2e2f853f02e70ee9716135866f58 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 15 Aug 2017 11:58:57 -0700 Subject: [PATCH 007/312] Actual fix + test --- src/compiler/checker.ts | 3 +++ .../fourslash/indirectClassInstantiation.ts | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 tests/cases/fourslash/indirectClassInstantiation.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cfa76c0315a..aa03332af2d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16377,6 +16377,9 @@ namespace ts { // Note:JS inferred classes might come from a variable declaration instead of a function declaration. // In this case, using getResolvedSymbol directly is required to avoid losing the members from the declaration. let funcSymbol = checkExpression(node.expression).symbol; + if (!funcSymbol && node.expression.kind === SyntaxKind.Identifier) { + funcSymbol = getResolvedSymbol(node.expression as Identifier); + } if (funcSymbol && isDeclarationOfFunctionOrClassExpression(funcSymbol)) { funcSymbol = getSymbolOfNode((funcSymbol.valueDeclaration).initializer); } diff --git a/tests/cases/fourslash/indirectClassInstantiation.ts b/tests/cases/fourslash/indirectClassInstantiation.ts new file mode 100644 index 00000000000..c4d0d38d6ed --- /dev/null +++ b/tests/cases/fourslash/indirectClassInstantiation.ts @@ -0,0 +1,21 @@ +/// + +// @allowJs: true +// @Filename: something.js +//// function TestObj(){ +//// this.property = "value"; +//// } +//// var constructor = TestObj; +//// var instance = new constructor(); +//// instance./*a*/ +//// var class2 = function() { }; +//// class2.prototype.blah = function() { }; +//// var inst2 = new class2(); +//// inst2.blah/*b*/; + +goTo.marker('a'); +verify.completionListContains('property'); +edit.backspace(); + +goTo.marker('b'); +verify.quickInfoIs('(property) class2.blah: () => void'); From 262d7bd53bda077786341c9cd3ad912d0f4f5eb0 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Tue, 19 Sep 2017 16:23:45 -0700 Subject: [PATCH 008/312] revert method rename --- src/services/formatting/smartIndenter.ts | 2 +- src/services/services.ts | 2 +- src/services/textChanges.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index b04369f30ae..fac61be45d5 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -23,7 +23,7 @@ namespace ts.formatting { * When inserting some text after an open brace, we would like to get indentation as if a newline was already there. * By default indentation at `position` will be 0 so 'assumeNewLineBeforeCloseBrace' overrides this behavior. */ - export function getIndentationAtPosition(position: number, sourceFile: SourceFile, options: EditorSettings, assumeNewLineBeforeCloseBrace = false): number { + export function getIndentation(position: number, sourceFile: SourceFile, options: EditorSettings, assumeNewLineBeforeCloseBrace = false): number { if (position > sourceFile.text.length) { return getBaseIndentation(options); // past EOF } diff --git a/src/services/services.ts b/src/services/services.ts index 4008d4382fc..90f9acd82ea 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1772,7 +1772,7 @@ namespace ts { start = timestamp(); - const result = formatting.SmartIndenter.getIndentationAtPosition(position, sourceFile, settings); + const result = formatting.SmartIndenter.getIndentation(position, sourceFile, settings); log("getIndentationAtPosition: computeIndentation : " + (timestamp() - start)); return result; diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 8883724f698..b4a2d3e07e2 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -557,7 +557,7 @@ namespace ts.textChanges { options.indentation !== undefined ? options.indentation : (options.useIndentationFromFile !== false) - ? formatting.SmartIndenter.getIndentationAtPosition(pos, sourceFile, formatOptions, posStartsLine || (options.prefix === this.newLineCharacter)) + ? formatting.SmartIndenter.getIndentation(pos, sourceFile, formatOptions, posStartsLine || (options.prefix === this.newLineCharacter)) : 0; const delta = options.delta !== undefined From e3a720f863fc353b6ec8c77aee5470cd1011a3d8 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Tue, 19 Sep 2017 16:25:06 -0700 Subject: [PATCH 009/312] explain changes and remove spurious assignment --- src/services/formatting/smartIndenter.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index fac61be45d5..7701cff182c 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -202,7 +202,14 @@ namespace ts.formatting { indentationDelta += options.indentSize; } - // Update `current` and `parent`. + // In our AST, a call argument's `parent` is the call-expression, not the argument list. + // We would like to increase indentation based on the relationship between an argument and its argument-list, + // so we spoof the starting position of the (parent) call-expression to match the (non-parent) argument-list. + // But, the spoofed start-value could then cause a problem when comparing the start position of the call-expression + // to *its* parent (in the case of an iife, an expression statement), adding an extra level of indentation. + // + // Instead, when at an argument, we unspoof the starting position of the enclosing call expression + // *after* applying indentation for the argument. const useTrueStart = isArgumentAndStartLineOverlapsExpressionBeingCalled(parent, current, currentStart.line, sourceFile); @@ -210,7 +217,6 @@ namespace ts.formatting { current = parent; parent = current.parent; currentStart = useTrueStart ? sourceFile.getLineAndCharacterOfPosition(current.getStart()) : containingListOrParentStart; - containingListOrParentStart = undefined; } return indentationDelta + getBaseIndentation(options); From 4b464ebca887d5bdf69968c8f46c7c888c97be59 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Tue, 19 Sep 2017 17:56:34 -0700 Subject: [PATCH 010/312] add tests * verified that new tests show no regressions against master --- tests/cases/fourslash/indentationInArrays.ts | 21 +++++++++++ .../fourslash/indentationInAssignment.ts | 37 +++++++++++++++++++ .../indentationInAsyncExpressions.ts | 16 ++++++++ .../fourslash/indentationInClassExpression.ts | 31 ++++++++++++++++ tests/cases/fourslash/indentationInObject.ts | 30 +++++++++++++++ 5 files changed, 135 insertions(+) create mode 100644 tests/cases/fourslash/indentationInArrays.ts create mode 100644 tests/cases/fourslash/indentationInAssignment.ts create mode 100644 tests/cases/fourslash/indentationInAsyncExpressions.ts create mode 100644 tests/cases/fourslash/indentationInClassExpression.ts create mode 100644 tests/cases/fourslash/indentationInObject.ts diff --git a/tests/cases/fourslash/indentationInArrays.ts b/tests/cases/fourslash/indentationInArrays.ts new file mode 100644 index 00000000000..9468ff43a08 --- /dev/null +++ b/tests/cases/fourslash/indentationInArrays.ts @@ -0,0 +1,21 @@ +/// + +//// function foo() { +//// [/*8_0*/1,2,3]; +//// [1/*8_1*/,2,3]; +//// [1,/*8_2*/2,3]; +//// [ +//// 1,/*8_3*/2,3]; +//// [1,2,3/*8_4*/]; +//// [ +//// 1,2,3/*8_5*/]; +//// [1,2,3]/*8_6*/; +//// [ +//// 1,2,3]/*8_7*/; +//// } + +for (let i = 0; i < 8; ++i) { + goTo.marker(`8_${i}`); + edit.insertLine(""); + verify.indentationIs(8); +} diff --git a/tests/cases/fourslash/indentationInAssignment.ts b/tests/cases/fourslash/indentationInAssignment.ts new file mode 100644 index 00000000000..253cb30cf38 --- /dev/null +++ b/tests/cases/fourslash/indentationInAssignment.ts @@ -0,0 +1,37 @@ +/// + +//// var v0 = /*4_0*/ +//// 1; +//// +//// let v1 = 1 /*4_1*/ +//// + 10; +//// +//// let v2 = 1 + /*4_2*/ +//// 1; +//// +//// let v3 = 1 + (function /*0_0*/(x: number, y: number) { return x || y; })(0, 1); +//// +//// let v4 = 1 + (function (x: number, /*4_3*/y: number) { return x || y; })(0, 1); +//// +//// let v5 = 1 + (function (x: number, y: number) { /*4_4*/return x || y; })(0, 1); +//// +//// let v6 = 1 + (function (x: number, y: number) { return x || y;/*0_1*/})(0, 1); +//// +//// let v7 = 1 + (function (x: number, y: number) { +//// return x || y;/*4_5*/ +//// })(0, 1); +//// +//// let v8 = 1 + (function (x: number, y: number) { return x || y; })(0, /*4_6*/1); + + +for (let i = 0; i < 2; ++i) { + goTo.marker(`0_${i}`); + edit.insertLine(""); + verify.indentationIs(0); +} + +for (let i = 0; i < 7; ++i) { + goTo.marker(`4_${i}`); + edit.insertLine(""); + verify.indentationIs(4); +} \ No newline at end of file diff --git a/tests/cases/fourslash/indentationInAsyncExpressions.ts b/tests/cases/fourslash/indentationInAsyncExpressions.ts new file mode 100644 index 00000000000..5273dcbd97a --- /dev/null +++ b/tests/cases/fourslash/indentationInAsyncExpressions.ts @@ -0,0 +1,16 @@ +/// + + +//// async function* foo() { +//// yield /*8_0*/await 1; +//// yield await /*8_1*/1; +//// yield +//// await /*8_2*/1; +//// yield await 1/*8_3*/; +//// } + +for (let i = 0; i < 4; ++i) { + goTo.marker(`8_${i}`); + edit.insertLine(""); + verify.indentationIs(8); +} \ No newline at end of file diff --git a/tests/cases/fourslash/indentationInClassExpression.ts b/tests/cases/fourslash/indentationInClassExpression.ts new file mode 100644 index 00000000000..77ac668790a --- /dev/null +++ b/tests/cases/fourslash/indentationInClassExpression.ts @@ -0,0 +1,31 @@ +/// + +////function foo() { +//// let x: any; +//// x = /*8_0*/class { constructor(public x: number) { } }; +//// x = class /*4_0*/{ constructor(public x: number) { } }; +//// x = class { /*8_1*/constructor(public x: number) { } }; +//// x = class { constructor(/*12_0*/public x: number) { } }; +//// x = class { constructor(public /*12_1*/x: number) { } }; +//// x = class { constructor(public x: number) {/*8_2*/ } }; +//// x = class { +//// constructor(/*12_2*/public x: number) { } +//// }; +//// x = class { +//// constructor(public x: number) {/*8_3*/ } +//// }; +//// x = class { +//// constructor(public x: number) { }/*4_1*/}; +////} + +function verifyIndentation(level: number, count: number) { + for (let i = 0; i < count; ++i) { + goTo.marker(`${level}_${i}`); + edit.insertLine(""); + verify.indentationIs(level); + } +} + +verifyIndentation(4, 2); +verifyIndentation(8, 4); +verifyIndentation(12, 3); \ No newline at end of file diff --git a/tests/cases/fourslash/indentationInObject.ts b/tests/cases/fourslash/indentationInObject.ts new file mode 100644 index 00000000000..2acb651c933 --- /dev/null +++ b/tests/cases/fourslash/indentationInObject.ts @@ -0,0 +1,30 @@ +/// + +//// function foo() { +//// {/*8_0*/x:1;y:2;z:3}; +//// {x:1/*12_0*/;y:2;z:3}; +//// {x:1;/*8_1*/y:2;z:3}; +//// { +//// x:1;/*8_2*/y:2;z:3}; +//// {x:1;y:2;z:3/*4_0*/}; +//// { +//// x:1;y:2;z:3/*4_1*/}; +//// {x:1;y:2;z:3}/*4_2*/; +//// { +//// x:1;y:2;z:3}/*4_3*/; +//// } + +for (let i = 0; i < 4; ++i) { + goTo.marker(`4_${i}`); + edit.insertLine(""); + verify.indentationIs(4); +} +for (let i = 0; i < 3; ++i) { + goTo.marker(`8_${i}`); + edit.insertLine(""); + verify.indentationIs(8); +} + + goTo.marker(`12_0`); + edit.insertLine(""); + verify.indentationIs(12); From cc8770390c8419a14d8563407a368a6f63eb3aef Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Wed, 20 Sep 2017 10:23:45 -0700 Subject: [PATCH 011/312] remove newline --- src/services/textChanges.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index b4a2d3e07e2..f3ad7df1607 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -553,7 +553,6 @@ namespace ts.textChanges { const posStartsLine = getLineStartPositionForPosition(pos, sourceFile) === pos; const initialIndentation = - options.indentation !== undefined ? options.indentation : (options.useIndentationFromFile !== false) From db78d5a5875becd3859aa414263c9ca6f91aabc2 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 21 Sep 2017 16:53:38 -0700 Subject: [PATCH 012/312] add error message test --- src/harness/unittests/session.ts | 55 ++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index 18109cfa9db..58d8c1b66d8 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -386,6 +386,61 @@ namespace ts.server { }); }); + describe("exceptions", () => { + const command = "testhandler"; + class TestSession extends Session { + lastSent: protocol.Message; + private exceptionRaisingHandler(_request: protocol.Request): { response?: any, responseRequired: boolean } { + f1(); + return; + function f1() { + throw new Error("myMessage"); + } + } + + constructor() { + super({ + host: mockHost, + cancellationToken: nullCancellationToken, + useSingleInferredProject: false, + useInferredProjectPerProjectRoot: false, + typingsInstaller: undefined, + byteLength: Utils.byteLength, + hrtime: process.hrtime, + logger: projectSystem.nullLogger, + canUseEvents: true + }); + this.addProtocolHandler(command, this.exceptionRaisingHandler); + } + send(msg: protocol.Message) { + this.lastSent = msg; + } + } + + it("raised in a protocol handler generate an event", () => { + + const session = new TestSession(); + + const request = { + command, + seq: 0, + type: "request" + }; + + session.onMessage(JSON.stringify(request)); + const lastSent = session.lastSent as protocol.Response; + + expect(lastSent).to.contain({ + seq: 0, + type: "response", + command, + success: false + }); + + expect(lastSent.message).has.string("myMessage").and.has.string("f1"); + }); + }); + describe("how Session is extendable via subclassing", () => { class TestSession extends Session { lastSent: protocol.Message; From b21c46b9b56d1d8cf7a6ebe71dd26f43015fc552 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 22 Sep 2017 16:21:31 -0700 Subject: [PATCH 013/312] support @extends in jsdoc --- src/compiler/checker.ts | 4 +- src/compiler/parser.ts | 12 +- src/compiler/types.ts | 11 +- src/compiler/utilities.ts | 8 +- src/services/completions.ts | 4 +- tests/baselines/reference/APISample_jsdoc.js | 4 +- tests/cases/compiler/APISample_jsdoc.ts | 232 +++++++++---------- tests/cases/fourslash/jsDocAugments.ts | 3 +- tests/cases/fourslash/jsDocExtends.ts | 22 ++ 9 files changed, 164 insertions(+), 136 deletions(-) create mode 100644 tests/cases/fourslash/jsDocExtends.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5c835582da0..2dbfa6bd409 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4986,10 +4986,10 @@ namespace ts { baseType = getReturnTypeOfSignature(constructors[0]); } - // In a JS file, you can use the @augments jsdoc tag to specify a base type with type parameters + // In a JS file, you can use the @augments and @extends jsdoc tags to specify a base type with type parameters const valueDecl = type.symbol.valueDeclaration; if (valueDecl && isInJavaScriptFile(valueDecl)) { - const augTag = getJSDocAugmentsTag(type.symbol.valueDeclaration); + const augTag = getJSDocAugmentsOrExtendsTag(type.symbol.valueDeclaration); if (augTag) { baseType = getTypeFromTypeNode(augTag.typeExpression.type); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 3809a071421..7e9ac8c5804 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -423,8 +423,9 @@ namespace ts { return visitNode(cbNode, (node).typeExpression); case SyntaxKind.JSDocTypeTag: return visitNode(cbNode, (node).typeExpression); - case SyntaxKind.JSDocAugmentsTag: - return visitNode(cbNode, (node).typeExpression); + case SyntaxKind.JSDocAugmentsOrExtendsTag: + case SyntaxKind.JSDocExtendsTag: + return visitNode(cbNode, (node).typeExpression); case SyntaxKind.JSDocTemplateTag: return visitNodes(cbNode, cbNodes, (node).typeParameters); case SyntaxKind.JSDocTypedefTag: @@ -6366,7 +6367,8 @@ namespace ts { if (tagName) { switch (tagName.escapedText) { case "augments": - tag = parseAugmentsTag(atToken, tagName); + case "extends": + tag = parseAugmentsOrExtendsTag(atToken, tagName); break; case "class": case "constructor": @@ -6603,10 +6605,10 @@ namespace ts { return finishNode(result); } - function parseAugmentsTag(atToken: AtToken, tagName: Identifier): JSDocAugmentsTag { + function parseAugmentsOrExtendsTag(atToken: AtToken, tagName: Identifier): JSDocAugmentsOrExtendsTag { const typeExpression = tryParseTypeExpression(); - const result = createNode(SyntaxKind.JSDocAugmentsTag, atToken.pos); + const result = createNode(SyntaxKind.JSDocAugmentsOrExtendsTag, atToken.pos); result.atToken = atToken; result.tagName = tagName; result.typeExpression = typeExpression; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4e5ca9f07e7..e8f54236798 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -363,7 +363,8 @@ namespace ts { JSDocVariadicType, JSDocComment, JSDocTag, - JSDocAugmentsTag, + JSDocAugmentsOrExtendsTag, + JSDocExtendsTag, JSDocClassTag, JSDocParameterTag, JSDocReturnTag, @@ -2159,8 +2160,12 @@ namespace ts { kind: SyntaxKind.JSDocTag; } - export interface JSDocAugmentsTag extends JSDocTag { - kind: SyntaxKind.JSDocAugmentsTag; + /** + * Note that `@extends` is a synonym of `@augments`. + * Both are covered by this interface. + */ + export interface JSDocAugmentsOrExtendsTag extends JSDocTag { + kind: SyntaxKind.JSDocAugmentsOrExtendsTag; typeExpression: JSDocTypeExpression; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 674215b0583..f9a0c4c38ab 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4072,8 +4072,8 @@ namespace ts { } /** Gets the JSDoc augments tag for the node if present */ - export function getJSDocAugmentsTag(node: Node): JSDocAugmentsTag | undefined { - return getFirstJSDocTag(node, SyntaxKind.JSDocAugmentsTag) as JSDocAugmentsTag; + export function getJSDocAugmentsOrExtendsTag(node: Node): JSDocAugmentsOrExtendsTag | undefined { + return getFirstJSDocTag(node, SyntaxKind.JSDocAugmentsOrExtendsTag) as JSDocAugmentsOrExtendsTag; } /** Gets the JSDoc class tag for the node if present */ @@ -4765,8 +4765,8 @@ namespace ts { return node.kind === SyntaxKind.JSDocComment; } - export function isJSDocAugmentsTag(node: Node): node is JSDocAugmentsTag { - return node.kind === SyntaxKind.JSDocAugmentsTag; + export function isJSDocAugmentsOrExtendsTag(node: Node): node is JSDocAugmentsOrExtendsTag { + return node.kind === SyntaxKind.JSDocAugmentsOrExtendsTag; } export function isJSDocParameterTag(node: Node): node is JSDocParameterTag { diff --git a/src/services/completions.ts b/src/services/completions.ts index e271ef12104..a954f687cb5 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -581,11 +581,11 @@ namespace ts.Completions { return { symbols, isGlobalCompletion, isMemberCompletion, allowStringLiteral, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), request, keywordFilters }; - type JSDocTagWithTypeExpression = JSDocAugmentsTag | JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag; + type JSDocTagWithTypeExpression = JSDocAugmentsOrExtendsTag | JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag; function isTagWithTypeExpression(tag: JSDocTag): tag is JSDocTagWithTypeExpression { switch (tag.kind) { - case SyntaxKind.JSDocAugmentsTag: + case SyntaxKind.JSDocAugmentsOrExtendsTag: case SyntaxKind.JSDocParameterTag: case SyntaxKind.JSDocPropertyTag: case SyntaxKind.JSDocReturnTag: diff --git a/tests/baselines/reference/APISample_jsdoc.js b/tests/baselines/reference/APISample_jsdoc.js index c74e188f38b..33857d06a6a 100644 --- a/tests/baselines/reference/APISample_jsdoc.js +++ b/tests/baselines/reference/APISample_jsdoc.js @@ -101,7 +101,7 @@ function getAllTags(node: ts.Node) { function getSomeOtherTags(node: ts.Node) { const tags: (ts.JSDocTag | undefined)[] = []; - tags.push(ts.getJSDocAugmentsTag(node)); + tags.push(ts.getJSDocAugmentsOrExtendsTag(node)); tags.push(ts.getJSDocClassTag(node)); tags.push(ts.getJSDocReturnTag(node)); const type = ts.getJSDocTypeTag(node); @@ -200,7 +200,7 @@ function getAllTags(node) { } function getSomeOtherTags(node) { var tags = []; - tags.push(ts.getJSDocAugmentsTag(node)); + tags.push(ts.getJSDocAugmentsOrExtendsTag(node)); tags.push(ts.getJSDocClassTag(node)); tags.push(ts.getJSDocReturnTag(node)); var type = ts.getJSDocTypeTag(node); diff --git a/tests/cases/compiler/APISample_jsdoc.ts b/tests/cases/compiler/APISample_jsdoc.ts index 70b814ffff4..491ff2b7a20 100644 --- a/tests/cases/compiler/APISample_jsdoc.ts +++ b/tests/cases/compiler/APISample_jsdoc.ts @@ -1,116 +1,116 @@ -// @module: commonjs -// @includebuiltfile: typescript_standalone.d.ts -// @strict:true - -/* - * Note: This test is a public API sample. The original sources can be found - * at: https://github.com/YousefED/typescript-json-schema - * https://github.com/vega/ts-json-schema-generator - * Please log a "breaking change" issue for any API breaking change affecting this issue - */ - -declare var console: any; - -import * as ts from "typescript"; - -// excerpted from https://github.com/YousefED/typescript-json-schema -// (converted from a method and modified; for example, `this: any` to compensate, among other changes) -function parseCommentsIntoDefinition(this: any, - symbol: ts.Symbol, - definition: {description?: string, [s: string]: string | undefined}, - otherAnnotations: { [s: string]: true}): void { - if (!symbol) { - return; - } - - // the comments for a symbol - let comments = symbol.getDocumentationComment(); - - if (comments.length) { - definition.description = comments.map(comment => comment.kind === "lineBreak" ? comment.text : comment.text.trim().replace(/\r\n/g, "\n")).join(""); - } - - // jsdocs are separate from comments - const jsdocs = symbol.getJsDocTags(); - jsdocs.forEach(doc => { - // if we have @TJS-... annotations, we have to parse them - const { name, text } = doc; - if (this.userValidationKeywords[name]) { - definition[name] = this.parseValue(text); - } else { - // special annotations - otherAnnotations[doc.name] = true; - } - }); -} - - -// excerpted from https://github.com/vega/ts-json-schema-generator -export interface Annotations { - [name: string]: any; -} -function getAnnotations(this: any, node: ts.Node): Annotations | undefined { - const symbol: ts.Symbol = (node as any).symbol; - if (!symbol) { - return undefined; - } - - const jsDocTags: ts.JSDocTagInfo[] = symbol.getJsDocTags(); - if (!jsDocTags || !jsDocTags.length) { - return undefined; - } - - const annotations: Annotations = jsDocTags.reduce((result: Annotations, jsDocTag: ts.JSDocTagInfo) => { - const value = this.parseJsDocTag(jsDocTag); - if (value !== undefined) { - result[jsDocTag.name] = value; - } - - return result; - }, {}); - return Object.keys(annotations).length ? annotations : undefined; -} - -// these examples are artificial and mostly nonsensical -function parseSpecificTags(node: ts.Node) { - if (node.kind === ts.SyntaxKind.Parameter) { - return ts.getJSDocParameterTags(node as ts.ParameterDeclaration); - } - if (node.kind === ts.SyntaxKind.FunctionDeclaration) { - const func = node as ts.FunctionDeclaration; - if (ts.hasJSDocParameterTags(func)) { - const flat: ts.JSDocTag[] = []; - for (const tags of func.parameters.map(ts.getJSDocParameterTags)) { - if (tags) flat.push(...tags); - } - return flat; - } - } -} - -function getReturnTypeFromJSDoc(node: ts.Node) { - if (node.kind === ts.SyntaxKind.FunctionDeclaration) { - return ts.getJSDocReturnType(node); - } - let type = ts.getJSDocType(node); - if (type && type.kind === ts.SyntaxKind.FunctionType) { - return (type as ts.FunctionTypeNode).type; - } -} - -function getAllTags(node: ts.Node) { - ts.getJSDocTags(node); -} - -function getSomeOtherTags(node: ts.Node) { - const tags: (ts.JSDocTag | undefined)[] = []; - tags.push(ts.getJSDocAugmentsTag(node)); - tags.push(ts.getJSDocClassTag(node)); - tags.push(ts.getJSDocReturnTag(node)); - const type = ts.getJSDocTypeTag(node); - if (type) { - tags.push(type); - } - tags.push(ts.getJSDocTemplateTag(node)); - return tags; -} +// @module: commonjs +// @includebuiltfile: typescript_standalone.d.ts +// @strict:true + +/* + * Note: This test is a public API sample. The original sources can be found + * at: https://github.com/YousefED/typescript-json-schema + * https://github.com/vega/ts-json-schema-generator + * Please log a "breaking change" issue for any API breaking change affecting this issue + */ + +declare var console: any; + +import * as ts from "typescript"; + +// excerpted from https://github.com/YousefED/typescript-json-schema +// (converted from a method and modified; for example, `this: any` to compensate, among other changes) +function parseCommentsIntoDefinition(this: any, + symbol: ts.Symbol, + definition: {description?: string, [s: string]: string | undefined}, + otherAnnotations: { [s: string]: true}): void { + if (!symbol) { + return; + } + + // the comments for a symbol + let comments = symbol.getDocumentationComment(); + + if (comments.length) { + definition.description = comments.map(comment => comment.kind === "lineBreak" ? comment.text : comment.text.trim().replace(/\r\n/g, "\n")).join(""); + } + + // jsdocs are separate from comments + const jsdocs = symbol.getJsDocTags(); + jsdocs.forEach(doc => { + // if we have @TJS-... annotations, we have to parse them + const { name, text } = doc; + if (this.userValidationKeywords[name]) { + definition[name] = this.parseValue(text); + } else { + // special annotations + otherAnnotations[doc.name] = true; + } + }); +} + + +// excerpted from https://github.com/vega/ts-json-schema-generator +export interface Annotations { + [name: string]: any; +} +function getAnnotations(this: any, node: ts.Node): Annotations | undefined { + const symbol: ts.Symbol = (node as any).symbol; + if (!symbol) { + return undefined; + } + + const jsDocTags: ts.JSDocTagInfo[] = symbol.getJsDocTags(); + if (!jsDocTags || !jsDocTags.length) { + return undefined; + } + + const annotations: Annotations = jsDocTags.reduce((result: Annotations, jsDocTag: ts.JSDocTagInfo) => { + const value = this.parseJsDocTag(jsDocTag); + if (value !== undefined) { + result[jsDocTag.name] = value; + } + + return result; + }, {}); + return Object.keys(annotations).length ? annotations : undefined; +} + +// these examples are artificial and mostly nonsensical +function parseSpecificTags(node: ts.Node) { + if (node.kind === ts.SyntaxKind.Parameter) { + return ts.getJSDocParameterTags(node as ts.ParameterDeclaration); + } + if (node.kind === ts.SyntaxKind.FunctionDeclaration) { + const func = node as ts.FunctionDeclaration; + if (ts.hasJSDocParameterTags(func)) { + const flat: ts.JSDocTag[] = []; + for (const tags of func.parameters.map(ts.getJSDocParameterTags)) { + if (tags) flat.push(...tags); + } + return flat; + } + } +} + +function getReturnTypeFromJSDoc(node: ts.Node) { + if (node.kind === ts.SyntaxKind.FunctionDeclaration) { + return ts.getJSDocReturnType(node); + } + let type = ts.getJSDocType(node); + if (type && type.kind === ts.SyntaxKind.FunctionType) { + return (type as ts.FunctionTypeNode).type; + } +} + +function getAllTags(node: ts.Node) { + ts.getJSDocTags(node); +} + +function getSomeOtherTags(node: ts.Node) { + const tags: (ts.JSDocTag | undefined)[] = []; + tags.push(ts.getJSDocAugmentsOrExtendsTag(node)); + tags.push(ts.getJSDocClassTag(node)); + tags.push(ts.getJSDocReturnTag(node)); + const type = ts.getJSDocTypeTag(node); + if (type) { + tags.push(type); + } + tags.push(ts.getJSDocTemplateTag(node)); + return tags; +} diff --git a/tests/cases/fourslash/jsDocAugments.ts b/tests/cases/fourslash/jsDocAugments.ts index 24458c529fb..cd2190e5486 100644 --- a/tests/cases/fourslash/jsDocAugments.ts +++ b/tests/cases/fourslash/jsDocAugments.ts @@ -15,9 +15,8 @@ // @Filename: declarations.d.ts //// declare class Thing { -//// mine: T; +//// mine: T; //// } goTo.marker(); verify.quickInfoIs("(local var) x: string"); - diff --git a/tests/cases/fourslash/jsDocExtends.ts b/tests/cases/fourslash/jsDocExtends.ts new file mode 100644 index 00000000000..6bce5569533 --- /dev/null +++ b/tests/cases/fourslash/jsDocExtends.ts @@ -0,0 +1,22 @@ +/// + +// @allowJs: true +// @Filename: dummy.js + +//// /** +//// * @extends {Thing} +//// */ +//// class MyStringThing extends Thing { +//// constructor() { +//// var x = this.mine; +//// x/**/; +//// } +//// } + +// @Filename: declarations.d.ts +//// declare class Thing { +//// mine: T; +//// } + +goTo.marker(); +verify.quickInfoIs("(local var) x: string"); From 6d218e2a48ac9ed05a843707a08f4a44851721f1 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 25 Sep 2017 08:56:51 -0700 Subject: [PATCH 014/312] Refactor JSDoc types to Typescript types When the caret is on a Typescript declaration that has no type, but does have a JSDoc annotation with a type, this refactor will add the Typescript equivalent of the JSDoc type. Notes: 1. This doesn't delete the JSDoc comment or delete parts of it. In fact, due to bugs in trivia handling, it sometimes duplicates the comment. These bugs are tracked in #18626. 2. As a bonus, when `noImplicitAny: true`, this shows up as a code fix in VS Code whenever there is a no-implicit-any error. With `noImplicityAny: false`, this code must be invoked via the refactoring command. --- src/compiler/diagnosticMessages.json | 4 + src/compiler/emitter.ts | 46 +++++- src/compiler/utilities.ts | 9 +- src/services/refactors/convertJSDocToTypes.ts | 137 ++++++++++++++++++ src/services/refactors/refactors.ts | 1 + 5 files changed, 193 insertions(+), 4 deletions(-) create mode 100644 src/services/refactors/convertJSDocToTypes.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 662e87d3159..b3741af80e8 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3703,5 +3703,9 @@ "Extract to {0}": { "category": "Message", "code": 95004 + }, + "Convert to Typescript type": { + "category": "Message", + "code": 95005 } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index d458e7e5ef5..80b08c60d34 100755 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -545,6 +545,7 @@ namespace ts { case SyntaxKind.TypeReference: return emitTypeReference(node); case SyntaxKind.FunctionType: + case SyntaxKind.JSDocFunctionType: return emitFunctionType(node); case SyntaxKind.ConstructorType: return emitConstructorType(node); @@ -574,6 +575,18 @@ namespace ts { return emitMappedType(node); case SyntaxKind.LiteralType: return emitLiteralType(node); + case SyntaxKind.JSDocAllType: + case SyntaxKind.JSDocUnknownType: + write("any"); + break; + case SyntaxKind.JSDocNullableType: + return emitJSDocNullableType(node as JSDocNullableType); + case SyntaxKind.JSDocNonNullableType: + return emitJSDocNonNullableType(node as JSDocNonNullableType); + case SyntaxKind.JSDocOptionalType: + return emitJSDocOptionalType(node as JSDocOptionalType); + case SyntaxKind.JSDocVariadicType: + return emitJSDocVariadicType(node as JSDocVariadicType); // Binding patterns case SyntaxKind.ObjectBindingPattern: @@ -914,7 +927,15 @@ namespace ts { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emitIfPresent(node.dotDotDotToken); - emit(node.name); + if (node.name) { + emit(node.name); + } + else if (node.parent.kind === SyntaxKind.JSDocFunctionType) { + const i = (node.parent as JSDocFunctionType).parameters.indexOf(node); + if (i > -1) { + write("arg" + i); + } + } emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); @@ -1035,6 +1056,20 @@ namespace ts { emit(node.type); } + function emitJSDocNullableType(node: JSDocNullableType) { + emit(node.type); + write(" | null"); + } + + function emitJSDocNonNullableType(node: JSDocNonNullableType) { + emit(node.type); + } + + function emitJSDocOptionalType(node: JSDocOptionalType) { + emit(node.type); + write(" | undefined"); + } + function emitConstructorType(node: ConstructorTypeNode) { write("new "); emitTypeParameters(node, node.typeParameters); @@ -1060,6 +1095,11 @@ namespace ts { write("[]"); } + function emitJSDocVariadicType(node: JSDocVariadicType) { + emit(node.type); + write("[]"); + } + function emitTupleType(node: TupleTypeNode) { write("["); emitList(node, node.elementTypes, ListFormat.TupleTypeElements); @@ -2357,7 +2397,7 @@ namespace ts { emitList(parentNode, parameters, ListFormat.Parameters); } - function canEmitSimpleArrowHead(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray) { + function canEmitSimpleArrowHead(parentNode: FunctionTypeNode | ArrowFunction | JSDocFunctionType, parameters: NodeArray) { const parameter = singleOrUndefined(parameters); return parameter && parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter @@ -2374,7 +2414,7 @@ namespace ts { && isIdentifier(parameter.name); // parameter name must be identifier } - function emitParametersForArrow(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray) { + function emitParametersForArrow(parentNode: FunctionTypeNode | ArrowFunction | JSDocFunctionType, parameters: NodeArray) { if (canEmitSimpleArrowHead(parentNode, parameters)) { emitList(parentNode, parameters, ListFormat.Parameters & ~ListFormat.Parenthesis); } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index cc7002ca059..2fee52f1e3f 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -5034,7 +5034,14 @@ namespace ts { || kind === SyntaxKind.UndefinedKeyword || kind === SyntaxKind.NullKeyword || kind === SyntaxKind.NeverKeyword - || kind === SyntaxKind.ExpressionWithTypeArguments; + || kind === SyntaxKind.ExpressionWithTypeArguments + || kind === SyntaxKind.JSDocAllType + || kind === SyntaxKind.JSDocUnknownType + || kind === SyntaxKind.JSDocNullableType + || kind === SyntaxKind.JSDocNonNullableType + || kind === SyntaxKind.JSDocOptionalType + || kind === SyntaxKind.JSDocFunctionType + || kind === SyntaxKind.JSDocVariadicType; } /** diff --git a/src/services/refactors/convertJSDocToTypes.ts b/src/services/refactors/convertJSDocToTypes.ts new file mode 100644 index 00000000000..562c26bf50f --- /dev/null +++ b/src/services/refactors/convertJSDocToTypes.ts @@ -0,0 +1,137 @@ +/* @internal */ +namespace ts.refactor.convertJSDocToTypes { + const actionName = "convert"; + + const convertJSDocToTypes: Refactor = { + name: "Convert to Typescript type", + description: Diagnostics.Convert_to_Typescript_type.message, + getEditsForAction, + getAvailableActions + }; + + type DeclarationWithType = + | FunctionLikeDeclaration + | VariableDeclaration + | ParameterDeclaration + | PropertySignature + | PropertyDeclaration; + + registerRefactor(convertJSDocToTypes); + + function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { + if (isInJavaScriptFile(context.file)) { + return undefined; + } + + const node = getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false); + const decl = findAncestor(node, isTypedNode); + if (decl && (getJSDocType(decl) || getJSDocReturnType(decl)) && !decl.type) { + return [ + { + name: convertJSDocToTypes.name, + description: convertJSDocToTypes.description, + actions: [ + { + description: convertJSDocToTypes.description, + name: actionName + } + ] + } + ]; + } + } + + function getEditsForAction(context: RefactorContext, action: string): RefactorEditInfo | undefined { + // Somehow wrong action got invoked? + if (actionName !== action) { + Debug.fail(`actionName !== action: ${actionName} !== ${action}`); + return undefined; + } + + const start = context.startPosition; + const sourceFile = context.file; + const token = getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); + const decl = findAncestor(token, isTypedNode); + const jsdocType = getJSDocType(decl); + const jsdocReturn = getJSDocReturnType(decl); + if (!decl || !jsdocType && !jsdocReturn || decl.type) { + Debug.fail(`!decl || !jsdocType && !jsdocReturn || decl.type: !${decl} || !${jsdocType} && !{jsdocReturn} || ${decl.type}`); + return undefined; + } + + const changeTracker = textChanges.ChangeTracker.fromContext(context); + if (isParameterOfSimpleArrowFunction(decl)) { + // `x => x` becomes `(x: number) => x`, but in order to make the changeTracker generate the parentheses, + // we have to replace the entire function; it doesn't check that the node it's replacing might require + // other syntax changes + const arrow = decl.parent as ArrowFunction; + const param = decl as ParameterDeclaration; + const replacementParam = createParameter(param.decorators, param.modifiers, param.dotDotDotToken, param.name, param.questionToken, jsdocType, param.initializer); + const replacement = createArrowFunction(arrow.modifiers, arrow.typeParameters, [replacementParam], arrow.type, arrow.equalsGreaterThanToken, arrow.body); + changeTracker.replaceRange(sourceFile, { pos: arrow.getStart(), end: arrow.end }, replacement); + } + else { + changeTracker.replaceRange(sourceFile, { pos: decl.getStart(), end: decl.end }, replaceType(decl, jsdocType, jsdocReturn)); + } + return { + edits: changeTracker.getChanges(), + renameFilename: undefined, + renameLocation: undefined + }; + } + + function isTypedNode(node: Node): node is DeclarationWithType { + return isFunctionLikeDeclaration(node) || + node.kind === SyntaxKind.VariableDeclaration || + node.kind === SyntaxKind.Parameter || + node.kind === SyntaxKind.PropertySignature || + node.kind === SyntaxKind.PropertyDeclaration; + } + + function replaceType(decl: DeclarationWithType, jsdocType: TypeNode, jsdocReturn: TypeNode) { + switch (decl.kind) { + case SyntaxKind.VariableDeclaration: + return createVariableDeclaration(decl.name, jsdocType, decl.initializer); + case SyntaxKind.Parameter: + return createParameter(decl.decorators, decl.modifiers, decl.dotDotDotToken, decl.name, decl.questionToken, jsdocType, decl.initializer); + case SyntaxKind.PropertySignature: + return createPropertySignature(decl.modifiers, decl.name, decl.questionToken, jsdocType, decl.initializer); + case SyntaxKind.PropertyDeclaration: + return createProperty(decl.decorators, decl.modifiers, decl.name, decl.questionToken, jsdocType, decl.initializer); + case SyntaxKind.FunctionDeclaration: + return createFunctionDeclaration(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.typeParameters, decl.parameters, jsdocReturn, decl.body); + case SyntaxKind.FunctionExpression: + return createFunctionExpression(decl.modifiers, decl.asteriskToken, decl.name, decl.typeParameters, decl.parameters, jsdocReturn, decl.body); + case SyntaxKind.ArrowFunction: + return createArrowFunction(decl.modifiers, decl.typeParameters, decl.parameters, jsdocReturn, decl.equalsGreaterThanToken, decl.body); + case SyntaxKind.MethodDeclaration: + return createMethod(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.questionToken, decl.typeParameters, decl.parameters, jsdocReturn, decl.body); + case SyntaxKind.GetAccessor: + return createGetAccessor(decl.decorators, decl.modifiers, decl.name, decl.parameters, jsdocReturn, decl.body); + default: + Debug.fail(`Unexpected SyntaxKind: ${decl.kind}`); + return undefined; + } + } + + function isParameterOfSimpleArrowFunction(decl: DeclarationWithType) { + return decl.kind === SyntaxKind.Parameter && decl.parent.kind === SyntaxKind.ArrowFunction && isSimpleArrowFunction(decl.parent); + } + + function isSimpleArrowFunction(parentNode: FunctionTypeNode | ArrowFunction | JSDocFunctionType) { + const parameter = singleOrUndefined(parentNode.parameters); + return parameter + && parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter + && !(isArrowFunction(parentNode) && parentNode.type) // arrow function may not have return type annotation + && !some(parentNode.decorators) // parent may not have decorators + && !some(parentNode.modifiers) // parent may not have modifiers + && !some(parentNode.typeParameters) // parent may not have type parameters + && !some(parameter.decorators) // parameter may not have decorators + && !some(parameter.modifiers) // parameter may not have modifiers + && !parameter.dotDotDotToken // parameter may not be rest + && !parameter.questionToken // parameter may not be optional + && !parameter.type // parameter may not have a type annotation + && !parameter.initializer // parameter may not have an initializer + && isIdentifier(parameter.name); // parameter name must be identifier + } +} diff --git a/src/services/refactors/refactors.ts b/src/services/refactors/refactors.ts index 3a33ccc83c2..d1d50cb50f9 100644 --- a/src/services/refactors/refactors.ts +++ b/src/services/refactors/refactors.ts @@ -1,2 +1,3 @@ +/// /// /// From 8996d11096d3c1de718883de97991b1a41fd3f70 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 25 Sep 2017 09:02:42 -0700 Subject: [PATCH 015/312] Test:refactor JSDoc types to Typescript types --- tests/cases/fourslash/convertJSDocToTypes1.ts | 10 ++ .../cases/fourslash/convertJSDocToTypes10.ts | 15 +++ .../cases/fourslash/convertJSDocToTypes11.ts | 15 +++ .../cases/fourslash/convertJSDocToTypes12.ts | 21 ++++ .../cases/fourslash/convertJSDocToTypes13.ts | 11 ++ tests/cases/fourslash/convertJSDocToTypes2.ts | 6 + tests/cases/fourslash/convertJSDocToTypes3.ts | 54 ++++++++ tests/cases/fourslash/convertJSDocToTypes4.ts | 115 ++++++++++++++++++ tests/cases/fourslash/convertJSDocToTypes5.ts | 15 +++ tests/cases/fourslash/convertJSDocToTypes6.ts | 15 +++ tests/cases/fourslash/convertJSDocToTypes7.ts | 17 +++ tests/cases/fourslash/convertJSDocToTypes8.ts | 17 +++ tests/cases/fourslash/convertJSDocToTypes9.ts | 15 +++ 13 files changed, 326 insertions(+) create mode 100644 tests/cases/fourslash/convertJSDocToTypes1.ts create mode 100644 tests/cases/fourslash/convertJSDocToTypes10.ts create mode 100644 tests/cases/fourslash/convertJSDocToTypes11.ts create mode 100644 tests/cases/fourslash/convertJSDocToTypes12.ts create mode 100644 tests/cases/fourslash/convertJSDocToTypes13.ts create mode 100644 tests/cases/fourslash/convertJSDocToTypes2.ts create mode 100644 tests/cases/fourslash/convertJSDocToTypes3.ts create mode 100644 tests/cases/fourslash/convertJSDocToTypes4.ts create mode 100644 tests/cases/fourslash/convertJSDocToTypes5.ts create mode 100644 tests/cases/fourslash/convertJSDocToTypes6.ts create mode 100644 tests/cases/fourslash/convertJSDocToTypes7.ts create mode 100644 tests/cases/fourslash/convertJSDocToTypes8.ts create mode 100644 tests/cases/fourslash/convertJSDocToTypes9.ts diff --git a/tests/cases/fourslash/convertJSDocToTypes1.ts b/tests/cases/fourslash/convertJSDocToTypes1.ts new file mode 100644 index 00000000000..7f90febaca1 --- /dev/null +++ b/tests/cases/fourslash/convertJSDocToTypes1.ts @@ -0,0 +1,10 @@ +/// + +// @Filename: test123.ts +/////** @type {number} */ +////var /*1*/x; + +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`/** @type {number} */ +var x: number;`, 'Convert to Typescript type', 'convert'); diff --git a/tests/cases/fourslash/convertJSDocToTypes10.ts b/tests/cases/fourslash/convertJSDocToTypes10.ts new file mode 100644 index 00000000000..1e925db81e0 --- /dev/null +++ b/tests/cases/fourslash/convertJSDocToTypes10.ts @@ -0,0 +1,15 @@ +/// + +/////** +//// * @param {?} x +//// * @returns {number} +//// */ +////var f = /*1*/(/*2*/x) => x + +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`/** + * @param {?} x + * @returns {number} + */ +var f = (x): number => x`, 'Convert to Typescript type', 'convert'); diff --git a/tests/cases/fourslash/convertJSDocToTypes11.ts b/tests/cases/fourslash/convertJSDocToTypes11.ts new file mode 100644 index 00000000000..0315e506dc1 --- /dev/null +++ b/tests/cases/fourslash/convertJSDocToTypes11.ts @@ -0,0 +1,15 @@ +/// + +/////** +//// * @param {?} x +//// * @returns {number} +//// */ +////var f = /*1*/(/*2*/x) => x + +verify.applicableRefactorAvailableAtMarker('2'); +verify.fileAfterApplyingRefactorAtMarker('2', +`/** + * @param {?} x + * @returns {number} + */ +var f = (x: any) => x`, 'Convert to Typescript type', 'convert'); diff --git a/tests/cases/fourslash/convertJSDocToTypes12.ts b/tests/cases/fourslash/convertJSDocToTypes12.ts new file mode 100644 index 00000000000..5015cb825d8 --- /dev/null +++ b/tests/cases/fourslash/convertJSDocToTypes12.ts @@ -0,0 +1,21 @@ +/// + +////class C { +//// /** +//// * @return {...*} +//// */ +//// /*1*/m(x) { +//// } +////} +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`class C { + /** + * @return {...*} + */ + /** + * @return {...*} + */ + m(x): any[] { + } +}`, 'Convert to Typescript type', 'convert'); diff --git a/tests/cases/fourslash/convertJSDocToTypes13.ts b/tests/cases/fourslash/convertJSDocToTypes13.ts new file mode 100644 index 00000000000..4ee58da1caa --- /dev/null +++ b/tests/cases/fourslash/convertJSDocToTypes13.ts @@ -0,0 +1,11 @@ +/// +////class C { +//// /** @return {number} */ +//// get /*1*/c() { return 12 } +////} +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`class C { + /** @return {number} */ + get c(): number { return 12; } +}`, 'Convert to Typescript type', 'convert'); diff --git a/tests/cases/fourslash/convertJSDocToTypes2.ts b/tests/cases/fourslash/convertJSDocToTypes2.ts new file mode 100644 index 00000000000..85f28de4a99 --- /dev/null +++ b/tests/cases/fourslash/convertJSDocToTypes2.ts @@ -0,0 +1,6 @@ +/// + +// @Filename: test123.ts +/////** @type {number} */ +////var /*1*/x: string; +verify.not.applicableRefactorAvailableAtMarker('1'); diff --git a/tests/cases/fourslash/convertJSDocToTypes3.ts b/tests/cases/fourslash/convertJSDocToTypes3.ts new file mode 100644 index 00000000000..3d3c1d35f44 --- /dev/null +++ b/tests/cases/fourslash/convertJSDocToTypes3.ts @@ -0,0 +1,54 @@ +/// +/////** +//// * @param {number} x - the first parameter +//// * @param {{ a: string, b: Date }} y - the most complex parameter +//// * @param z - the best parameter +//// * @param alpha - the other best parameter +//// * @param {*} beta - I have no idea how this got here +//// */ +////function f(/*1*/x, /*2*/y, /*3*/z: string, /*4*/alpha, /*5*/beta) { +////} + +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`/** + * @param {number} x - the first parameter + * @param {{ a: string, b: Date }} y - the most complex parameter + * @param z - the best parameter + * @param alpha - the other best parameter + * @param {*} beta - I have no idea how this got here + */ +function f(x: number, y, z: string, alpha, beta) { +}`, 'Convert to Typescript type', 'convert'); + +verify.applicableRefactorAvailableAtMarker('2'); +verify.fileAfterApplyingRefactorAtMarker('2', +`/** + * @param {number} x - the first parameter + * @param {{ a: string, b: Date }} y - the most complex parameter + * @param z - the best parameter + * @param alpha - the other best parameter + * @param {*} beta - I have no idea how this got here + */ +function f(x: number, y: { + a: string; + b: Date; +}, z: string, alpha, beta) { +}`, 'Convert to Typescript type', 'convert'); + +verify.not.applicableRefactorAvailableAtMarker('3'); +verify.not.applicableRefactorAvailableAtMarker('4'); +verify.applicableRefactorAvailableAtMarker('5'); +verify.fileAfterApplyingRefactorAtMarker('5', +`/** + * @param {number} x - the first parameter + * @param {{ a: string, b: Date }} y - the most complex parameter + * @param z - the best parameter + * @param alpha - the other best parameter + * @param {*} beta - I have no idea how this got here + */ +function f(x: number, y: { + a: string; + b: Date; +}, z: string, alpha, beta: any) { +}`, 'Convert to Typescript type', 'convert'); diff --git a/tests/cases/fourslash/convertJSDocToTypes4.ts b/tests/cases/fourslash/convertJSDocToTypes4.ts new file mode 100644 index 00000000000..ea80bf0452d --- /dev/null +++ b/tests/cases/fourslash/convertJSDocToTypes4.ts @@ -0,0 +1,115 @@ +/// +// @strict: true +/////** +//// * @param {*} x +//// * @param {?} y +//// * @param {number=} z +//// * @param {...number} alpha +//// * @param {function(this:{ a: string}, string, number): boolean} beta +//// * @param {number?} gamma +//// * @param {number!} delta +//// */ +////function f(/*1*/x, /*2*/y, /*3*/z, /*4*/alpha, /*5*/beta, /*6*/gamma, /*7*/delta) { +////} + +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`/** + * @param {*} x + * @param {?} y + * @param {number=} z + * @param {...number} alpha + * @param {function(this:{ a: string}, string, number): boolean} beta + * @param {number?} gamma + * @param {number!} delta + */ +function f(x: any, y, z, alpha, beta, gamma, delta) { +}`, 'Convert to Typescript type', 'convert'); + +verify.applicableRefactorAvailableAtMarker('2'); +verify.fileAfterApplyingRefactorAtMarker('2', +`/** + * @param {*} x + * @param {?} y + * @param {number=} z + * @param {...number} alpha + * @param {function(this:{ a: string}, string, number): boolean} beta + * @param {number?} gamma + * @param {number!} delta + */ +function f(x: any, y: any, z, alpha, beta, gamma, delta) { +}`, 'Convert to Typescript type', 'convert'); + +verify.applicableRefactorAvailableAtMarker('3'); +verify.fileAfterApplyingRefactorAtMarker('3', +`/** + * @param {*} x + * @param {?} y + * @param {number=} z + * @param {...number} alpha + * @param {function(this:{ a: string}, string, number): boolean} beta + * @param {number?} gamma + * @param {number!} delta + */ +function f(x: any, y: any, z: number | undefined, alpha, beta, gamma, delta) { +}`, 'Convert to Typescript type', 'convert'); +verify.applicableRefactorAvailableAtMarker('4'); +verify.fileAfterApplyingRefactorAtMarker('4', +`/** + * @param {*} x + * @param {?} y + * @param {number=} z + * @param {...number} alpha + * @param {function(this:{ a: string}, string, number): boolean} beta + * @param {number?} gamma + * @param {number!} delta + */ +function f(x: any, y: any, z: number | undefined, alpha: number[], beta, gamma, delta) { +}`, 'Convert to Typescript type', 'convert'); + +verify.applicableRefactorAvailableAtMarker('5'); +verify.fileAfterApplyingRefactorAtMarker('5', +`/** + * @param {*} x + * @param {?} y + * @param {number=} z + * @param {...number} alpha + * @param {function(this:{ a: string}, string, number): boolean} beta + * @param {number?} gamma + * @param {number!} delta + */ +function f(x: any, y: any, z: number | undefined, alpha: number[], beta: (this: { + a: string; +}, arg1: string, arg2: number) => boolean, gamma, delta) { +}`, 'Convert to Typescript type', 'convert'); +verify.applicableRefactorAvailableAtMarker('6'); +verify.fileAfterApplyingRefactorAtMarker('6', +`/** + * @param {*} x + * @param {?} y + * @param {number=} z + * @param {...number} alpha + * @param {function(this:{ a: string}, string, number): boolean} beta + * @param {number?} gamma + * @param {number!} delta + */ +function f(x: any, y: any, z: number | undefined, alpha: number[], beta: (this: { + a: string; +}, arg1: string, arg2: number) => boolean, gamma: number | null, delta) { +}`, 'Convert to Typescript type', 'convert'); + +verify.applicableRefactorAvailableAtMarker('7'); +verify.fileAfterApplyingRefactorAtMarker('7', +`/** + * @param {*} x + * @param {?} y + * @param {number=} z + * @param {...number} alpha + * @param {function(this:{ a: string}, string, number): boolean} beta + * @param {number?} gamma + * @param {number!} delta + */ +function f(x: any, y: any, z: number | undefined, alpha: number[], beta: (this: { + a: string; +}, arg1: string, arg2: number) => boolean, gamma: number | null, delta: number) { +}`, 'Convert to Typescript type', 'convert'); diff --git a/tests/cases/fourslash/convertJSDocToTypes5.ts b/tests/cases/fourslash/convertJSDocToTypes5.ts new file mode 100644 index 00000000000..7647e7be2f8 --- /dev/null +++ b/tests/cases/fourslash/convertJSDocToTypes5.ts @@ -0,0 +1,15 @@ +/// + +////class C { +//// /** @type {number | null} */ +//// /*1*/p = null +////} + +// NOTE: The duplicated comment is unintentional but needs a serious fix in trivia handling +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`class C { + /** @type {number | null} */ + /** @type {number | null} */ + p: number | null = null; +}`, 'Convert to Typescript type', 'convert'); diff --git a/tests/cases/fourslash/convertJSDocToTypes6.ts b/tests/cases/fourslash/convertJSDocToTypes6.ts new file mode 100644 index 00000000000..991e84b76b6 --- /dev/null +++ b/tests/cases/fourslash/convertJSDocToTypes6.ts @@ -0,0 +1,15 @@ +/// + +////declare class C { +//// /** @type {number | null} */ +//// /*1*/p; +////} + +// NOTE: The duplicated comment is unintentional but needs a serious fix in trivia handling +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`declare class C { + /** @type {number | null} */ + /** @type {number | null} */ + p: number | null; +}`, 'Convert to Typescript type', 'convert'); diff --git a/tests/cases/fourslash/convertJSDocToTypes7.ts b/tests/cases/fourslash/convertJSDocToTypes7.ts new file mode 100644 index 00000000000..5046b4237ec --- /dev/null +++ b/tests/cases/fourslash/convertJSDocToTypes7.ts @@ -0,0 +1,17 @@ +/// + +/////** +//// * @param {number} x +//// * @returns {number} +//// */ +/////*1*/function f(x) { +////} + +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`/** + * @param {number} x + * @returns {number} + */ +function f(x): number { +}`, 'Convert to Typescript type', 'convert'); diff --git a/tests/cases/fourslash/convertJSDocToTypes8.ts b/tests/cases/fourslash/convertJSDocToTypes8.ts new file mode 100644 index 00000000000..b3d0f821836 --- /dev/null +++ b/tests/cases/fourslash/convertJSDocToTypes8.ts @@ -0,0 +1,17 @@ +/// + +/////** +//// * @param {number} x +//// * @returns {number} +//// */ +////var f = /*1*/function (x) { +////} + +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`/** + * @param {number} x + * @returns {number} + */ +var f = function(x): number { +}`, 'Convert to Typescript type', 'convert'); diff --git a/tests/cases/fourslash/convertJSDocToTypes9.ts b/tests/cases/fourslash/convertJSDocToTypes9.ts new file mode 100644 index 00000000000..7f682a2459c --- /dev/null +++ b/tests/cases/fourslash/convertJSDocToTypes9.ts @@ -0,0 +1,15 @@ +/// + +/////** +//// * @param {?} x +//// * @returns {number} +//// */ +////var f = /*1*/x => x + +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`/** + * @param {?} x + * @returns {number} + */ +var f = (x: any) => x`, 'Convert to Typescript type', 'convert'); From 13b37a482593340d12bfbd4a3243f18d01067d7a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Tue, 26 Sep 2017 08:58:18 -0700 Subject: [PATCH 016/312] Change refactoring name and description --- src/compiler/diagnosticMessages.json | 6 ++- src/services/refactors/convertJSDocToTypes.ts | 40 ++++++++++++------- tests/cases/fourslash/convertJSDocToTypes1.ts | 2 +- .../cases/fourslash/convertJSDocToTypes10.ts | 2 +- .../cases/fourslash/convertJSDocToTypes11.ts | 2 +- .../cases/fourslash/convertJSDocToTypes12.ts | 2 +- .../cases/fourslash/convertJSDocToTypes13.ts | 2 +- .../cases/fourslash/convertJSDocToTypes14.ts | 11 +++++ tests/cases/fourslash/convertJSDocToTypes3.ts | 6 +-- tests/cases/fourslash/convertJSDocToTypes4.ts | 14 +++---- tests/cases/fourslash/convertJSDocToTypes5.ts | 2 +- tests/cases/fourslash/convertJSDocToTypes6.ts | 2 +- tests/cases/fourslash/convertJSDocToTypes7.ts | 2 +- tests/cases/fourslash/convertJSDocToTypes8.ts | 2 +- tests/cases/fourslash/convertJSDocToTypes9.ts | 2 +- 15 files changed, 61 insertions(+), 36 deletions(-) create mode 100644 tests/cases/fourslash/convertJSDocToTypes14.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index b3741af80e8..c6024e0974c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3704,8 +3704,12 @@ "category": "Message", "code": 95004 }, - "Convert to Typescript type": { + "Annotate with type from JSDoc": { "category": "Message", "code": 95005 + }, + "Annotate with return type from JSDoc": { + "category": "Message", + "code": 95006 } } diff --git a/src/services/refactors/convertJSDocToTypes.ts b/src/services/refactors/convertJSDocToTypes.ts index 562c26bf50f..c9915d85961 100644 --- a/src/services/refactors/convertJSDocToTypes.ts +++ b/src/services/refactors/convertJSDocToTypes.ts @@ -1,10 +1,16 @@ /* @internal */ namespace ts.refactor.convertJSDocToTypes { - const actionName = "convert"; + const actionName = "annotate"; - const convertJSDocToTypes: Refactor = { - name: "Convert to Typescript type", - description: Diagnostics.Convert_to_Typescript_type.message, + const annotateTypeFromJSDoc: Refactor = { + name: "Annotate with type from JSDoc", + description: Diagnostics.Annotate_with_type_from_JSDoc.message, + getEditsForAction, + getAvailableActions + }; + const annotateReturnTypeFromJSDoc: Refactor = { + name: "Annotate with return type from JSDoc", + description: Diagnostics.Annotate_with_return_type_from_JSDoc.message, getEditsForAction, getAvailableActions }; @@ -16,7 +22,8 @@ namespace ts.refactor.convertJSDocToTypes { | PropertySignature | PropertyDeclaration; - registerRefactor(convertJSDocToTypes); + registerRefactor(annotateTypeFromJSDoc); + registerRefactor(annotateReturnTypeFromJSDoc); function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { if (isInJavaScriptFile(context.file)) { @@ -25,19 +32,22 @@ namespace ts.refactor.convertJSDocToTypes { const node = getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false); const decl = findAncestor(node, isTypedNode); - if (decl && (getJSDocType(decl) || getJSDocReturnType(decl)) && !decl.type) { - return [ - { - name: convertJSDocToTypes.name, - description: convertJSDocToTypes.description, + if (decl && !decl.type) { + const annotate = getJSDocType(decl) ? annotateTypeFromJSDoc : + getJSDocReturnType(decl) ? annotateReturnTypeFromJSDoc : + undefined; + if (annotate) { + return [{ + name: annotate.name, + description: annotate.description, actions: [ { - description: convertJSDocToTypes.description, - name: actionName - } + description: annotate.description, + name: actionName + } ] - } - ]; + }]; + } } } diff --git a/tests/cases/fourslash/convertJSDocToTypes1.ts b/tests/cases/fourslash/convertJSDocToTypes1.ts index 7f90febaca1..99cf5f8db1c 100644 --- a/tests/cases/fourslash/convertJSDocToTypes1.ts +++ b/tests/cases/fourslash/convertJSDocToTypes1.ts @@ -7,4 +7,4 @@ verify.applicableRefactorAvailableAtMarker('1'); verify.fileAfterApplyingRefactorAtMarker('1', `/** @type {number} */ -var x: number;`, 'Convert to Typescript type', 'convert'); +var x: number;`, 'Annotate with type from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/convertJSDocToTypes10.ts b/tests/cases/fourslash/convertJSDocToTypes10.ts index 1e925db81e0..88b565fa932 100644 --- a/tests/cases/fourslash/convertJSDocToTypes10.ts +++ b/tests/cases/fourslash/convertJSDocToTypes10.ts @@ -12,4 +12,4 @@ verify.fileAfterApplyingRefactorAtMarker('1', * @param {?} x * @returns {number} */ -var f = (x): number => x`, 'Convert to Typescript type', 'convert'); +var f = (x): number => x`, 'Annotate with return type from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/convertJSDocToTypes11.ts b/tests/cases/fourslash/convertJSDocToTypes11.ts index 0315e506dc1..63b2d85fbfe 100644 --- a/tests/cases/fourslash/convertJSDocToTypes11.ts +++ b/tests/cases/fourslash/convertJSDocToTypes11.ts @@ -12,4 +12,4 @@ verify.fileAfterApplyingRefactorAtMarker('2', * @param {?} x * @returns {number} */ -var f = (x: any) => x`, 'Convert to Typescript type', 'convert'); +var f = (x: any) => x`, 'Annotate with type from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/convertJSDocToTypes12.ts b/tests/cases/fourslash/convertJSDocToTypes12.ts index 5015cb825d8..95fa0b55cd2 100644 --- a/tests/cases/fourslash/convertJSDocToTypes12.ts +++ b/tests/cases/fourslash/convertJSDocToTypes12.ts @@ -18,4 +18,4 @@ verify.fileAfterApplyingRefactorAtMarker('1', */ m(x): any[] { } -}`, 'Convert to Typescript type', 'convert'); +}`, 'Annotate with return type from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/convertJSDocToTypes13.ts b/tests/cases/fourslash/convertJSDocToTypes13.ts index 4ee58da1caa..caa3315b87f 100644 --- a/tests/cases/fourslash/convertJSDocToTypes13.ts +++ b/tests/cases/fourslash/convertJSDocToTypes13.ts @@ -8,4 +8,4 @@ verify.fileAfterApplyingRefactorAtMarker('1', `class C { /** @return {number} */ get c(): number { return 12; } -}`, 'Convert to Typescript type', 'convert'); +}`, 'Annotate with return type from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/convertJSDocToTypes14.ts b/tests/cases/fourslash/convertJSDocToTypes14.ts new file mode 100644 index 00000000000..43ac95a1c4a --- /dev/null +++ b/tests/cases/fourslash/convertJSDocToTypes14.ts @@ -0,0 +1,11 @@ +/// +/////** @return {number} */ +////function f() { +//// /*1*/return 12; +////} +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`/** @return {number} */ +function f(): number { + return 12; +}`, 'Annotate with return type from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/convertJSDocToTypes3.ts b/tests/cases/fourslash/convertJSDocToTypes3.ts index 3d3c1d35f44..985b89ed709 100644 --- a/tests/cases/fourslash/convertJSDocToTypes3.ts +++ b/tests/cases/fourslash/convertJSDocToTypes3.ts @@ -19,7 +19,7 @@ verify.fileAfterApplyingRefactorAtMarker('1', * @param {*} beta - I have no idea how this got here */ function f(x: number, y, z: string, alpha, beta) { -}`, 'Convert to Typescript type', 'convert'); +}`, 'Annotate with type from JSDoc', 'annotate'); verify.applicableRefactorAvailableAtMarker('2'); verify.fileAfterApplyingRefactorAtMarker('2', @@ -34,7 +34,7 @@ function f(x: number, y: { a: string; b: Date; }, z: string, alpha, beta) { -}`, 'Convert to Typescript type', 'convert'); +}`, 'Annotate with type from JSDoc', 'annotate'); verify.not.applicableRefactorAvailableAtMarker('3'); verify.not.applicableRefactorAvailableAtMarker('4'); @@ -51,4 +51,4 @@ function f(x: number, y: { a: string; b: Date; }, z: string, alpha, beta: any) { -}`, 'Convert to Typescript type', 'convert'); +}`, 'Annotate with type from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/convertJSDocToTypes4.ts b/tests/cases/fourslash/convertJSDocToTypes4.ts index ea80bf0452d..d4d5384b19c 100644 --- a/tests/cases/fourslash/convertJSDocToTypes4.ts +++ b/tests/cases/fourslash/convertJSDocToTypes4.ts @@ -24,7 +24,7 @@ verify.fileAfterApplyingRefactorAtMarker('1', * @param {number!} delta */ function f(x: any, y, z, alpha, beta, gamma, delta) { -}`, 'Convert to Typescript type', 'convert'); +}`, 'Annotate with type from JSDoc', 'annotate'); verify.applicableRefactorAvailableAtMarker('2'); verify.fileAfterApplyingRefactorAtMarker('2', @@ -38,7 +38,7 @@ verify.fileAfterApplyingRefactorAtMarker('2', * @param {number!} delta */ function f(x: any, y: any, z, alpha, beta, gamma, delta) { -}`, 'Convert to Typescript type', 'convert'); +}`, 'Annotate with type from JSDoc', 'annotate'); verify.applicableRefactorAvailableAtMarker('3'); verify.fileAfterApplyingRefactorAtMarker('3', @@ -52,7 +52,7 @@ verify.fileAfterApplyingRefactorAtMarker('3', * @param {number!} delta */ function f(x: any, y: any, z: number | undefined, alpha, beta, gamma, delta) { -}`, 'Convert to Typescript type', 'convert'); +}`, 'Annotate with type from JSDoc', 'annotate'); verify.applicableRefactorAvailableAtMarker('4'); verify.fileAfterApplyingRefactorAtMarker('4', `/** @@ -65,7 +65,7 @@ verify.fileAfterApplyingRefactorAtMarker('4', * @param {number!} delta */ function f(x: any, y: any, z: number | undefined, alpha: number[], beta, gamma, delta) { -}`, 'Convert to Typescript type', 'convert'); +}`, 'Annotate with type from JSDoc', 'annotate'); verify.applicableRefactorAvailableAtMarker('5'); verify.fileAfterApplyingRefactorAtMarker('5', @@ -81,7 +81,7 @@ verify.fileAfterApplyingRefactorAtMarker('5', function f(x: any, y: any, z: number | undefined, alpha: number[], beta: (this: { a: string; }, arg1: string, arg2: number) => boolean, gamma, delta) { -}`, 'Convert to Typescript type', 'convert'); +}`, 'Annotate with type from JSDoc', 'annotate'); verify.applicableRefactorAvailableAtMarker('6'); verify.fileAfterApplyingRefactorAtMarker('6', `/** @@ -96,7 +96,7 @@ verify.fileAfterApplyingRefactorAtMarker('6', function f(x: any, y: any, z: number | undefined, alpha: number[], beta: (this: { a: string; }, arg1: string, arg2: number) => boolean, gamma: number | null, delta) { -}`, 'Convert to Typescript type', 'convert'); +}`, 'Annotate with type from JSDoc', 'annotate'); verify.applicableRefactorAvailableAtMarker('7'); verify.fileAfterApplyingRefactorAtMarker('7', @@ -112,4 +112,4 @@ verify.fileAfterApplyingRefactorAtMarker('7', function f(x: any, y: any, z: number | undefined, alpha: number[], beta: (this: { a: string; }, arg1: string, arg2: number) => boolean, gamma: number | null, delta: number) { -}`, 'Convert to Typescript type', 'convert'); +}`, 'Annotate with type from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/convertJSDocToTypes5.ts b/tests/cases/fourslash/convertJSDocToTypes5.ts index 7647e7be2f8..1f15bf59924 100644 --- a/tests/cases/fourslash/convertJSDocToTypes5.ts +++ b/tests/cases/fourslash/convertJSDocToTypes5.ts @@ -12,4 +12,4 @@ verify.fileAfterApplyingRefactorAtMarker('1', /** @type {number | null} */ /** @type {number | null} */ p: number | null = null; -}`, 'Convert to Typescript type', 'convert'); +}`, 'Annotate with type from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/convertJSDocToTypes6.ts b/tests/cases/fourslash/convertJSDocToTypes6.ts index 991e84b76b6..91bc1523ea3 100644 --- a/tests/cases/fourslash/convertJSDocToTypes6.ts +++ b/tests/cases/fourslash/convertJSDocToTypes6.ts @@ -12,4 +12,4 @@ verify.fileAfterApplyingRefactorAtMarker('1', /** @type {number | null} */ /** @type {number | null} */ p: number | null; -}`, 'Convert to Typescript type', 'convert'); +}`, 'Annotate with type from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/convertJSDocToTypes7.ts b/tests/cases/fourslash/convertJSDocToTypes7.ts index 5046b4237ec..c78f8949b18 100644 --- a/tests/cases/fourslash/convertJSDocToTypes7.ts +++ b/tests/cases/fourslash/convertJSDocToTypes7.ts @@ -14,4 +14,4 @@ verify.fileAfterApplyingRefactorAtMarker('1', * @returns {number} */ function f(x): number { -}`, 'Convert to Typescript type', 'convert'); +}`, 'Annotate with return type from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/convertJSDocToTypes8.ts b/tests/cases/fourslash/convertJSDocToTypes8.ts index b3d0f821836..502b945819c 100644 --- a/tests/cases/fourslash/convertJSDocToTypes8.ts +++ b/tests/cases/fourslash/convertJSDocToTypes8.ts @@ -14,4 +14,4 @@ verify.fileAfterApplyingRefactorAtMarker('1', * @returns {number} */ var f = function(x): number { -}`, 'Convert to Typescript type', 'convert'); +}`, 'Annotate with return type from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/convertJSDocToTypes9.ts b/tests/cases/fourslash/convertJSDocToTypes9.ts index 7f682a2459c..cf2581f5d8f 100644 --- a/tests/cases/fourslash/convertJSDocToTypes9.ts +++ b/tests/cases/fourslash/convertJSDocToTypes9.ts @@ -12,4 +12,4 @@ verify.fileAfterApplyingRefactorAtMarker('1', * @param {?} x * @returns {number} */ -var f = (x: any) => x`, 'Convert to Typescript type', 'convert'); +var f = (x: any) => x`, 'Annotate with type from JSDoc', 'annotate'); From 96b80938909438a80d84c33ce342e7e1a45eda99 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Tue, 26 Sep 2017 09:08:39 -0700 Subject: [PATCH 017/312] Move filenames to match refactoring rename --- .../{convertJSDocToTypes.ts => annotateWithTypeFromJSDoc.ts} | 2 +- src/services/refactors/refactors.ts | 2 +- .../{convertJSDocToTypes1.ts => annotateWithTypeFromJSDoc1.ts} | 0 ...{convertJSDocToTypes10.ts => annotateWithTypeFromJSDoc10.ts} | 0 ...{convertJSDocToTypes11.ts => annotateWithTypeFromJSDoc11.ts} | 0 ...{convertJSDocToTypes12.ts => annotateWithTypeFromJSDoc12.ts} | 0 ...{convertJSDocToTypes13.ts => annotateWithTypeFromJSDoc13.ts} | 0 ...{convertJSDocToTypes14.ts => annotateWithTypeFromJSDoc14.ts} | 0 .../{convertJSDocToTypes2.ts => annotateWithTypeFromJSDoc2.ts} | 0 .../{convertJSDocToTypes3.ts => annotateWithTypeFromJSDoc3.ts} | 0 .../{convertJSDocToTypes4.ts => annotateWithTypeFromJSDoc4.ts} | 0 .../{convertJSDocToTypes5.ts => annotateWithTypeFromJSDoc5.ts} | 0 .../{convertJSDocToTypes6.ts => annotateWithTypeFromJSDoc6.ts} | 0 .../{convertJSDocToTypes7.ts => annotateWithTypeFromJSDoc7.ts} | 0 .../{convertJSDocToTypes8.ts => annotateWithTypeFromJSDoc8.ts} | 0 .../{convertJSDocToTypes9.ts => annotateWithTypeFromJSDoc9.ts} | 0 16 files changed, 2 insertions(+), 2 deletions(-) rename src/services/refactors/{convertJSDocToTypes.ts => annotateWithTypeFromJSDoc.ts} (97%) rename tests/cases/fourslash/{convertJSDocToTypes1.ts => annotateWithTypeFromJSDoc1.ts} (100%) rename tests/cases/fourslash/{convertJSDocToTypes10.ts => annotateWithTypeFromJSDoc10.ts} (100%) rename tests/cases/fourslash/{convertJSDocToTypes11.ts => annotateWithTypeFromJSDoc11.ts} (100%) rename tests/cases/fourslash/{convertJSDocToTypes12.ts => annotateWithTypeFromJSDoc12.ts} (100%) rename tests/cases/fourslash/{convertJSDocToTypes13.ts => annotateWithTypeFromJSDoc13.ts} (100%) rename tests/cases/fourslash/{convertJSDocToTypes14.ts => annotateWithTypeFromJSDoc14.ts} (100%) rename tests/cases/fourslash/{convertJSDocToTypes2.ts => annotateWithTypeFromJSDoc2.ts} (100%) rename tests/cases/fourslash/{convertJSDocToTypes3.ts => annotateWithTypeFromJSDoc3.ts} (100%) rename tests/cases/fourslash/{convertJSDocToTypes4.ts => annotateWithTypeFromJSDoc4.ts} (100%) rename tests/cases/fourslash/{convertJSDocToTypes5.ts => annotateWithTypeFromJSDoc5.ts} (100%) rename tests/cases/fourslash/{convertJSDocToTypes6.ts => annotateWithTypeFromJSDoc6.ts} (100%) rename tests/cases/fourslash/{convertJSDocToTypes7.ts => annotateWithTypeFromJSDoc7.ts} (100%) rename tests/cases/fourslash/{convertJSDocToTypes8.ts => annotateWithTypeFromJSDoc8.ts} (100%) rename tests/cases/fourslash/{convertJSDocToTypes9.ts => annotateWithTypeFromJSDoc9.ts} (100%) diff --git a/src/services/refactors/convertJSDocToTypes.ts b/src/services/refactors/annotateWithTypeFromJSDoc.ts similarity index 97% rename from src/services/refactors/convertJSDocToTypes.ts rename to src/services/refactors/annotateWithTypeFromJSDoc.ts index c9915d85961..d8b8e849bb6 100644 --- a/src/services/refactors/convertJSDocToTypes.ts +++ b/src/services/refactors/annotateWithTypeFromJSDoc.ts @@ -1,5 +1,5 @@ /* @internal */ -namespace ts.refactor.convertJSDocToTypes { +namespace ts.refactor.annotateWithTypeFromJSDoc { const actionName = "annotate"; const annotateTypeFromJSDoc: Refactor = { diff --git a/src/services/refactors/refactors.ts b/src/services/refactors/refactors.ts index d1d50cb50f9..a536d5a8b62 100644 --- a/src/services/refactors/refactors.ts +++ b/src/services/refactors/refactors.ts @@ -1,3 +1,3 @@ -/// +/// /// /// diff --git a/tests/cases/fourslash/convertJSDocToTypes1.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc1.ts similarity index 100% rename from tests/cases/fourslash/convertJSDocToTypes1.ts rename to tests/cases/fourslash/annotateWithTypeFromJSDoc1.ts diff --git a/tests/cases/fourslash/convertJSDocToTypes10.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc10.ts similarity index 100% rename from tests/cases/fourslash/convertJSDocToTypes10.ts rename to tests/cases/fourslash/annotateWithTypeFromJSDoc10.ts diff --git a/tests/cases/fourslash/convertJSDocToTypes11.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc11.ts similarity index 100% rename from tests/cases/fourslash/convertJSDocToTypes11.ts rename to tests/cases/fourslash/annotateWithTypeFromJSDoc11.ts diff --git a/tests/cases/fourslash/convertJSDocToTypes12.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc12.ts similarity index 100% rename from tests/cases/fourslash/convertJSDocToTypes12.ts rename to tests/cases/fourslash/annotateWithTypeFromJSDoc12.ts diff --git a/tests/cases/fourslash/convertJSDocToTypes13.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc13.ts similarity index 100% rename from tests/cases/fourslash/convertJSDocToTypes13.ts rename to tests/cases/fourslash/annotateWithTypeFromJSDoc13.ts diff --git a/tests/cases/fourslash/convertJSDocToTypes14.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc14.ts similarity index 100% rename from tests/cases/fourslash/convertJSDocToTypes14.ts rename to tests/cases/fourslash/annotateWithTypeFromJSDoc14.ts diff --git a/tests/cases/fourslash/convertJSDocToTypes2.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc2.ts similarity index 100% rename from tests/cases/fourslash/convertJSDocToTypes2.ts rename to tests/cases/fourslash/annotateWithTypeFromJSDoc2.ts diff --git a/tests/cases/fourslash/convertJSDocToTypes3.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc3.ts similarity index 100% rename from tests/cases/fourslash/convertJSDocToTypes3.ts rename to tests/cases/fourslash/annotateWithTypeFromJSDoc3.ts diff --git a/tests/cases/fourslash/convertJSDocToTypes4.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc4.ts similarity index 100% rename from tests/cases/fourslash/convertJSDocToTypes4.ts rename to tests/cases/fourslash/annotateWithTypeFromJSDoc4.ts diff --git a/tests/cases/fourslash/convertJSDocToTypes5.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc5.ts similarity index 100% rename from tests/cases/fourslash/convertJSDocToTypes5.ts rename to tests/cases/fourslash/annotateWithTypeFromJSDoc5.ts diff --git a/tests/cases/fourslash/convertJSDocToTypes6.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc6.ts similarity index 100% rename from tests/cases/fourslash/convertJSDocToTypes6.ts rename to tests/cases/fourslash/annotateWithTypeFromJSDoc6.ts diff --git a/tests/cases/fourslash/convertJSDocToTypes7.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc7.ts similarity index 100% rename from tests/cases/fourslash/convertJSDocToTypes7.ts rename to tests/cases/fourslash/annotateWithTypeFromJSDoc7.ts diff --git a/tests/cases/fourslash/convertJSDocToTypes8.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc8.ts similarity index 100% rename from tests/cases/fourslash/convertJSDocToTypes8.ts rename to tests/cases/fourslash/annotateWithTypeFromJSDoc8.ts diff --git a/tests/cases/fourslash/convertJSDocToTypes9.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc9.ts similarity index 100% rename from tests/cases/fourslash/convertJSDocToTypes9.ts rename to tests/cases/fourslash/annotateWithTypeFromJSDoc9.ts From fc933d7c33bbc14add9f73a4639ee20439293787 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Tue, 26 Sep 2017 12:42:08 -0700 Subject: [PATCH 018/312] Transform jsdoc types in the refactor, not emitter The emitter now understands JSDoc types but emits them in the original format. --- src/compiler/emitter.ts | 39 +++-- .../refactors/annotateWithTypeFromJSDoc.ts | 109 ++++++++++-- .../fourslash/annotateWithTypeFromJSDoc15.ts | 158 ++++++++++++++++++ 3 files changed, 276 insertions(+), 30 deletions(-) create mode 100644 tests/cases/fourslash/annotateWithTypeFromJSDoc15.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 80b08c60d34..61f9773c7a0 100755 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -545,8 +545,9 @@ namespace ts { case SyntaxKind.TypeReference: return emitTypeReference(node); case SyntaxKind.FunctionType: - case SyntaxKind.JSDocFunctionType: return emitFunctionType(node); + case SyntaxKind.JSDocFunctionType: + return emitJSDocFunctionType(node as JSDocFunctionType); case SyntaxKind.ConstructorType: return emitConstructorType(node); case SyntaxKind.TypeQuery: @@ -576,8 +577,10 @@ namespace ts { case SyntaxKind.LiteralType: return emitLiteralType(node); case SyntaxKind.JSDocAllType: + write("*"); + break; case SyntaxKind.JSDocUnknownType: - write("any"); + write("?"); break; case SyntaxKind.JSDocNullableType: return emitJSDocNullableType(node as JSDocNullableType); @@ -930,14 +933,13 @@ namespace ts { if (node.name) { emit(node.name); } - else if (node.parent.kind === SyntaxKind.JSDocFunctionType) { - const i = (node.parent as JSDocFunctionType).parameters.indexOf(node); - if (i > -1) { - write("arg" + i); - } - } emitIfPresent(node.questionToken); - emitWithPrefix(": ", node.type); + if (node.parent && node.parent.kind === SyntaxKind.JSDocFunctionType && !node.name) { + emit(node.type); + } + else { + emitWithPrefix(": ", node.type); + } emitExpressionWithPrefix(" = ", node.initializer); } @@ -1056,18 +1058,27 @@ namespace ts { emit(node.type); } + function emitJSDocFunctionType(node: JSDocFunctionType) { + write("function"); + emitParameters(node, node.parameters); + write(":"); + emit(node.type); + } + + function emitJSDocNullableType(node: JSDocNullableType) { + write("?"); emit(node.type); - write(" | null"); } function emitJSDocNonNullableType(node: JSDocNonNullableType) { + write("!"); emit(node.type); } function emitJSDocOptionalType(node: JSDocOptionalType) { emit(node.type); - write(" | undefined"); + write("="); } function emitConstructorType(node: ConstructorTypeNode) { @@ -1096,8 +1107,8 @@ namespace ts { } function emitJSDocVariadicType(node: JSDocVariadicType) { + write("..."); emit(node.type); - write("[]"); } function emitTupleType(node: TupleTypeNode) { @@ -2397,7 +2408,7 @@ namespace ts { emitList(parentNode, parameters, ListFormat.Parameters); } - function canEmitSimpleArrowHead(parentNode: FunctionTypeNode | ArrowFunction | JSDocFunctionType, parameters: NodeArray) { + function canEmitSimpleArrowHead(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray) { const parameter = singleOrUndefined(parameters); return parameter && parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter @@ -2414,7 +2425,7 @@ namespace ts { && isIdentifier(parameter.name); // parameter name must be identifier } - function emitParametersForArrow(parentNode: FunctionTypeNode | ArrowFunction | JSDocFunctionType, parameters: NodeArray) { + function emitParametersForArrow(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray) { if (canEmitSimpleArrowHead(parentNode, parameters)) { emitList(parentNode, parameters, ListFormat.Parameters & ~ListFormat.Parenthesis); } diff --git a/src/services/refactors/annotateWithTypeFromJSDoc.ts b/src/services/refactors/annotateWithTypeFromJSDoc.ts index d8b8e849bb6..dde367f0ac9 100644 --- a/src/services/refactors/annotateWithTypeFromJSDoc.ts +++ b/src/services/refactors/annotateWithTypeFromJSDoc.ts @@ -35,16 +35,16 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { if (decl && !decl.type) { const annotate = getJSDocType(decl) ? annotateTypeFromJSDoc : getJSDocReturnType(decl) ? annotateReturnTypeFromJSDoc : - undefined; + undefined; if (annotate) { return [{ name: annotate.name, description: annotate.description, actions: [ { - description: annotate.description, - name: actionName - } + description: annotate.description, + name: actionName + } ] }]; } @@ -62,10 +62,9 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { const sourceFile = context.file; const token = getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); const decl = findAncestor(token, isTypedNode); - const jsdocType = getJSDocType(decl); - const jsdocReturn = getJSDocReturnType(decl); - if (!decl || !jsdocType && !jsdocReturn || decl.type) { - Debug.fail(`!decl || !jsdocType && !jsdocReturn || decl.type: !${decl} || !${jsdocType} && !{jsdocReturn} || ${decl.type}`); + const jsdocType = getJSDocReturnType(decl) || getJSDocType(decl); + if (!decl || !jsdocType || decl.type) { + Debug.fail(`!decl || !jsdocType || decl.type: !${decl} || !${jsdocType} || ${decl.type}`); return undefined; } @@ -76,12 +75,12 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { // other syntax changes const arrow = decl.parent as ArrowFunction; const param = decl as ParameterDeclaration; - const replacementParam = createParameter(param.decorators, param.modifiers, param.dotDotDotToken, param.name, param.questionToken, jsdocType, param.initializer); + const replacementParam = createParameter(param.decorators, param.modifiers, param.dotDotDotToken, param.name, param.questionToken, transformJSDocType(jsdocType) as TypeNode, param.initializer); const replacement = createArrowFunction(arrow.modifiers, arrow.typeParameters, [replacementParam], arrow.type, arrow.equalsGreaterThanToken, arrow.body); changeTracker.replaceRange(sourceFile, { pos: arrow.getStart(), end: arrow.end }, replacement); } else { - changeTracker.replaceRange(sourceFile, { pos: decl.getStart(), end: decl.end }, replaceType(decl, jsdocType, jsdocReturn)); + changeTracker.replaceRange(sourceFile, { pos: decl.getStart(), end: decl.end }, replaceType(decl, transformJSDocType(jsdocType) as TypeNode)); } return { edits: changeTracker.getChanges(), @@ -98,7 +97,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { node.kind === SyntaxKind.PropertyDeclaration; } - function replaceType(decl: DeclarationWithType, jsdocType: TypeNode, jsdocReturn: TypeNode) { + function replaceType(decl: DeclarationWithType, jsdocType: TypeNode) { switch (decl.kind) { case SyntaxKind.VariableDeclaration: return createVariableDeclaration(decl.name, jsdocType, decl.initializer); @@ -109,15 +108,15 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { case SyntaxKind.PropertyDeclaration: return createProperty(decl.decorators, decl.modifiers, decl.name, decl.questionToken, jsdocType, decl.initializer); case SyntaxKind.FunctionDeclaration: - return createFunctionDeclaration(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.typeParameters, decl.parameters, jsdocReturn, decl.body); + return createFunctionDeclaration(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.typeParameters, decl.parameters, jsdocType, decl.body); case SyntaxKind.FunctionExpression: - return createFunctionExpression(decl.modifiers, decl.asteriskToken, decl.name, decl.typeParameters, decl.parameters, jsdocReturn, decl.body); + return createFunctionExpression(decl.modifiers, decl.asteriskToken, decl.name, decl.typeParameters, decl.parameters, jsdocType, decl.body); case SyntaxKind.ArrowFunction: - return createArrowFunction(decl.modifiers, decl.typeParameters, decl.parameters, jsdocReturn, decl.equalsGreaterThanToken, decl.body); + return createArrowFunction(decl.modifiers, decl.typeParameters, decl.parameters, jsdocType, decl.equalsGreaterThanToken, decl.body); case SyntaxKind.MethodDeclaration: - return createMethod(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.questionToken, decl.typeParameters, decl.parameters, jsdocReturn, decl.body); + return createMethod(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.questionToken, decl.typeParameters, decl.parameters, jsdocType, decl.body); case SyntaxKind.GetAccessor: - return createGetAccessor(decl.decorators, decl.modifiers, decl.name, decl.parameters, jsdocReturn, decl.body); + return createGetAccessor(decl.decorators, decl.modifiers, decl.name, decl.parameters, jsdocType, decl.body); default: Debug.fail(`Unexpected SyntaxKind: ${decl.kind}`); return undefined; @@ -144,4 +143,82 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { && !parameter.initializer // parameter may not have an initializer && isIdentifier(parameter.name); // parameter name must be identifier } + + function transformJSDocType(node: Node): Node | undefined { + if (node === undefined) { + return undefined; + } + switch (node.kind) { + case SyntaxKind.JSDocAllType: + case SyntaxKind.JSDocUnknownType: + return createTypeReferenceNode("any", emptyArray); + case SyntaxKind.JSDocOptionalType: + return visitJSDocOptionalType(node as JSDocOptionalType); + case SyntaxKind.JSDocNonNullableType: + return transformJSDocType((node as JSDocNonNullableType).type); + case SyntaxKind.JSDocNullableType: + return visitJSDocNullableType(node as JSDocNullableType); + case SyntaxKind.JSDocVariadicType: + return visitJSDocVariadicType(node as JSDocVariadicType); + case SyntaxKind.JSDocFunctionType: + return visitJSDocFunctionType(node as JSDocFunctionType); + case SyntaxKind.Parameter: + return visitJSDocParameter(node as ParameterDeclaration); + case SyntaxKind.TypeReference: + return visitJSDocTypeReference(node as TypeReferenceNode); + default: + return visitEachChild(node, transformJSDocType, /*context*/ undefined) as TypeNode; + } + } + + function visitJSDocOptionalType(node: JSDocOptionalType) { + return createUnionTypeNode([visitNode(node.type, transformJSDocType), createTypeReferenceNode("undefined", emptyArray)]); + } + + function visitJSDocNullableType(node: JSDocNullableType) { + return createUnionTypeNode([visitNode(node.type, transformJSDocType), createTypeReferenceNode("null", emptyArray)]); + } + + function visitJSDocVariadicType(node: JSDocVariadicType) { + return createArrayTypeNode(visitNode(node.type, transformJSDocType)); + } + + function visitJSDocFunctionType(node: JSDocFunctionType) { + const parameters = node.parameters && node.parameters.map(transformJSDocType); + return createFunctionTypeNode(emptyArray, parameters as ParameterDeclaration[], node.type); + } + + function visitJSDocParameter(node: ParameterDeclaration) { + const name = node.name || "arg" + node.parent.parameters.indexOf(node); + return createParameter(node.decorators, node.modifiers, node.dotDotDotToken, name, node.questionToken, node.type, node.initializer); + } + + function visitJSDocTypeReference(node: TypeReferenceNode) { + let name = node.typeName; + let args = node.typeArguments; + if (isIdentifier(node.typeName)) { + let text = node.typeName.text; + switch (node.typeName.text) { + case "String": + case "Boolean": + case "Object": + case "Number": + text = text.toLowerCase(); + break; + case "array": + case "date": + case "promise": + text = text[0].toUpperCase() + text.slice(1); + break; + } + name = createIdentifier(text); + if ((text === "Array" || text === "Promise") && !node.typeArguments) { + args = createNodeArray([createTypeReferenceNode("any", emptyArray)]); + } + else { + args = visitNodes(node.typeArguments, transformJSDocType); + } + } + return createTypeReferenceNode(name, args); + } } diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc15.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc15.ts new file mode 100644 index 00000000000..487b456d561 --- /dev/null +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc15.ts @@ -0,0 +1,158 @@ +/// +// @strict: true +/////** +//// * @param {Boolean} x +//// * @param {String} y +//// * @param {Number} z +//// * @param {Object} alpha +//// * @param {date} beta +//// * @param {promise} gamma +//// * @param {array} delta +//// * @param {Array} epsilon +//// * @param {promise} zeta +//// */ +////function f(/*1*/x, /*2*/y, /*3*/z, /*4*/alpha, /*5*/beta, /*6*/gamma, /*7*/delta, /*8*/epsilon, /*9*/zeta) { +////} +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`/** + * @param {Boolean} x + * @param {String} y + * @param {Number} z + * @param {Object} alpha + * @param {date} beta + * @param {promise} gamma + * @param {array} delta + * @param {Array} epsilon + * @param {promise} zeta + */ +function f(x: boolean, y, z, alpha, beta, gamma, delta, epsilon, zeta) { +}`, 'Annotate with type from JSDoc', 'annotate'); + +verify.applicableRefactorAvailableAtMarker('2'); +verify.fileAfterApplyingRefactorAtMarker('2', +`/** + * @param {Boolean} x + * @param {String} y + * @param {Number} z + * @param {Object} alpha + * @param {date} beta + * @param {promise} gamma + * @param {array} delta + * @param {Array} epsilon + * @param {promise} zeta + */ +function f(x: boolean, y: string, z, alpha, beta, gamma, delta, epsilon, zeta) { +}`, 'Annotate with type from JSDoc', 'annotate'); + +verify.applicableRefactorAvailableAtMarker('3'); +verify.fileAfterApplyingRefactorAtMarker('3', +`/** + * @param {Boolean} x + * @param {String} y + * @param {Number} z + * @param {Object} alpha + * @param {date} beta + * @param {promise} gamma + * @param {array} delta + * @param {Array} epsilon + * @param {promise} zeta + */ +function f(x: boolean, y: string, z: number, alpha, beta, gamma, delta, epsilon, zeta) { +}`, 'Annotate with type from JSDoc', 'annotate'); + +verify.applicableRefactorAvailableAtMarker('4'); +verify.fileAfterApplyingRefactorAtMarker('4', +`/** + * @param {Boolean} x + * @param {String} y + * @param {Number} z + * @param {Object} alpha + * @param {date} beta + * @param {promise} gamma + * @param {array} delta + * @param {Array} epsilon + * @param {promise} zeta + */ +function f(x: boolean, y: string, z: number, alpha: object, beta, gamma, delta, epsilon, zeta) { +}`, 'Annotate with type from JSDoc', 'annotate'); + +verify.applicableRefactorAvailableAtMarker('5'); +verify.fileAfterApplyingRefactorAtMarker('5', +`/** + * @param {Boolean} x + * @param {String} y + * @param {Number} z + * @param {Object} alpha + * @param {date} beta + * @param {promise} gamma + * @param {array} delta + * @param {Array} epsilon + * @param {promise} zeta + */ +function f(x: boolean, y: string, z: number, alpha: object, beta: Date, gamma, delta, epsilon, zeta) { +}`, 'Annotate with type from JSDoc', 'annotate'); + +verify.applicableRefactorAvailableAtMarker('6'); +verify.fileAfterApplyingRefactorAtMarker('6', +`/** + * @param {Boolean} x + * @param {String} y + * @param {Number} z + * @param {Object} alpha + * @param {date} beta + * @param {promise} gamma + * @param {array} delta + * @param {Array} epsilon + * @param {promise} zeta + */ +function f(x: boolean, y: string, z: number, alpha: object, beta: Date, gamma: Promise, delta, epsilon, zeta) { +}`, 'Annotate with type from JSDoc', 'annotate'); + +verify.applicableRefactorAvailableAtMarker('7'); +verify.fileAfterApplyingRefactorAtMarker('7', +`/** + * @param {Boolean} x + * @param {String} y + * @param {Number} z + * @param {Object} alpha + * @param {date} beta + * @param {promise} gamma + * @param {array} delta + * @param {Array} epsilon + * @param {promise} zeta + */ +function f(x: boolean, y: string, z: number, alpha: object, beta: Date, gamma: Promise, delta: Array, epsilon, zeta) { +}`, 'Annotate with type from JSDoc', 'annotate'); + +verify.applicableRefactorAvailableAtMarker('8'); +verify.fileAfterApplyingRefactorAtMarker('8', +`/** + * @param {Boolean} x + * @param {String} y + * @param {Number} z + * @param {Object} alpha + * @param {date} beta + * @param {promise} gamma + * @param {array} delta + * @param {Array} epsilon + * @param {promise} zeta + */ +function f(x: boolean, y: string, z: number, alpha: object, beta: Date, gamma: Promise, delta: Array, epsilon: Array, zeta) { +}`, 'Annotate with type from JSDoc', 'annotate'); + +verify.applicableRefactorAvailableAtMarker('9'); +verify.fileAfterApplyingRefactorAtMarker('9', +`/** + * @param {Boolean} x + * @param {String} y + * @param {Number} z + * @param {Object} alpha + * @param {date} beta + * @param {promise} gamma + * @param {array} delta + * @param {Array} epsilon + * @param {promise} zeta + */ +function f(x: boolean, y: string, z: number, alpha: object, beta: Date, gamma: Promise, delta: Array, epsilon: Array, zeta: Promise) { +}`, 'Annotate with type from JSDoc', 'annotate'); From 6ba62d2d8dbfcfcbf542ab3213949ed98beaf459 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 26 Sep 2017 16:29:25 -0700 Subject: [PATCH 019/312] Revert all the changes except test case --- src/compiler/program.ts | 12 ++++++------ src/compiler/types.ts | 6 +----- src/server/builder.ts | 4 ++-- src/server/project.ts | 11 +---------- src/services/services.ts | 4 ++-- src/services/transpile.ts | 2 +- src/services/types.ts | 2 +- 7 files changed, 14 insertions(+), 27 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 30c61f50dff..bbc0fa09780 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -874,12 +874,12 @@ namespace ts { return oldProgram.structureIsReused = StructureIsReused.Completely; } - function getEmitHost(writeFileCallback?: WriteFileCallback, getCurrentDirectoryCallback?: GetCurrentDirectoryCallback): EmitHost { + function getEmitHost(writeFileCallback?: WriteFileCallback): EmitHost { return { getCanonicalFileName, getCommonSourceDirectory: program.getCommonSourceDirectory, getCompilerOptions: program.getCompilerOptions, - getCurrentDirectory: getCurrentDirectoryCallback || (() => currentDirectory), + getCurrentDirectory: () => currentDirectory, getNewLine: () => host.getNewLine(), getSourceFile: program.getSourceFile, getSourceFileByPath: program.getSourceFileByPath, @@ -907,15 +907,15 @@ namespace ts { return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = createTypeChecker(program, /*produceDiagnostics:*/ false)); } - function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, transformers?: CustomTransformers, getCurrentDirectoryCallback?: GetCurrentDirectoryCallback): EmitResult { - return runWithCancellationToken(() => emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers, getCurrentDirectoryCallback)); + function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, transformers?: CustomTransformers): EmitResult { + return runWithCancellationToken(() => emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers)); } function isEmitBlocked(emitFileName: string): boolean { return hasEmitBlockingDiagnostics.contains(toPath(emitFileName, currentDirectory, getCanonicalFileName)); } - function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers, getCurrentDirectoryCallback?: GetCurrentDirectoryCallback): EmitResult { + function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult { let declarationDiagnostics: Diagnostic[] = []; if (options.noEmit) { @@ -960,7 +960,7 @@ namespace ts { const transformers = emitOnlyDtsFiles ? [] : getTransformers(options, customTransformers); const emitResult = emitFiles( emitResolver, - getEmitHost(writeFileCallback, getCurrentDirectoryCallback), + getEmitHost(writeFileCallback), sourceFile, emitOnlyDtsFiles, transformers); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ac5de153226..ac64624e1a6 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2405,10 +2405,6 @@ namespace ts { (fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void, sourceFiles?: SourceFile[]): void; } - export interface GetCurrentDirectoryCallback { - (): string; - } - export class OperationCanceledException { } export interface CancellationToken { @@ -2440,7 +2436,7 @@ namespace ts { * used for writing the JavaScript and declaration files. Otherwise, the writeFile parameter * will be invoked when writing the JavaScript and declaration files. */ - emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers, getCurrentDirectoryCallback?: GetCurrentDirectoryCallback): EmitResult; + emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult; getOptionsDiagnostics(cancellationToken?: CancellationToken): Diagnostic[]; getGlobalDiagnostics(cancellationToken?: CancellationToken): Diagnostic[]; diff --git a/src/server/builder.ts b/src/server/builder.ts index 711045d0ae6..895732ebece 100644 --- a/src/server/builder.ts +++ b/src/server/builder.ts @@ -148,9 +148,9 @@ namespace ts.server { const { emitSkipped, outputFiles } = this.project.getFileEmitOutput(fileInfo.scriptInfo, /*emitOnlyDtsFiles*/ false); if (!emitSkipped) { - const currentDirectoryForEmit = this.project.getCurrentDirectoryForScriptInfoEmit(scriptInfo); + const projectRootPath = this.project.getProjectRootPath(); for (const outputFile of outputFiles) { - const outputFileAbsoluteFileName = getNormalizedAbsolutePath(outputFile.name, currentDirectoryForEmit); + const outputFileAbsoluteFileName = getNormalizedAbsolutePath(outputFile.name, projectRootPath ? projectRootPath : getDirectoryPath(scriptInfo.fileName)); writeFile(outputFileAbsoluteFileName, outputFile.text, outputFile.writeByteOrderMark); } } diff --git a/src/server/project.ts b/src/server/project.ts index a7d8605315b..ac040a77ace 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -367,16 +367,7 @@ namespace ts.server { if (!this.languageServiceEnabled) { return undefined; } - - const getCurrentDirectoryCallback = memoize( - () => this.getCurrentDirectoryForScriptInfoEmit(info) - ); - return this.getLanguageService().getEmitOutput(info.fileName, emitOnlyDtsFiles, getCurrentDirectoryCallback); - } - - getCurrentDirectoryForScriptInfoEmit(info: ScriptInfo) { - const projectRootPath = this.getProjectRootPath(); - return projectRootPath || getDirectoryPath(info.fileName); + return this.getLanguageService().getEmitOutput(info.fileName, emitOnlyDtsFiles); } getFileNames(excludeFilesFromExternalLibraries?: boolean, excludeConfigFiles?: boolean) { diff --git a/src/services/services.ts b/src/services/services.ts index 11061181ee6..b508285b182 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1528,7 +1528,7 @@ namespace ts { return ts.NavigateTo.getNavigateToItems(sourceFiles, program.getTypeChecker(), cancellationToken, searchValue, maxResultCount, excludeDtsFiles); } - function getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean, getCurrentDirectoryCallback?: GetCurrentDirectoryCallback): EmitOutput { + function getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput { synchronizeHostData(); const sourceFile = getValidSourceFile(fileName); @@ -1543,7 +1543,7 @@ namespace ts { } const customTransformers = host.getCustomTransformers && host.getCustomTransformers(); - const emitOutput = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers, getCurrentDirectoryCallback); + const emitOutput = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers); return { outputFiles, diff --git a/src/services/transpile.ts b/src/services/transpile.ts index 5ba393a90c9..561c188c6cd 100644 --- a/src/services/transpile.ts +++ b/src/services/transpile.ts @@ -104,7 +104,7 @@ namespace ts { addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics()); } // Emit - program.emit(/*targetSourceFile*/ undefined, /*writeFile*/ undefined, /*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ undefined, transpileOptions.transformers, /*getCurrentDirectoryCallback*/ undefined); + program.emit(/*targetSourceFile*/ undefined, /*writeFile*/ undefined, /*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ undefined, transpileOptions.transformers); Debug.assert(outputText !== undefined, "Output generation failed"); diff --git a/src/services/types.ts b/src/services/types.ts index 07aaaeeb4b4..2d47da2fd1d 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -269,7 +269,7 @@ namespace ts { getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; - getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean, getCurrentDirectoryCallBack?: GetCurrentDirectoryCallback): EmitOutput; + getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; getProgram(): Program; From fad71d3dc69bc5381ba8bb17605a9660f5a05339 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 26 Sep 2017 17:29:53 -0700 Subject: [PATCH 020/312] Use project root as the current directory whenever possible to create the project --- src/compiler/program.ts | 13 +++- src/harness/unittests/compileOnSave.ts | 2 +- src/harness/unittests/session.ts | 4 +- src/server/builder.ts | 3 +- src/server/editorServices.ts | 33 ++++++++-- src/server/lsHost.ts | 4 +- src/server/project.ts | 66 +++++++++---------- tests/cases/fourslash/server/projectInfo01.ts | 8 +-- tests/cases/fourslash/server/projectInfo02.ts | 2 +- .../server/projectWithNonExistentFiles.ts | 2 +- 10 files changed, 78 insertions(+), 59 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index c8ff2496725..1397d46af1c 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -984,11 +984,18 @@ namespace ts { return true; } - if (defaultLibraryPath && defaultLibraryPath.length !== 0) { - return containsPath(defaultLibraryPath, file.path, currentDirectory, /*ignoreCase*/ !host.useCaseSensitiveFileNames()); + if (!options.noLib) { + return false; } - return compareStrings(file.fileName, getDefaultLibraryFileName(), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === Comparison.EqualTo; + // If '--lib' is not specified, include default library file according to '--target' + // otherwise, using options specified in '--lib' instead of '--target' default library file + if (!options.lib) { + return compareStrings(file.fileName, getDefaultLibraryFileName(), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === Comparison.EqualTo; + } + else { + return forEach(options.lib, libFileName => compareStrings(file.fileName, combinePaths(defaultLibraryPath, libFileName), /*ignoreCase*/ !host.useCaseSensitiveFileNames()) === Comparison.EqualTo); + } } function getDiagnosticsProducingTypeChecker() { diff --git a/src/harness/unittests/compileOnSave.ts b/src/harness/unittests/compileOnSave.ts index 89b980f23f8..dddcd64cd39 100644 --- a/src/harness/unittests/compileOnSave.ts +++ b/src/harness/unittests/compileOnSave.ts @@ -567,7 +567,7 @@ namespace ts.projectSystem { path: "/a/b/file3.js", content: "console.log('file3');" }; - const externalProjectName = "externalproject"; + const externalProjectName = "/a/b/externalproject"; const host = createServerHost([file1, file2, file3, libFile]); const session = createSession(host); const projectService = session.getProjectService(); diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index f37c9ea2392..417591cdb6f 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -16,8 +16,8 @@ namespace ts.server { directoryExists: () => false, getDirectories: () => [], createDirectory: noop, - getExecutingFilePath(): string { return void 0; }, - getCurrentDirectory(): string { return void 0; }, + getExecutingFilePath(): string { return ""; }, + getCurrentDirectory(): string { return ""; }, getEnvironmentVariable(): string { return ""; }, readDirectory() { return []; }, exit: noop, diff --git a/src/server/builder.ts b/src/server/builder.ts index 5cf65611fb3..0279f08bfab 100644 --- a/src/server/builder.ts +++ b/src/server/builder.ts @@ -148,9 +148,8 @@ namespace ts.server { const { emitSkipped, outputFiles } = this.project.getFileEmitOutput(fileInfo.scriptInfo, /*emitOnlyDtsFiles*/ false); if (!emitSkipped) { - const projectRootPath = this.project.getProjectRootPath(); for (const outputFile of outputFiles) { - const outputFileAbsoluteFileName = getNormalizedAbsolutePath(outputFile.name, projectRootPath ? projectRootPath : getDirectoryPath(scriptInfo.fileName)); + const outputFileAbsoluteFileName = getNormalizedAbsolutePath(outputFile.name, this.project.currentDirectory); writeFile(outputFileAbsoluteFileName, outputFile.text, outputFile.writeByteOrderMark); } } diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index d86f45a9ad9..9a12c4cab7c 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -417,7 +417,7 @@ namespace ts.server { this.globalPlugins = opts.globalPlugins || emptyArray; this.pluginProbeLocations = opts.pluginProbeLocations || emptyArray; this.allowLocalPluginLoads = !!opts.allowLocalPluginLoads; - this.typesMapLocation = (opts.typesMapLocation === undefined) ? combinePaths(this.host.getExecutingFilePath(), "../typesMap.json") : opts.typesMapLocation; + this.typesMapLocation = (opts.typesMapLocation === undefined) ? combinePaths(this.getExecutingFilePath(), "../typesMap.json") : opts.typesMapLocation; Debug.assert(!!this.host.createHash, "'ServerHost.createHash' is required for ProjectService"); @@ -442,6 +442,16 @@ namespace ts.server { this.documentRegistry = createDocumentRegistry(this.host.useCaseSensitiveFileNames, this.host.getCurrentDirectory()); } + /*@internal*/ + getExecutingFilePath() { + return this.getNormalizedAbsolutePath(this.host.getExecutingFilePath()); + } + + /*@internal*/ + getNormalizedAbsolutePath(fileName: string) { + return getNormalizedAbsolutePath(fileName, this.host.getCurrentDirectory()); + } + /* @internal */ getChangedFiles_TestOnly() { return this.changedFiles; @@ -924,6 +934,14 @@ namespace ts.server { }); } + /*@internal*/ getScriptInfoPaths() { + const result: Path[] = []; + this.filenameToScriptInfo.forEach(info => { + result.push(info.path); + }); + return result; + } + /** * This function tries to search for a tsconfig.json for the given file. If we found it, * we first detect if there is already a configured project created for it: if so, we re-read @@ -1365,7 +1383,7 @@ namespace ts.server { return project; } } - return this.createInferredProject(/*isSingleInferredProject*/ false, projectRootPath); + return this.createInferredProject(projectRootPath, /*isSingleInferredProject*/ false, projectRootPath); } // we don't have an explicit root path, so we should try to find an inferred project @@ -1402,12 +1420,13 @@ namespace ts.server { return this.inferredProjects[0]; } - return this.createInferredProject(/*isSingleInferredProject*/ true); + // Single inferred project does not have a project root. + return this.createInferredProject(/*currentDirectory*/ undefined, /*isSingleInferredProject*/ true); } - private createInferredProject(isSingleInferredProject?: boolean, projectRootPath?: string): InferredProject { + private createInferredProject(currentDirectory: string | undefined, isSingleInferredProject?: boolean, projectRootPath?: string): InferredProject { const compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects; - const project = new InferredProject(this, this.documentRegistry, compilerOptions, projectRootPath); + const project = new InferredProject(this, this.documentRegistry, compilerOptions, currentDirectory, projectRootPath); if (isSingleInferredProject) { this.inferredProjects.unshift(project); } @@ -1419,8 +1438,8 @@ namespace ts.server { createInferredProjectWithRootFileIfNecessary(root: ScriptInfo, projectRootPath?: string) { const project = this.getOrCreateInferredProjectForProjectRootPathIfEnabled(root, projectRootPath) || - this.getOrCreateSingleInferredProjectIfEnabled() || - this.createInferredProject(); + this.getOrCreateSingleInferredProjectIfEnabled() || + this.createInferredProject(getDirectoryPath(root.path)); project.addRoot(root); diff --git a/src/server/lsHost.ts b/src/server/lsHost.ts index 13b9505a658..08dd5000cba 100644 --- a/src/server/lsHost.ts +++ b/src/server/lsHost.ts @@ -173,7 +173,7 @@ namespace ts.server { } getDefaultLibFileName() { - const nodeModuleBinDir = getDirectoryPath(normalizePath(this.host.getExecutingFilePath())); + const nodeModuleBinDir = getDirectoryPath(this.project.projectService.getExecutingFilePath()); return combinePaths(nodeModuleBinDir, getDefaultLibFileName(this.compilationSettings)); } @@ -203,7 +203,7 @@ namespace ts.server { } getCurrentDirectory(): string { - return this.host.getCurrentDirectory(); + return this.project.currentDirectory; } resolvePath(path: string): string { diff --git a/src/server/project.ts b/src/server/project.ts index 9ef79530e51..084193a97f5 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -177,6 +177,9 @@ namespace ts.server { return result.module; } + /*@internal*/ + readonly currentDirectory: string; + constructor( private readonly projectName: string, readonly projectKind: ProjectKind, @@ -185,8 +188,9 @@ namespace ts.server { hasExplicitListOfFiles: boolean, languageServiceEnabled: boolean, private compilerOptions: CompilerOptions, - public compileOnSaveEnabled: boolean) { - + public compileOnSaveEnabled: boolean, + currentDirectory: string | undefined) { + this.currentDirectory = this.projectService.getNormalizedAbsolutePath(currentDirectory || ""); if (!this.compilerOptions) { this.compilerOptions = getDefaultCompilerOptions(); this.compilerOptions.allowNonTsExtensions = true; @@ -268,7 +272,6 @@ namespace ts.server { getProjectName() { return this.projectName; } - abstract getProjectRootPath(): string | undefined; abstract getTypeAcquisition(): TypeAcquisition; getExternalFiles(): SortedReadonlyArray { @@ -363,7 +366,7 @@ namespace ts.server { return map(this.program.getSourceFiles(), sourceFile => { const scriptInfo = this.projectService.getScriptInfoForPath(sourceFile.path); if (!scriptInfo) { - Debug.fail(`scriptInfo for a file '${sourceFile.fileName}' is missing.`); + Debug.fail(`scriptInfo for a file '${sourceFile.fileName}' Path: '${sourceFile.path}' is missing.\nProgram currentDirectory: '${this.program.getCurrentDirectory()}'\nCurrentScriptInfos: ${this.projectService.getScriptInfoPaths()}\ncurrentDirectory: ${this.projectService.host.getCurrentDirectory()}`); } return scriptInfo; }); @@ -842,8 +845,6 @@ namespace ts.server { * the file and its imports/references are put into an InferredProject. */ export class InferredProject extends Project { - public readonly projectRootPath: string | undefined; - private static readonly newName = (() => { let nextId = 1; return () => { @@ -882,7 +883,7 @@ namespace ts.server { // Used to keep track of what directories are watched for this project directoriesWatchedForTsconfig: string[] = []; - constructor(projectService: ProjectService, documentRegistry: DocumentRegistry, compilerOptions: CompilerOptions, projectRootPath?: string) { + constructor(projectService: ProjectService, documentRegistry: DocumentRegistry, compilerOptions: CompilerOptions, currentDirectory: string | undefined, readonly projectRootPath: string | undefined) { super(InferredProject.newName(), ProjectKind.Inferred, projectService, @@ -890,7 +891,8 @@ namespace ts.server { /*files*/ undefined, /*languageServiceEnabled*/ true, compilerOptions, - /*compileOnSaveEnabled*/ false); + /*compileOnSaveEnabled*/ false, + currentDirectory); this.projectRootPath = projectRootPath; } @@ -910,15 +912,6 @@ namespace ts.server { super.removeRoot(info); } - getProjectRootPath() { - // Single inferred project does not have a project root. - if (this.projectService.useSingleInferredProject) { - return undefined; - } - const rootFiles = this.getRootFiles(); - return getDirectoryPath(rootFiles[0]); - } - close() { super.close(); @@ -962,7 +955,15 @@ namespace ts.server { private wildcardDirectories: Map, languageServiceEnabled: boolean, public compileOnSaveEnabled: boolean) { - super(configFileName, ProjectKind.Configured, projectService, documentRegistry, hasExplicitListOfFiles, languageServiceEnabled, compilerOptions, compileOnSaveEnabled); + super(configFileName, + ProjectKind.Configured, + projectService, + documentRegistry, + hasExplicitListOfFiles, + languageServiceEnabled, + compilerOptions, + compileOnSaveEnabled, + getDirectoryPath(configFileName)); this.canonicalConfigFilePath = asNormalizedPath(projectService.toCanonicalFileName(configFileName)); this.enablePlugins(); } @@ -982,7 +983,7 @@ namespace ts.server { // Search our peer node_modules, then any globally-specified probe paths // ../../.. to walk from X/node_modules/typescript/lib/tsserver.js to X/node_modules/ - const searchPaths = [combinePaths(host.getExecutingFilePath(), "../../.."), ...this.projectService.pluginProbeLocations]; + const searchPaths = [combinePaths(this.projectService.getExecutingFilePath(), "../../.."), ...this.projectService.pluginProbeLocations]; if (this.projectService.allowLocalPluginLoads) { const local = getDirectoryPath(this.canonicalConfigFilePath); @@ -1062,10 +1063,6 @@ namespace ts.server { } } - getProjectRootPath() { - return getDirectoryPath(this.getConfigFilePath()); - } - setProjectErrors(projectErrors: ReadonlyArray) { this.projectErrors = projectErrors; } @@ -1196,25 +1193,22 @@ namespace ts.server { compilerOptions: CompilerOptions, languageServiceEnabled: boolean, public compileOnSaveEnabled: boolean, - private readonly projectFilePath?: string) { - super(externalProjectName, ProjectKind.External, projectService, documentRegistry, /*hasExplicitListOfFiles*/ true, languageServiceEnabled, compilerOptions, compileOnSaveEnabled); - + projectFilePath?: string) { + super(externalProjectName, + ProjectKind.External, + projectService, + documentRegistry, + /*hasExplicitListOfFiles*/ true, + languageServiceEnabled, + compilerOptions, + compileOnSaveEnabled, + getDirectoryPath(projectFilePath || normalizeSlashes(externalProjectName))); } getExcludedFiles() { return this.excludedFiles; } - getProjectRootPath() { - if (this.projectFilePath) { - return getDirectoryPath(this.projectFilePath); - } - // if the projectFilePath is not given, we make the assumption that the project name - // is the path of the project file. AS the project name is provided by VS, we need to - // normalize slashes before using it as a file name. - return getDirectoryPath(normalizeSlashes(this.getProjectName())); - } - getTypeAcquisition() { return this.typeAcquisition; } diff --git a/tests/cases/fourslash/server/projectInfo01.ts b/tests/cases/fourslash/server/projectInfo01.ts index 0d8707bf8a1..036aa5f0d4d 100644 --- a/tests/cases/fourslash/server/projectInfo01.ts +++ b/tests/cases/fourslash/server/projectInfo01.ts @@ -14,11 +14,11 @@ ////console.log("nothing"); goTo.file("a.ts") -verify.ProjectInfo(["lib.d.ts", "a.ts"]) +verify.ProjectInfo(["/lib.d.ts", "a.ts"]) goTo.file("b.ts") -verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts"]) +verify.ProjectInfo(["/lib.d.ts", "a.ts", "b.ts"]) goTo.file("c.ts") -verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts", "c.ts"]) +verify.ProjectInfo(["/lib.d.ts", "a.ts", "b.ts", "c.ts"]) goTo.file("d.ts") -verify.ProjectInfo(["lib.d.ts", "d.ts"]) +verify.ProjectInfo(["/lib.d.ts", "d.ts"]) diff --git a/tests/cases/fourslash/server/projectInfo02.ts b/tests/cases/fourslash/server/projectInfo02.ts index 3077deb453c..fb7c9cf8257 100644 --- a/tests/cases/fourslash/server/projectInfo02.ts +++ b/tests/cases/fourslash/server/projectInfo02.ts @@ -10,4 +10,4 @@ ////{ "files": ["a.ts", "b.ts"] } goTo.file("a.ts") -verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts", "tsconfig.json"]) +verify.ProjectInfo(["/lib.d.ts", "a.ts", "b.ts", "tsconfig.json"]) diff --git a/tests/cases/fourslash/server/projectWithNonExistentFiles.ts b/tests/cases/fourslash/server/projectWithNonExistentFiles.ts index 0e263d9aca6..a52c5f8918f 100644 --- a/tests/cases/fourslash/server/projectWithNonExistentFiles.ts +++ b/tests/cases/fourslash/server/projectWithNonExistentFiles.ts @@ -10,4 +10,4 @@ ////{ "files": ["a.ts", "c.ts", "b.ts"] } goTo.file("a.ts"); -verify.ProjectInfo(["lib.d.ts", "a.ts", "b.ts", "tsconfig.json"]) +verify.ProjectInfo(["/lib.d.ts", "a.ts", "b.ts", "tsconfig.json"]) From d797b4ab7692a995662ddb11ffa7b6b83004fb13 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 28 Sep 2017 11:40:56 -0700 Subject: [PATCH 021/312] Correctly transform jsdoc parameter types And give a better name for rest params --- src/compiler/emitter.ts | 4 ++-- src/services/refactors/annotateWithTypeFromJSDoc.ts | 7 +++++-- tests/cases/fourslash/annotateWithTypeFromJSDoc16.ts | 9 +++++++++ 3 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 tests/cases/fourslash/annotateWithTypeFromJSDoc16.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 61f9773c7a0..808e8aeaf81 100755 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -578,10 +578,10 @@ namespace ts { return emitLiteralType(node); case SyntaxKind.JSDocAllType: write("*"); - break; + return; case SyntaxKind.JSDocUnknownType: write("?"); - break; + return; case SyntaxKind.JSDocNullableType: return emitJSDocNullableType(node as JSDocNullableType); case SyntaxKind.JSDocNonNullableType: diff --git a/src/services/refactors/annotateWithTypeFromJSDoc.ts b/src/services/refactors/annotateWithTypeFromJSDoc.ts index dde367f0ac9..3111c0d3ed9 100644 --- a/src/services/refactors/annotateWithTypeFromJSDoc.ts +++ b/src/services/refactors/annotateWithTypeFromJSDoc.ts @@ -189,8 +189,11 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { } function visitJSDocParameter(node: ParameterDeclaration) { - const name = node.name || "arg" + node.parent.parameters.indexOf(node); - return createParameter(node.decorators, node.modifiers, node.dotDotDotToken, name, node.questionToken, node.type, node.initializer); + const index = node.parent.parameters.indexOf(node); + const isRest = node.type.kind === SyntaxKind.JSDocVariadicType && index === node.parent.parameters.length - 1; + const name = node.name || (isRest ? "rest" : "arg" + index); + const dotdotdot = isRest ? createToken(SyntaxKind.DotDotDotToken) : node.dotDotDotToken; + return createParameter(node.decorators, node.modifiers, dotdotdot, name, node.questionToken, visitNode(node.type, transformJSDocType), node.initializer); } function visitJSDocTypeReference(node: TypeReferenceNode) { diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc16.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc16.ts new file mode 100644 index 00000000000..2f5ab2bcc72 --- /dev/null +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc16.ts @@ -0,0 +1,9 @@ +/// +// @strict: true +/////** @type {function(*, ...number, ...boolean): void} */ +////var /*1*/x; + +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`/** @type {function(*, ...number, ...boolean): void} */ +var x: (arg0: any, arg1: number[], ...rest: boolean[]) => void;`, 'Annotate with type from JSDoc', 'annotate'); From 686fd1e62d0ac8ed06a77029821a9bcf21329a48 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 4 Oct 2017 11:23:58 -0700 Subject: [PATCH 022/312] Fix whitespace around inserted static property Fixes #18743 --- src/services/codefixes/fixAddMissingMember.ts | 2 +- tests/cases/fourslash/codeFixAddMissingMember5.ts | 5 +++-- tests/cases/fourslash/codeFixAddMissingMember7.ts | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index a9583106fc6..9aba4c37f68 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -92,7 +92,7 @@ namespace ts.codefix { classDeclarationSourceFile, classDeclaration, staticInitialization, - { suffix: context.newLineCharacter }); + { prefix: context.newLineCharacter, suffix: context.newLineCharacter }); const initializeStaticAction = { description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Initialize_static_property_0), [tokenName]), changes: staticInitializationChangeTracker.getChanges() diff --git a/tests/cases/fourslash/codeFixAddMissingMember5.ts b/tests/cases/fourslash/codeFixAddMissingMember5.ts index 804a3910a8c..562c4a10f21 100644 --- a/tests/cases/fourslash/codeFixAddMissingMember5.ts +++ b/tests/cases/fourslash/codeFixAddMissingMember5.ts @@ -13,11 +13,12 @@ verify.codeFix({ description: "Initialize static property 'foo'.", index: 0, - // TODO: GH#18743 and GH#18445 + // TODO: GH#18445 newFileContent: `class C { static method() { ()=>{ this.foo === 10 }; } -}C.foo = undefined;\r +}\r +C.foo = undefined;\r ` }); diff --git a/tests/cases/fourslash/codeFixAddMissingMember7.ts b/tests/cases/fourslash/codeFixAddMissingMember7.ts index 4ed9c9293d7..014ab6102dd 100644 --- a/tests/cases/fourslash/codeFixAddMissingMember7.ts +++ b/tests/cases/fourslash/codeFixAddMissingMember7.ts @@ -11,9 +11,10 @@ verify.codeFix({ description: "Initialize static property 'foo'.", index: 2, - // TODO: GH#18743 and GH#18445 + // TODO: GH#18445 newFileContent: `class C { static p = ()=>{ this.foo === 10 }; -}C.foo = undefined;\r +}\r +C.foo = undefined;\r ` }); From 4cf289e1a57b7ff32d73efc7d9b36b932df926ec Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 4 Oct 2017 11:26:41 -0700 Subject: [PATCH 023/312] Fix whitespace around inserted property initializer Fixes #18741 --- src/services/codefixes/fixAddMissingMember.ts | 6 +++--- tests/cases/fourslash/codeFixAddMissingMember4.ts | 7 +++---- tests/cases/fourslash/codeFixAddMissingMember6.ts | 7 +++---- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 9aba4c37f68..19bd592b7a7 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -112,11 +112,11 @@ namespace ts.codefix { createIdentifier("undefined"))); const propertyInitializationChangeTracker = textChanges.ChangeTracker.fromContext(context); - propertyInitializationChangeTracker.insertNodeAt( + propertyInitializationChangeTracker.insertNodeBefore( classDeclarationSourceFile, - classConstructor.body.getEnd() - 1, + classConstructor.body.getLastToken(), propertyInitialization, - { prefix: context.newLineCharacter, suffix: context.newLineCharacter }); + { suffix: context.newLineCharacter }); const initializeAction = { description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Initialize_property_0_in_the_constructor), [tokenName]), diff --git a/tests/cases/fourslash/codeFixAddMissingMember4.ts b/tests/cases/fourslash/codeFixAddMissingMember4.ts index cfbec8977f6..a17b777ae5f 100644 --- a/tests/cases/fourslash/codeFixAddMissingMember4.ts +++ b/tests/cases/fourslash/codeFixAddMissingMember4.ts @@ -15,12 +15,11 @@ verify.codeFix({ description: "Initialize property 'foo' in the constructor.", index: 0, - // TODO: GH#18741 and GH#18445 + // TODO: GH#18445 newFileContent: `class C { constructor() { - \r -this.foo = undefined;\r -} + this.foo = undefined;\r + } method() { this.foo === 10; } diff --git a/tests/cases/fourslash/codeFixAddMissingMember6.ts b/tests/cases/fourslash/codeFixAddMissingMember6.ts index 2598014dde5..32525066657 100644 --- a/tests/cases/fourslash/codeFixAddMissingMember6.ts +++ b/tests/cases/fourslash/codeFixAddMissingMember6.ts @@ -13,12 +13,11 @@ verify.codeFix({ description: "Initialize property 'foo' in the constructor.", index: 0, - // TODO: GH#18741 and GH#18445 + // TODO: GH#18445 newFileContent: `class C { constructor() { - \r -this.foo = undefined;\r -} + this.foo = undefined;\r + } prop = ()=>{ this.foo === 10 }; }` }); From 249725d4b72a0dcdd5524457c813330002ed07a3 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 4 Oct 2017 13:25:56 -0700 Subject: [PATCH 024/312] Do not report config file errors if the file opened isnt from configured project and that project doesnt have the config errors Fixes #16635 --- src/harness/unittests/telemetry.ts | 34 +++++++--- .../unittests/tsserverProjectSystem.ts | 67 ++++++++++++++++++- src/server/editorServices.ts | 28 +++++--- src/server/project.ts | 6 +- src/server/session.ts | 8 +-- .../reference/api/tsserverlibrary.d.ts | 1 + 6 files changed, 116 insertions(+), 28 deletions(-) diff --git a/src/harness/unittests/telemetry.ts b/src/harness/unittests/telemetry.ts index 7c098066321..d2a54fdc1bb 100644 --- a/src/harness/unittests/telemetry.ts +++ b/src/harness/unittests/telemetry.ts @@ -7,7 +7,7 @@ namespace ts.projectSystem { const file = makeFile("/a.js"); const et = new EventTracker([file]); et.service.openClientFile(file.path); - assert.equal(et.getEvents().length, 0); + assert.equal(et.getEventsWithName(ts.server.ProjectInfoTelemetryEvent).length, 0); }); it("only sends an event once", () => { @@ -25,12 +25,12 @@ namespace ts.projectSystem { et.service.openClientFile(file2.path); checkNumberOfProjects(et.service, { inferredProjects: 1 }); - assert.equal(et.getEvents().length, 0); + assert.equal(et.getEventsWithName(ts.server.ProjectInfoTelemetryEvent).length, 0); et.service.openClientFile(file.path); checkNumberOfProjects(et.service, { configuredProjects: 1, inferredProjects: 1 }); - assert.equal(et.getEvents().length, 0); + assert.equal(et.getEventsWithName(ts.server.ProjectInfoTelemetryEvent).length, 0); }); it("counts files by extension", () => { @@ -219,7 +219,7 @@ namespace ts.projectSystem { const et = new EventTracker([tsconfig, file]); et.host.getFileSize = () => server.maxProgramSizeForNonTsFiles + 1; et.service.openClientFile(file.path); - et.getEvent(server.ProjectLanguageServiceStateEvent, /*mayBeMore*/ true); + et.getEvent(server.ProjectLanguageServiceStateEvent); et.assertProjectInfoTelemetryEvent({ projectId: Harness.mockHash("/jsconfig.json"), fileStats: fileStats({ js: 1 }), @@ -255,6 +255,17 @@ namespace ts.projectSystem { return events; } + getEventsWithName(eventName: T["eventName"]): ReadonlyArray { + let events: T[]; + removeWhere(this.events, event => { + if (event.eventName === eventName) { + (events || (events = [])).push(event as T); + return true; + } + }); + return events || emptyArray; + } + assertProjectInfoTelemetryEvent(partial: Partial, configFile?: string): void { assert.deepEqual(this.getEvent(ts.server.ProjectInfoTelemetryEvent), { projectId: Harness.mockHash(configFile || "/tsconfig.json"), @@ -278,10 +289,17 @@ namespace ts.projectSystem { }); } - getEvent(eventName: T["eventName"], mayBeMore = false): T["data"] { - if (mayBeMore) { assert(this.events.length !== 0); } - else { assert.equal(this.events.length, 1); } - const event = this.events.shift(); + getEvent(eventName: T["eventName"]): T["data"] { + let event: server.ProjectServiceEvent; + removeWhere(this.events, e => { + if (e.eventName === eventName) { + if (event) { + assert(false, "more than one event found"); + } + event = e; + return true; + } + }); assert.equal(event.eventName, eventName); return event.data; } diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 06e2beeaaa6..e8b18ea3b54 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -463,7 +463,7 @@ namespace ts.projectSystem { const { configFileName, configFileErrors } = projectService.openClientFile(file1.path); assert(configFileName, "should find config file"); - assert.isTrue(!configFileErrors, `expect no errors in config file, got ${JSON.stringify(configFileErrors)}`); + assert.isTrue(!configFileErrors || configFileErrors.length === 0, `expect no errors in config file, got ${JSON.stringify(configFileErrors)}`); checkNumberOfInferredProjects(projectService, 0); checkNumberOfConfiguredProjects(projectService, 1); @@ -503,7 +503,7 @@ namespace ts.projectSystem { const { configFileName, configFileErrors } = projectService.openClientFile(file1.path); assert(configFileName, "should find config file"); - assert.isTrue(!configFileErrors, `expect no errors in config file, got ${JSON.stringify(configFileErrors)}`); + assert.isTrue(!configFileErrors || configFileErrors.length === 0, `expect no errors in config file, got ${JSON.stringify(configFileErrors)}`); checkNumberOfInferredProjects(projectService, 0); checkNumberOfConfiguredProjects(projectService, 1); @@ -3169,6 +3169,69 @@ namespace ts.projectSystem { host.runQueuedTimeoutCallbacks(); serverEventManager.checkEventCountOfType("configFileDiag", 3); }); + + it("are generated when the config file doesnot include file opened but has errors", () => { + const serverEventManager = new TestServerEventManager(); + const file = { + path: "/a/b/app.ts", + content: "let x = 10" + }; + const file2 = { + path: "/a/b/test.ts", + content: "let x = 10" + }; + const configFile = { + path: "/a/b/tsconfig.json", + content: `{ + "compilerOptions": { + "foo": "bar", + "allowJS": true + }, + "files": ["app.ts"] + }` + }; + + const host = createServerHost([file, file2, libFile, configFile]); + const session = createSession(host, { + canUseEvents: true, + eventHandler: serverEventManager.handler + }); + openFilesForSession([file2], session); + serverEventManager.checkEventCountOfType("configFileDiag", 1); + for (const event of serverEventManager.events) { + if (event.eventName === "configFileDiag") { + assert.equal(event.data.configFileName, configFile.path); + assert.equal(event.data.triggerFile, file2.path); + return; + } + } + }); + + it("are not generated when the config file doesnot include file opened and doesnt contain any errors", () => { + const serverEventManager = new TestServerEventManager(); + const file = { + path: "/a/b/app.ts", + content: "let x = 10" + }; + const file2 = { + path: "/a/b/test.ts", + content: "let x = 10" + }; + const configFile = { + path: "/a/b/tsconfig.json", + content: `{ + "files": ["app.ts"] + }` + }; + + const host = createServerHost([file, file2, libFile, configFile]); + const session = createSession(host, { + canUseEvents: true, + eventHandler: serverEventManager.handler + }); + openFilesForSession([file2], session); + serverEventManager.checkEventCountOfType("configFileDiag", 0); + }); }); describe("skipLibCheck", () => { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 25a285929be..32358ba3c4c 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1561,14 +1561,17 @@ namespace ts.server { project.watchWildcards(projectOptions.wildcardDirectories); } this.updateNonInferredProject(project, projectOptions.files, fileNamePropertyReader, projectOptions.compilerOptions, projectOptions.typeAcquisition, projectOptions.compileOnSave); + this.sendConfigFileDiagEvent(project, configFileName); + } + private sendConfigFileDiagEvent(project: ConfiguredProject, triggerFile: NormalizedPath) { if (!this.eventHandler) { return; } this.eventHandler({ eventName: ConfigFileDiagEvent, - data: { configFileName, diagnostics: project.getGlobalProjectErrors() || [], triggerFile: configFileName } + data: { configFileName: project.getConfigFilePath(), diagnostics: project.getAllProjectErrors(), triggerFile } }); } @@ -1888,6 +1891,7 @@ namespace ts.server { openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult { let configFileName: NormalizedPath; + let sendConfigFileDiagEvent = false; let configFileErrors: ReadonlyArray; const info = this.getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName, fileContent, scriptKind, hasMixedContent); @@ -1898,14 +1902,8 @@ namespace ts.server { project = this.findConfiguredProjectByProjectName(configFileName); if (!project) { project = this.createConfiguredProject(configFileName); - - // even if opening config file was successful, it could still - // contain errors that were tolerated. - const errors = project.getGlobalProjectErrors(); - if (errors && errors.length > 0) { - // set configFileErrors only when the errors array is non-empty - configFileErrors = errors; - } + // Send the event only if the project got created as part of this open request + sendConfigFileDiagEvent = true; } } } @@ -1919,10 +1917,21 @@ namespace ts.server { // At this point if file is part of any any configured or external project, then it would be present in the containing projects // So if it still doesnt have any containing projects, it needs to be part of inferred project if (info.isOrphan()) { + // Since the file isnt part of configured project, + // report config file and its error only if config file found had errors (and hence may be didnt include the file) + if (sendConfigFileDiagEvent && !project.getAllProjectErrors().length) { + configFileName = undefined; + sendConfigFileDiagEvent = false; + } this.assignOrphanScriptInfoToInferredProject(info, projectRootPath); } this.addToListOfOpenFiles(info); + if (sendConfigFileDiagEvent) { + configFileErrors = project.getAllProjectErrors(); + this.sendConfigFileDiagEvent(project as ConfiguredProject, fileName); + } + // Remove the configured projects that have zero references from open files. // This was postponed from closeOpenFile to after opening next file, // so that we can reuse the project if we need to right away @@ -1938,6 +1947,7 @@ namespace ts.server { // the file from that old project is reopened because of opening file from here. this.deleteOrphanScriptInfoNotInAnyProject(); this.printProjects(); + return { configFileName, configFileErrors }; } diff --git a/src/server/project.ts b/src/server/project.ts index 655f3ed0cfc..203355ad9db 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1271,14 +1271,14 @@ namespace ts.server { * Get the errors that dont have any file name associated */ getGlobalProjectErrors(): ReadonlyArray { - return filter(this.projectErrors, diagnostic => !diagnostic.file); + return filter(this.projectErrors, diagnostic => !diagnostic.file) || emptyArray; } /** * Get all the project errors */ getAllProjectErrors(): ReadonlyArray { - return this.projectErrors; + return this.projectErrors || emptyArray; } setProjectErrors(projectErrors: Diagnostic[]) { @@ -1335,6 +1335,8 @@ namespace ts.server { } this.stopWatchingWildCards(); + this.projectErrors = undefined; + this.configFileSpecs = undefined; } addOpenRef() { diff --git a/src/server/session.ts b/src/server/session.ts index 57dac7ec799..59762f8191b 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -969,13 +969,7 @@ namespace ts.server { * @param fileContent is a version of the file content that is known to be more up to date than the one on disk */ private openClientFile(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, projectRootPath?: NormalizedPath) { - const { configFileName, configFileErrors } = this.projectService.openClientFileWithNormalizedPath(fileName, fileContent, scriptKind, /*hasMixedContent*/ false, projectRootPath); - if (this.eventHandler) { - this.eventHandler({ - eventName: "configFileDiag", - data: { triggerFile: fileName, configFileName, diagnostics: configFileErrors || emptyArray } - }); - } + this.projectService.openClientFileWithNormalizedPath(fileName, fileContent, scriptKind, /*hasMixedContent*/ false, projectRootPath); } private getPosition(args: protocol.FileLocationRequestArgs, scriptInfo: ScriptInfo): number { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 1feb6b7d073..b9b72dec922 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7517,6 +7517,7 @@ declare namespace ts.server { private createConfiguredProject(configFileName); private updateNonInferredProjectFiles(project, files, propertyReader); private updateNonInferredProject(project, newUncheckedFiles, propertyReader, newOptions, newTypeAcquisition, compileOnSave); + private sendConfigFileDiagEvent(project, triggerFile); private getOrCreateInferredProjectForProjectRootPathIfEnabled(info, projectRootPath); private getOrCreateSingleInferredProjectIfEnabled(); private createInferredProject(rootDirectoryForResolution, isSingleInferredProject?, projectRootPath?); From bf4ca30bc30b273f9bae31a2992a8c2481d8a850 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 4 Oct 2017 17:29:06 -0700 Subject: [PATCH 025/312] Let builder find out from imports/typereference directives if file references have changed. This is needed to ensure that the ambient module addition takes effect Fixes #15632 --- src/compiler/builder.ts | 7 +- src/compiler/program.ts | 3 +- src/compiler/types.ts | 2 - src/harness/unittests/tscWatchMode.ts | 142 ++++++++++++++++++++++++++ 4 files changed, 146 insertions(+), 8 deletions(-) diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 6bb94ea2de7..03eb5b7e8ae 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -77,8 +77,8 @@ namespace ts { */ onUpdateSourceFile(program: Program, sourceFile: SourceFile): void; /** - * Called when source file has not changed but has some of the resolutions invalidated - * If returned true, builder will mark the file as changed (noting that something associated with file has changed) + * Called when source file has not changed + * If returned true, builder will mark the file as changed (noting that something associated with file has changed eg. module resolution) */ onUpdateSourceFileWithSameVersion(program: Program, sourceFile: SourceFile): boolean; /** @@ -161,8 +161,7 @@ namespace ts { existingInfo.version = sourceFile.version; emitHandler.onUpdateSourceFile(program, sourceFile); } - else if (program.hasInvalidatedResolution(sourceFile.path) && - emitHandler.onUpdateSourceFileWithSameVersion(program, sourceFile)) { + else if (emitHandler.onUpdateSourceFileWithSameVersion(program, sourceFile)) { registerChangedFile(sourceFile.path, sourceFile.fileName); } } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 24d7707f50d..757e7827f27 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -663,8 +663,7 @@ namespace ts { dropDiagnosticsProducingTypeChecker, getSourceFileFromReference, sourceFileToPackageName, - redirectTargetsSet, - hasInvalidatedResolution + redirectTargetsSet }; verifyCompilerOptions(); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 578c2d23c4f..a6fccabd4dc 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2525,8 +2525,6 @@ namespace ts { /* @internal */ sourceFileToPackageName: Map; /** Set of all source files that some other source file redirects to. */ /* @internal */ redirectTargetsSet: Map; - /** Returns true when file in the program had invalidated resolution at the time of program creation. */ - /* @internal */ hasInvalidatedResolution: HasInvalidatedResolution; } /* @internal */ diff --git a/src/harness/unittests/tscWatchMode.ts b/src/harness/unittests/tscWatchMode.ts index 5267bbcf047..31d79df21c1 100644 --- a/src/harness/unittests/tscWatchMode.ts +++ b/src/harness/unittests/tscWatchMode.ts @@ -1655,5 +1655,147 @@ namespace ts.tscWatch { assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called."); checkOutputDoesNotContain(host, [barNotFound]); }); + + it("works when module resolution changes to ambient module", () => { + const root = { + path: "/a/b/foo.ts", + content: `import * as fs from "fs";` + }; + + const packageJson = { + path: "/a/b/node_modules/@types/node/package.json", + content: ` +{ + "main": "" +} +` + }; + + const nodeType = { + path: "/a/b/node_modules/@types/node/index.d.ts", + content: ` +declare module "fs" { + export interface Stats { + isFile(): boolean; + isDirectory(): boolean; + isBlockDevice(): boolean; + isCharacterDevice(): boolean; + isSymbolicLink(): boolean; + isFIFO(): boolean; + isSocket(): boolean; + dev: number; + ino: number; + mode: number; + nlink: number; + uid: number; + gid: number; + rdev: number; + size: number; + blksize: number; + blocks: number; + atimeMs: number; + mtimeMs: number; + ctimeMs: number; + birthtimeMs: number; + atime: Date; + mtime: Date; + ctime: Date; + birthtime: Date; + } +}` + }; + + const files = [root, libFile]; + const filesWithNodeType = files.concat(packageJson, nodeType); + const host = createWatchedSystem(files, { currentDirectory: "/a/b" }); + + createWatchModeWithoutConfigFile([root.path], host, { }); + + const fsNotFound = `foo.ts(1,21): error TS2307: Cannot find module 'fs'.\n`; + checkOutputContains(host, [fsNotFound]); + host.clearOutput(); + + host.reloadFS(filesWithNodeType); + host.runQueuedTimeoutCallbacks(); + checkOutputDoesNotContain(host, [fsNotFound]); + }); + + it("works when included file with ambient module changes", () => { + const root = { + path: "/a/b/foo.ts", + content: ` +import * as fs from "fs"; +import * as u from "url"; +` + }; + + const file = { + path: "/a/b/bar.d.ts", + content: ` +declare module "url" { + export interface Url { + href?: string; + protocol?: string; + auth?: string; + hostname?: string; + port?: string; + host?: string; + pathname?: string; + search?: string; + query?: string | any; + slashes?: boolean; + hash?: string; + path?: string; + } +} +` + }; + + const fileContentWithFS = ` +declare module "fs" { + export interface Stats { + isFile(): boolean; + isDirectory(): boolean; + isBlockDevice(): boolean; + isCharacterDevice(): boolean; + isSymbolicLink(): boolean; + isFIFO(): boolean; + isSocket(): boolean; + dev: number; + ino: number; + mode: number; + nlink: number; + uid: number; + gid: number; + rdev: number; + size: number; + blksize: number; + blocks: number; + atimeMs: number; + mtimeMs: number; + ctimeMs: number; + birthtimeMs: number; + atime: Date; + mtime: Date; + ctime: Date; + birthtime: Date; + } +} +`; + + const files = [root, file, libFile]; + const host = createWatchedSystem(files, { currentDirectory: "/a/b" }); + + createWatchModeWithoutConfigFile([root.path, file.path], host, {}); + + const fsNotFound = `foo.ts(2,21): error TS2307: Cannot find module 'fs'.\n`; + checkOutputContains(host, [fsNotFound]); + host.clearOutput(); + + file.content += fileContentWithFS; + host.reloadFS(files); + host.runQueuedTimeoutCallbacks(); + checkOutputDoesNotContain(host, [fsNotFound]); + }); }); } From b69652b137c280b16f7325b8dedd3bf029339f27 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 5 Oct 2017 09:01:39 -0700 Subject: [PATCH 026/312] Set symbol on union of spreads Previously, it was only set on the top-level type, and only if that top-level type was an object type. Now it uses `forEachType` to set the symbol on every object type in the union as well, if `getSpreadType` returns a union. --- src/compiler/checker.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fbe192c5629..d7585bd6e9a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13917,13 +13917,15 @@ namespace ts { if (propertiesArray.length > 0) { spread = getSpreadType(spread, createObjectLiteralType()); } - if (spread.flags & TypeFlags.Object) { - // only set the symbol and flags if this is a (fresh) object type - spread.flags |= propagatedFlags; - spread.flags |= TypeFlags.FreshLiteral; - (spread as ObjectType).objectFlags |= ObjectFlags.ObjectLiteral; - spread.symbol = node.symbol; - } + // only set the symbol and flags if this is a (fresh) object type + forEachType(spread, t => { + if (t.flags & TypeFlags.Object) { + t.flags |= propagatedFlags; + t.flags |= TypeFlags.FreshLiteral; + (t as ObjectType).objectFlags |= ObjectFlags.ObjectLiteral; + t.symbol = node.symbol + } + }); return spread; } From 0cb12b32a5abbe37b847fd93c94a435319480e61 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 5 Oct 2017 09:03:03 -0700 Subject: [PATCH 027/312] Test:{} in union from spread gets implicit index signature Also tighten up the existing test code in the file. --- .../objectSpreadIndexSignature.errors.txt | 19 ++++++ .../reference/objectSpreadIndexSignature.js | 28 ++++----- .../objectSpreadIndexSignature.symbols | 63 +++++++++---------- .../objectSpreadIndexSignature.types | 56 ++++++++--------- .../spread/objectSpreadIndexSignature.ts | 21 +++---- 5 files changed, 98 insertions(+), 89 deletions(-) create mode 100644 tests/baselines/reference/objectSpreadIndexSignature.errors.txt diff --git a/tests/baselines/reference/objectSpreadIndexSignature.errors.txt b/tests/baselines/reference/objectSpreadIndexSignature.errors.txt new file mode 100644 index 00000000000..ee7425909c2 --- /dev/null +++ b/tests/baselines/reference/objectSpreadIndexSignature.errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts(6,1): error TS7017: Element implicitly has an 'any' type because type '{ b: number; a: number; }' has no index signature. + + +==== tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts (1 errors) ==== + declare let indexed1: { [n: string]: number; a: number; }; + declare let indexed2: { [n: string]: boolean; c: boolean; }; + declare let indexed3: { [n: string]: number }; + let i = { ...indexed1, b: 11 }; + // only indexed has indexer, so i[101]: any + i[101]; + ~~~~~~ +!!! error TS7017: Element implicitly has an 'any' type because type '{ b: number; a: number; }' has no index signature. + let ii = { ...indexed1, ...indexed2 }; + // both have indexer, so i[1001]: number | boolean + ii[1001]; + + declare const b: boolean; + indexed3 = { ...b ? indexed3 : undefined }; + \ No newline at end of file diff --git a/tests/baselines/reference/objectSpreadIndexSignature.js b/tests/baselines/reference/objectSpreadIndexSignature.js index 22e92e6a844..283129036da 100644 --- a/tests/baselines/reference/objectSpreadIndexSignature.js +++ b/tests/baselines/reference/objectSpreadIndexSignature.js @@ -1,23 +1,20 @@ //// [objectSpreadIndexSignature.ts] -interface Indexed { - [n: string]: number; - a: number; -} -interface Indexed2 { - [n: string]: boolean; - c: boolean; -} -let indexed: Indexed; -let indexed2: Indexed2; -let i = { ...indexed, b: 11 }; +declare let indexed1: { [n: string]: number; a: number; }; +declare let indexed2: { [n: string]: boolean; c: boolean; }; +declare let indexed3: { [n: string]: number }; +let i = { ...indexed1, b: 11 }; // only indexed has indexer, so i[101]: any i[101]; -let ii = { ...indexed, ...indexed2 }; +let ii = { ...indexed1, ...indexed2 }; // both have indexer, so i[1001]: number | boolean ii[1001]; + +declare const b: boolean; +indexed3 = { ...b ? indexed3 : undefined }; //// [objectSpreadIndexSignature.js] +"use strict"; var __assign = (this && this.__assign) || Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; @@ -26,11 +23,10 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { } return t; }; -var indexed; -var indexed2; -var i = __assign({}, indexed, { b: 11 }); +var i = __assign({}, indexed1, { b: 11 }); // only indexed has indexer, so i[101]: any i[101]; -var ii = __assign({}, indexed, indexed2); +var ii = __assign({}, indexed1, indexed2); // both have indexer, so i[1001]: number | boolean ii[1001]; +indexed3 = __assign({}, b ? indexed3 : undefined); diff --git a/tests/baselines/reference/objectSpreadIndexSignature.symbols b/tests/baselines/reference/objectSpreadIndexSignature.symbols index cd64b157196..d08cfff53ff 100644 --- a/tests/baselines/reference/objectSpreadIndexSignature.symbols +++ b/tests/baselines/reference/objectSpreadIndexSignature.symbols @@ -1,45 +1,42 @@ === tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts === -interface Indexed { ->Indexed : Symbol(Indexed, Decl(objectSpreadIndexSignature.ts, 0, 0)) +declare let indexed1: { [n: string]: number; a: number; }; +>indexed1 : Symbol(indexed1, Decl(objectSpreadIndexSignature.ts, 0, 11)) +>n : Symbol(n, Decl(objectSpreadIndexSignature.ts, 0, 25)) +>a : Symbol(a, Decl(objectSpreadIndexSignature.ts, 0, 44)) - [n: string]: number; ->n : Symbol(n, Decl(objectSpreadIndexSignature.ts, 1, 5)) +declare let indexed2: { [n: string]: boolean; c: boolean; }; +>indexed2 : Symbol(indexed2, Decl(objectSpreadIndexSignature.ts, 1, 11)) +>n : Symbol(n, Decl(objectSpreadIndexSignature.ts, 1, 25)) +>c : Symbol(c, Decl(objectSpreadIndexSignature.ts, 1, 45)) - a: number; ->a : Symbol(Indexed.a, Decl(objectSpreadIndexSignature.ts, 1, 24)) -} -interface Indexed2 { ->Indexed2 : Symbol(Indexed2, Decl(objectSpreadIndexSignature.ts, 3, 1)) +declare let indexed3: { [n: string]: number }; +>indexed3 : Symbol(indexed3, Decl(objectSpreadIndexSignature.ts, 2, 11)) +>n : Symbol(n, Decl(objectSpreadIndexSignature.ts, 2, 25)) - [n: string]: boolean; ->n : Symbol(n, Decl(objectSpreadIndexSignature.ts, 5, 5)) - - c: boolean; ->c : Symbol(Indexed2.c, Decl(objectSpreadIndexSignature.ts, 5, 25)) -} -let indexed: Indexed; ->indexed : Symbol(indexed, Decl(objectSpreadIndexSignature.ts, 8, 3)) ->Indexed : Symbol(Indexed, Decl(objectSpreadIndexSignature.ts, 0, 0)) - -let indexed2: Indexed2; ->indexed2 : Symbol(indexed2, Decl(objectSpreadIndexSignature.ts, 9, 3)) ->Indexed2 : Symbol(Indexed2, Decl(objectSpreadIndexSignature.ts, 3, 1)) - -let i = { ...indexed, b: 11 }; ->i : Symbol(i, Decl(objectSpreadIndexSignature.ts, 10, 3)) ->indexed : Symbol(indexed, Decl(objectSpreadIndexSignature.ts, 8, 3)) ->b : Symbol(b, Decl(objectSpreadIndexSignature.ts, 10, 21)) +let i = { ...indexed1, b: 11 }; +>i : Symbol(i, Decl(objectSpreadIndexSignature.ts, 3, 3)) +>indexed1 : Symbol(indexed1, Decl(objectSpreadIndexSignature.ts, 0, 11)) +>b : Symbol(b, Decl(objectSpreadIndexSignature.ts, 3, 22)) // only indexed has indexer, so i[101]: any i[101]; ->i : Symbol(i, Decl(objectSpreadIndexSignature.ts, 10, 3)) +>i : Symbol(i, Decl(objectSpreadIndexSignature.ts, 3, 3)) -let ii = { ...indexed, ...indexed2 }; ->ii : Symbol(ii, Decl(objectSpreadIndexSignature.ts, 13, 3)) ->indexed : Symbol(indexed, Decl(objectSpreadIndexSignature.ts, 8, 3)) ->indexed2 : Symbol(indexed2, Decl(objectSpreadIndexSignature.ts, 9, 3)) +let ii = { ...indexed1, ...indexed2 }; +>ii : Symbol(ii, Decl(objectSpreadIndexSignature.ts, 6, 3)) +>indexed1 : Symbol(indexed1, Decl(objectSpreadIndexSignature.ts, 0, 11)) +>indexed2 : Symbol(indexed2, Decl(objectSpreadIndexSignature.ts, 1, 11)) // both have indexer, so i[1001]: number | boolean ii[1001]; ->ii : Symbol(ii, Decl(objectSpreadIndexSignature.ts, 13, 3)) +>ii : Symbol(ii, Decl(objectSpreadIndexSignature.ts, 6, 3)) + +declare const b: boolean; +>b : Symbol(b, Decl(objectSpreadIndexSignature.ts, 10, 13)) + +indexed3 = { ...b ? indexed3 : undefined }; +>indexed3 : Symbol(indexed3, Decl(objectSpreadIndexSignature.ts, 2, 11)) +>b : Symbol(b, Decl(objectSpreadIndexSignature.ts, 10, 13)) +>indexed3 : Symbol(indexed3, Decl(objectSpreadIndexSignature.ts, 2, 11)) +>undefined : Symbol(undefined) diff --git a/tests/baselines/reference/objectSpreadIndexSignature.types b/tests/baselines/reference/objectSpreadIndexSignature.types index 5eebc2ffa02..eff3b04b8f6 100644 --- a/tests/baselines/reference/objectSpreadIndexSignature.types +++ b/tests/baselines/reference/objectSpreadIndexSignature.types @@ -1,34 +1,22 @@ === tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts === -interface Indexed { ->Indexed : Indexed - - [n: string]: number; +declare let indexed1: { [n: string]: number; a: number; }; +>indexed1 : { [n: string]: number; a: number; } >n : string - - a: number; >a : number -} -interface Indexed2 { ->Indexed2 : Indexed2 - [n: string]: boolean; +declare let indexed2: { [n: string]: boolean; c: boolean; }; +>indexed2 : { [n: string]: boolean; c: boolean; } +>n : string +>c : boolean + +declare let indexed3: { [n: string]: number }; +>indexed3 : { [n: string]: number; } >n : string - c: boolean; ->c : boolean -} -let indexed: Indexed; ->indexed : Indexed ->Indexed : Indexed - -let indexed2: Indexed2; ->indexed2 : Indexed2 ->Indexed2 : Indexed2 - -let i = { ...indexed, b: 11 }; +let i = { ...indexed1, b: 11 }; >i : { b: number; a: number; } ->{ ...indexed, b: 11 } : { b: number; a: number; } ->indexed : Indexed +>{ ...indexed1, b: 11 } : { b: number; a: number; } +>indexed1 : { [n: string]: number; a: number; } >b : number >11 : 11 @@ -38,11 +26,11 @@ i[101]; >i : { b: number; a: number; } >101 : 101 -let ii = { ...indexed, ...indexed2 }; +let ii = { ...indexed1, ...indexed2 }; >ii : { [x: string]: number | boolean; c: boolean; a: number; } ->{ ...indexed, ...indexed2 } : { [x: string]: number | boolean; c: boolean; a: number; } ->indexed : Indexed ->indexed2 : Indexed2 +>{ ...indexed1, ...indexed2 } : { [x: string]: number | boolean; c: boolean; a: number; } +>indexed1 : { [n: string]: number; a: number; } +>indexed2 : { [n: string]: boolean; c: boolean; } // both have indexer, so i[1001]: number | boolean ii[1001]; @@ -50,3 +38,15 @@ ii[1001]; >ii : { [x: string]: number | boolean; c: boolean; a: number; } >1001 : 1001 +declare const b: boolean; +>b : boolean + +indexed3 = { ...b ? indexed3 : undefined }; +>indexed3 = { ...b ? indexed3 : undefined } : {} | { [n: string]: number; } +>indexed3 : { [n: string]: number; } +>{ ...b ? indexed3 : undefined } : {} | { [n: string]: number; } +>b ? indexed3 : undefined : { [n: string]: number; } | undefined +>b : boolean +>indexed3 : { [n: string]: number; } +>undefined : undefined + diff --git a/tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts b/tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts index ae46f2547d5..83649d465f1 100644 --- a/tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts +++ b/tests/cases/conformance/types/spread/objectSpreadIndexSignature.ts @@ -1,16 +1,13 @@ -interface Indexed { - [n: string]: number; - a: number; -} -interface Indexed2 { - [n: string]: boolean; - c: boolean; -} -let indexed: Indexed; -let indexed2: Indexed2; -let i = { ...indexed, b: 11 }; +// @strict: true +declare let indexed1: { [n: string]: number; a: number; }; +declare let indexed2: { [n: string]: boolean; c: boolean; }; +declare let indexed3: { [n: string]: number }; +let i = { ...indexed1, b: 11 }; // only indexed has indexer, so i[101]: any i[101]; -let ii = { ...indexed, ...indexed2 }; +let ii = { ...indexed1, ...indexed2 }; // both have indexer, so i[1001]: number | boolean ii[1001]; + +declare const b: boolean; +indexed3 = { ...b ? indexed3 : undefined }; From 2facead886b2850df151dca9cf2852f0e68f800c Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 5 Oct 2017 09:54:21 -0700 Subject: [PATCH 028/312] Update tests after the merge from master --- src/harness/unittests/tsserverProjectSystem.ts | 11 +++++------ src/harness/virtualFileSystemWithWatch.ts | 12 ++++++++---- tests/baselines/reference/api/tsserverlibrary.d.ts | 7 +------ 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 06e2beeaaa6..e594093605a 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -352,8 +352,6 @@ namespace ts.projectSystem { verifyDiagnostics(actual, []); } - const typeRootFromTsserverLocation = "/node_modules/@types"; - export function getTypeRootsFromLocation(currentDirectory: string) { currentDirectory = normalizePath(currentDirectory); const result: string[] = []; @@ -401,7 +399,7 @@ namespace ts.projectSystem { const configFiles = flatMap(configFileLocations, location => [location + "tsconfig.json", location + "jsconfig.json"]); checkWatchedFiles(host, configFiles.concat(libFile.path, moduleFile.path)); checkWatchedDirectories(host, [], /*recursive*/ false); - checkWatchedDirectories(host, ["/a/b/c", typeRootFromTsserverLocation], /*recursive*/ true); + checkWatchedDirectories(host, ["/a/b/c", ...getTypeRootsFromLocation(getDirectoryPath(appFile.path))], /*recursive*/ true); }); it("can handle tsconfig file name with difference casing", () => { @@ -4331,7 +4329,7 @@ namespace ts.projectSystem { function verifyCalledOnEachEntry(callback: CalledMaps, expectedKeys: Map) { const calledMap = calledMaps[callback]; - assert.equal(calledMap.size, expectedKeys.size, `${callback}: incorrect size of map: Actual keys: ${arrayFrom(calledMap.keys())} Expected: ${arrayFrom(expectedKeys.keys())}`); + ts.TestFSWithWatch.verifyMapSize(callback, calledMap, arrayFrom(expectedKeys.keys())); expectedKeys.forEach((called, name) => { assert.isTrue(calledMap.has(name), `${callback} is expected to contain ${name}, actual keys: ${arrayFrom(calledMap.keys())}`); assert.equal(calledMap.get(name).length, called, `${callback} is expected to be called ${called} times with ${name}. Actual entry: ${calledMap.get(name)}`); @@ -4413,6 +4411,7 @@ namespace ts.projectSystem { } const f2Lookups = getLocationsForModuleLookup("f2"); callsTrackingHost.verifyCalledOnEachEntryNTimes(CalledMapsWithSingleArg.fileExists, f2Lookups, 1); + const typeRootLocations = getTypeRootsFromLocation(getDirectoryPath(root.path)); const f2DirLookups = getLocationsForDirectoryLookup(); callsTrackingHost.verifyCalledOnEachEntry(CalledMapsWithSingleArg.directoryExists, f2DirLookups); callsTrackingHost.verifyNoCall(CalledMapsWithSingleArg.getDirectories); @@ -4423,7 +4422,7 @@ namespace ts.projectSystem { verifyImportedDiagnostics(); const f1Lookups = f2Lookups.map(s => s.replace("f2", "f1")); f1Lookups.length = f1Lookups.indexOf(imported.path) + 1; - const f1DirLookups = ["/c/d", "/c", typeRootFromTsserverLocation]; + const f1DirLookups = ["/c/d", "/c", ...typeRootLocations]; vertifyF1Lookups(); // setting compiler options discards module resolution cache @@ -4475,7 +4474,7 @@ namespace ts.projectSystem { function getLocationsForDirectoryLookup() { const result = createMap(); // Type root - result.set(typeRootFromTsserverLocation, 1); + typeRootLocations.forEach(location => result.set(location, 1)); forEachAncestorDirectory(getDirectoryPath(root.path), ancestor => { // To resolve modules result.set(ancestor, 2); diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index c16f57235e4..ff782bbf7d2 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -95,7 +95,7 @@ namespace ts.TestFSWithWatch { } } - function getDiffInKeys(map: Map, expectedKeys: ReadonlyArray) { + function getDiffInKeys(map: Map, expectedKeys: ReadonlyArray) { if (map.size === expectedKeys.length) { return ""; } @@ -122,8 +122,12 @@ namespace ts.TestFSWithWatch { return `\n\nNotInActual: ${notInActual}\nDuplicates: ${duplicates}\nInActualButNotInExpected: ${inActualNotExpected}`; } - function checkMapKeys(caption: string, map: Map, expectedKeys: ReadonlyArray) { + export function verifyMapSize(caption: string, map: Map, expectedKeys: ReadonlyArray) { assert.equal(map.size, expectedKeys.length, `${caption}: incorrect size of map: Actual keys: ${arrayFrom(map.keys())} Expected: ${expectedKeys}${getDiffInKeys(map, expectedKeys)}`); + } + + function checkMapKeys(caption: string, map: Map, expectedKeys: ReadonlyArray) { + verifyMapSize(caption, map, expectedKeys); for (const name of expectedKeys) { assert.isTrue(map.has(name), `${caption} is expected to contain ${name}, actual keys: ${arrayFrom(map.keys())}`); } @@ -548,7 +552,7 @@ namespace ts.TestFSWithWatch { const folder = this.toFolder(directoryName); // base folder has to be present - const base = getDirectoryPath(folder.fullPath); + const base = getDirectoryPath(folder.path); const baseFolder = this.fs.get(base) as Folder; Debug.assert(isFolder(baseFolder)); @@ -560,7 +564,7 @@ namespace ts.TestFSWithWatch { const file = this.toFile({ path, content }); // base folder has to be present - const base = getDirectoryPath(file.fullPath); + const base = getDirectoryPath(file.path); const folder = this.fs.get(base) as Folder; Debug.assert(isFolder(folder)); diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 3bb2ed11674..713188e9da8 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7131,7 +7131,6 @@ declare namespace ts.server { enableLanguageService(): void; disableLanguageService(): void; getProjectName(): string; - abstract getProjectRootPath(): string | undefined; abstract getTypeAcquisition(): TypeAcquisition; getExternalFiles(): SortedReadonlyArray; getSourceFile(path: Path): SourceFile; @@ -7184,7 +7183,6 @@ declare namespace ts.server { addRoot(info: ScriptInfo): void; removeRoot(info: ScriptInfo): void; isProjectWithSingleRoot(): boolean; - getProjectRootPath(): string; close(): void; getTypeAcquisition(): TypeAcquisition; } @@ -7211,7 +7209,6 @@ declare namespace ts.server { enablePlugins(): void; private enablePlugin(pluginConfigEntry, searchPaths); private enableProxy(pluginModuleFactory, configEntry); - getProjectRootPath(): string; /** * Get the errors that dont have any file name associated */ @@ -7237,11 +7234,9 @@ declare namespace ts.server { class ExternalProject extends Project { externalProjectName: string; compileOnSaveEnabled: boolean; - private readonly projectFilePath; excludedFiles: ReadonlyArray; private typeAcquisition; getExcludedFiles(): ReadonlyArray; - getProjectRootPath(): string; getTypeAcquisition(): TypeAcquisition; setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void; } @@ -7519,7 +7514,7 @@ declare namespace ts.server { private updateNonInferredProject(project, newUncheckedFiles, propertyReader, newOptions, newTypeAcquisition, compileOnSave); private getOrCreateInferredProjectForProjectRootPathIfEnabled(info, projectRootPath); private getOrCreateSingleInferredProjectIfEnabled(); - private createInferredProject(rootDirectoryForResolution, isSingleInferredProject?, projectRootPath?); + private createInferredProject(currentDirectory, isSingleInferredProject?, projectRootPath?); getScriptInfo(uncheckedFileName: string): ScriptInfo; private watchClosedScriptInfo(info); private stopWatchingScriptInfo(info); From 32d705dbb53b48d2d473547d7ec566d3df818df8 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 5 Oct 2017 11:29:00 -0700 Subject: [PATCH 029/312] Fine tune logging so that only triggers in watch are logged in normal logging vs verbose --- src/compiler/watch.ts | 8 ++++---- src/compiler/watchUtilities.ts | 31 +++++++++++++++++++++++++------ src/server/editorServices.ts | 5 +++++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 779efb62c46..2ab3ccc5ce6 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -249,10 +249,10 @@ namespace ts { let hasChangedAutomaticTypeDirectiveNames = false; // True if the automatic type directives have changed const loggingEnabled = compilerOptions.diagnostics || compilerOptions.extendedDiagnostics; - const writeLog: (s: string) => void = loggingEnabled ? s => system.write(s) : noop; - const watchFile = loggingEnabled ? ts.addFileWatcherWithLogging : ts.addFileWatcher; - const watchFilePath = loggingEnabled ? ts.addFilePathWatcherWithLogging : ts.addFilePathWatcher; - const watchDirectoryWorker = loggingEnabled ? ts.addDirectoryWatcherWithLogging : ts.addDirectoryWatcher; + const writeLog: (s: string) => void = loggingEnabled ? s => { system.write(s); system.write(system.newLine); } : noop; + const watchFile = compilerOptions.extendedDiagnostics ? ts.addFileWatcherWithLogging : loggingEnabled ? ts.addFileWatcherWithOnlyTriggerLogging : ts.addFileWatcher; + const watchFilePath = compilerOptions.extendedDiagnostics ? ts.addFilePathWatcherWithLogging : ts.addFilePathWatcher; + const watchDirectoryWorker = compilerOptions.extendedDiagnostics ? ts.addDirectoryWatcherWithLogging : ts.addDirectoryWatcher; watchingHost = watchingHost || createWatchingSystemHost(compilerOptions.pretty); const { system, parseConfigFile, reportDiagnostic, reportWatchDiagnostic, beforeCompile, afterCompile } = watchingHost; diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts index de415293954..26bf689401a 100644 --- a/src/compiler/watchUtilities.ts +++ b/src/compiler/watchUtilities.ts @@ -82,7 +82,12 @@ namespace ts { export function addFileWatcherWithLogging(host: System, file: string, cb: FileWatcherCallback, log: (s: string) => void): FileWatcher { const watcherCaption = `FileWatcher:: `; - return createWatcherWithLogging(addFileWatcher, watcherCaption, log, host, file, cb); + return createWatcherWithLogging(addFileWatcher, watcherCaption, log, /*logOnlyTrigger*/ false, host, file, cb); + } + + export function addFileWatcherWithOnlyTriggerLogging(host: System, file: string, cb: FileWatcherCallback, log: (s: string) => void): FileWatcher { + const watcherCaption = `FileWatcher:: `; + return createWatcherWithLogging(addFileWatcher, watcherCaption, log, /*logOnlyTrigger*/ true, host, file, cb); } export type FilePathWatcherCallback = (fileName: string, eventKind: FileWatcherEventKind, filePath: Path) => void; @@ -92,7 +97,12 @@ namespace ts { export function addFilePathWatcherWithLogging(host: System, file: string, cb: FilePathWatcherCallback, path: Path, log: (s: string) => void): FileWatcher { const watcherCaption = `FileWatcher:: `; - return createWatcherWithLogging(addFileWatcher, watcherCaption, log, host, file, cb, path); + return createWatcherWithLogging(addFileWatcher, watcherCaption, log, /*logOnlyTrigger*/ false, host, file, cb, path); + } + + export function addFilePathWatcherWithOnlyTriggerLogging(host: System, file: string, cb: FilePathWatcherCallback, path: Path, log: (s: string) => void): FileWatcher { + const watcherCaption = `FileWatcher:: `; + return createWatcherWithLogging(addFileWatcher, watcherCaption, log, /*logOnlyTrigger*/ true, host, file, cb, path); } export function addDirectoryWatcher(host: System, directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags): FileWatcher { @@ -102,14 +112,21 @@ namespace ts { export function addDirectoryWatcherWithLogging(host: System, directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags, log: (s: string) => void): FileWatcher { const watcherCaption = `DirectoryWatcher ${(flags & WatchDirectoryFlags.Recursive) !== 0 ? "recursive" : ""}:: `; - return createWatcherWithLogging(addDirectoryWatcher, watcherCaption, log, host, directory, cb, flags); + return createWatcherWithLogging(addDirectoryWatcher, watcherCaption, log, /*logOnlyTrigger*/ false, host, directory, cb, flags); + } + + export function addDirectoryWatcherWithOnlyTriggerLogging(host: System, directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags, log: (s: string) => void): FileWatcher { + const watcherCaption = `DirectoryWatcher ${(flags & WatchDirectoryFlags.Recursive) !== 0 ? "recursive" : ""}:: `; + return createWatcherWithLogging(addDirectoryWatcher, watcherCaption, log, /*logOnlyTrigger*/ true, host, directory, cb, flags); } type WatchCallback = (fileName: string, cbOptional1?: T, optional?: U) => void; type AddWatch = (host: System, file: string, cb: WatchCallback, optional?: U) => FileWatcher; - function createWatcherWithLogging(addWatch: AddWatch, watcherCaption: string, log: (s: string) => void, host: System, file: string, cb: WatchCallback, optional?: U): FileWatcher { + function createWatcherWithLogging(addWatch: AddWatch, watcherCaption: string, log: (s: string) => void, logOnlyTrigger: boolean, host: System, file: string, cb: WatchCallback, optional?: U): FileWatcher { const info = `PathInfo: ${file}`; - log(`${watcherCaption}Added: ${info}`); + if (!logOnlyTrigger) { + log(`${watcherCaption}Added: ${info}`); + } const watcher = addWatch(host, file, (fileName, cbOptional1?) => { const optionalInfo = cbOptional1 !== undefined ? ` ${cbOptional1}` : ""; log(`${watcherCaption}Trigger: ${fileName}${optionalInfo} ${info}`); @@ -120,7 +137,9 @@ namespace ts { }, optional); return { close: () => { - log(`${watcherCaption}Close: ${info}`); + if (!logOnlyTrigger) { + log(`${watcherCaption}Close: ${info}`); + } watcher.close(); } }; diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 25a285929be..2916fb60c57 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -431,6 +431,11 @@ namespace ts.server { this.watchFilePath = (host, file, cb, path, watchType, project) => ts.addFilePathWatcherWithLogging(host, file, cb, path, this.createWatcherLog(watchType, project)); this.watchDirectory = (host, dir, cb, flags, watchType, project) => ts.addDirectoryWatcherWithLogging(host, dir, cb, flags, this.createWatcherLog(watchType, project)); } + else if (this.logger.loggingEnabled()) { + this.watchFile = (host, file, cb, watchType, project) => ts.addFileWatcherWithOnlyTriggerLogging(host, file, cb, this.createWatcherLog(watchType, project)); + this.watchFilePath = (host, file, cb, path, watchType, project) => ts.addFilePathWatcherWithOnlyTriggerLogging(host, file, cb, path, this.createWatcherLog(watchType, project)); + this.watchDirectory = (host, dir, cb, flags, watchType, project) => ts.addDirectoryWatcherWithOnlyTriggerLogging(host, dir, cb, flags, this.createWatcherLog(watchType, project)); + } else { this.watchFile = ts.addFileWatcher; this.watchFilePath = ts.addFilePathWatcher; From a5e184118088342db9db79c49f6cb95e53f63b72 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 5 Oct 2017 15:37:47 -0700 Subject: [PATCH 030/312] Handle undefined in getSynthesizedClone --- src/compiler/factory.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 968144c0fc7..fe183c5e806 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -47,10 +47,15 @@ namespace ts { * Creates a shallow, memberwise clone of a node with no source map location. */ /* @internal */ - export function getSynthesizedClone(node: T | undefined): T { + export function getSynthesizedClone(node: T | undefined): T | undefined { // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of // the original node. We also need to exclude specific properties and only include own- // properties (to skip members already defined on the shared prototype). + + if (node === undefined) { + return undefined; + } + const clone = createSynthesizedNode(node.kind); clone.flags |= node.flags; setOriginalNode(clone, node); From 380b8df13f3ff9deaf36c6a7aa3ae0c7fd4ce960 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 5 Oct 2017 15:38:02 -0700 Subject: [PATCH 031/312] Introduce getSynthesizedDeepClone --- src/compiler/factory.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index fe183c5e806..84c28abe1a5 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -71,6 +71,15 @@ namespace ts { return clone; } + /** + * Creates a deep, memberwise clone of a node with no source map location. + */ + export function getSynthesizedDeepClone(node: T | undefined): T | undefined { + return node + ? getSynthesizedClone(visitEachChild(node, child => getSynthesizedDeepClone(child), nullTransformationContext)) + : undefined; + } + // Literals export function createLiteral(value: string): StringLiteral; From ad148dbc8800da4bbd2863a68f6f6617ee776a7a Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 5 Oct 2017 15:46:14 -0700 Subject: [PATCH 032/312] Use deep cloning, rather than thunking for repeated substitution Replaces b244cd4fb47 --- src/services/refactors/extractSymbol.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 0e2f5ebfe3c..0176841e346 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -1064,7 +1064,7 @@ namespace ts.refactor.extractSymbol { } } - function transformFunctionBody(body: Node, writes: ReadonlyArray, substitutions: ReadonlyMap<() => Node>, hasReturn: boolean): { body: Block, returnValueProperty: string } { + function transformFunctionBody(body: Node, writes: ReadonlyArray, substitutions: ReadonlyMap, hasReturn: boolean): { body: Block, returnValueProperty: string } { if (isBlock(body) && !writes && substitutions.size === 0) { // already block, no writes to propagate back, no substitutions - can use node as is return { body: createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined }; @@ -1112,21 +1112,21 @@ namespace ts.refactor.extractSymbol { const oldIgnoreReturns = ignoreReturns; ignoreReturns = ignoreReturns || isFunctionLikeDeclaration(node) || isClassLike(node); const substitution = substitutions.get(getNodeId(node).toString()); - const result = substitution ? substitution() : visitEachChild(node, visitor, nullTransformationContext); + const result = substitution ? getSynthesizedDeepClone(substitution) : visitEachChild(node, visitor, nullTransformationContext); ignoreReturns = oldIgnoreReturns; return result; } } } - function transformConstantInitializer(initializer: Expression, substitutions: ReadonlyMap<() => Node>): Expression { + function transformConstantInitializer(initializer: Expression, substitutions: ReadonlyMap): Expression { return substitutions.size ? visitor(initializer) as Expression : initializer; function visitor(node: Node): VisitResult { const substitution = substitutions.get(getNodeId(node).toString()); - return substitution ? substitution() : visitEachChild(node, visitor, nullTransformationContext); + return substitution ? getSynthesizedDeepClone(substitution) : visitEachChild(node, visitor, nullTransformationContext); } } @@ -1255,7 +1255,7 @@ namespace ts.refactor.extractSymbol { interface ScopeUsages { readonly usages: Map; readonly typeParameterUsages: Map; // Key is type ID - readonly substitutions: Map<() => Node>; + readonly substitutions: Map; } interface ReadsAndWrites { @@ -1274,7 +1274,7 @@ namespace ts.refactor.extractSymbol { const allTypeParameterUsages = createMap(); // Key is type ID const usagesPerScope: ScopeUsages[] = []; - const substitutionsPerScope: Map<() => Node>[] = []; + const substitutionsPerScope: Map[] = []; const functionErrorsPerScope: Diagnostic[][] = []; const constantErrorsPerScope: Diagnostic[][] = []; const visibleDeclarationsInExtractedRange: Symbol[] = []; @@ -1298,8 +1298,8 @@ namespace ts.refactor.extractSymbol { // initialize results for (const scope of scopes) { - usagesPerScope.push({ usages: createMap(), typeParameterUsages: createMap(), substitutions: createMap<() => Expression>() }); - substitutionsPerScope.push(createMap<() => Expression>()); + usagesPerScope.push({ usages: createMap(), typeParameterUsages: createMap(), substitutions: createMap() }); + substitutionsPerScope.push(createMap()); functionErrorsPerScope.push( isFunctionLikeDeclaration(scope) && scope.kind !== SyntaxKind.FunctionDeclaration @@ -1598,20 +1598,20 @@ namespace ts.refactor.extractSymbol { } } - function tryReplaceWithQualifiedNameOrPropertyAccess(symbol: Symbol, scopeDecl: Node, isTypeNode: boolean): () => (PropertyAccessExpression | EntityName) { + function tryReplaceWithQualifiedNameOrPropertyAccess(symbol: Symbol, scopeDecl: Node, isTypeNode: boolean): PropertyAccessExpression | EntityName { if (!symbol) { return undefined; } if (symbol.getDeclarations().some(d => d.parent === scopeDecl)) { - return () => createIdentifier(symbol.name); + return createIdentifier(symbol.name); } const prefix = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.parent, scopeDecl, isTypeNode); if (prefix === undefined) { return undefined; } return isTypeNode - ? () => createQualifiedName(prefix(), createIdentifier(symbol.name)) - : () => createPropertyAccess(prefix(), symbol.name); + ? createQualifiedName(prefix, createIdentifier(symbol.name)) + : createPropertyAccess(prefix, symbol.name); } } From 5c9f8c56d95eee6bc897c8dfb64c398bf0e273fd Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Fri, 6 Oct 2017 10:20:12 -0700 Subject: [PATCH 033/312] Mark getSynthesizedDeepClone @internal --- src/compiler/factory.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 84c28abe1a5..7d703ffe062 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -74,6 +74,7 @@ namespace ts { /** * Creates a deep, memberwise clone of a node with no source map location. */ + /* @internal */ export function getSynthesizedDeepClone(node: T | undefined): T | undefined { return node ? getSynthesizedClone(visitEachChild(node, child => getSynthesizedDeepClone(child), nullTransformationContext)) From fbf8df66f006553bc720751389e18d98a3f9b3cf Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 6 Oct 2017 14:27:32 -0700 Subject: [PATCH 034/312] accept baselines --- tests/baselines/reference/APISample_jsdoc.js | 4 ++-- tests/baselines/reference/api/tsserverlibrary.d.ts | 4 ++++ tests/baselines/reference/api/typescript.d.ts | 4 ++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/APISample_jsdoc.js b/tests/baselines/reference/APISample_jsdoc.js index 33857d06a6a..c74e188f38b 100644 --- a/tests/baselines/reference/APISample_jsdoc.js +++ b/tests/baselines/reference/APISample_jsdoc.js @@ -101,7 +101,7 @@ function getAllTags(node: ts.Node) { function getSomeOtherTags(node: ts.Node) { const tags: (ts.JSDocTag | undefined)[] = []; - tags.push(ts.getJSDocAugmentsOrExtendsTag(node)); + tags.push(ts.getJSDocAugmentsTag(node)); tags.push(ts.getJSDocClassTag(node)); tags.push(ts.getJSDocReturnTag(node)); const type = ts.getJSDocTypeTag(node); @@ -200,7 +200,7 @@ function getAllTags(node) { } function getSomeOtherTags(node) { var tags = []; - tags.push(ts.getJSDocAugmentsOrExtendsTag(node)); + tags.push(ts.getJSDocAugmentsTag(node)); tags.push(ts.getJSDocClassTag(node)); tags.push(ts.getJSDocReturnTag(node)); var type = ts.getJSDocTypeTag(node); diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 3bb2ed11674..ca8696b11fb 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1442,6 +1442,10 @@ declare namespace ts { interface JSDocUnknownTag extends JSDocTag { kind: SyntaxKind.JSDocTag; } + /** + * Note that `@extends` is a synonym of `@augments`. + * Both tags are represented by this interface. + */ interface JSDocAugmentsTag extends JSDocTag { kind: SyntaxKind.JSDocAugmentsTag; class: ExpressionWithTypeArguments & { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index d41db2eb413..820be44f1f1 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1442,6 +1442,10 @@ declare namespace ts { interface JSDocUnknownTag extends JSDocTag { kind: SyntaxKind.JSDocTag; } + /** + * Note that `@extends` is a synonym of `@augments`. + * Both tags are represented by this interface. + */ interface JSDocAugmentsTag extends JSDocTag { kind: SyntaxKind.JSDocAugmentsTag; class: ExpressionWithTypeArguments & { From 0afaadba3b83dfbad89a8c2c5d812ef8ab783361 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 6 Oct 2017 15:56:39 -0700 Subject: [PATCH 035/312] add error for multiple tags --- src/compiler/checker.ts | 14 ++++-- src/compiler/diagnosticMessages.json | 4 ++ src/compiler/utilities.ts | 6 +++ .../fourslash/jsDocAugmentsAndExtends.ts | 50 +++++++++++++++++++ 4 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 tests/cases/fourslash/jsDocAugmentsAndExtends.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 718fd76625f..31c9acd8fb1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20009,14 +20009,20 @@ namespace ts { } function checkJSDocAugmentsTag(node: JSDocAugmentsTag): void { - const cls = getJSDocHost(node); - if (!isClassDeclaration(cls) && !isClassExpression(cls)) { - error(cls, Diagnostics.JSDoc_augments_is_not_attached_to_a_class_declaration); + const classLike = getJSDocHost(node); + if (!isClassDeclaration(classLike) && !isClassExpression(classLike)) { + error(classLike, Diagnostics.JSDoc_augments_is_not_attached_to_a_class_declaration); return; } + const augmentsTags = getAllJSDocTagsOfKind(classLike, SyntaxKind.JSDocAugmentsTag); + Debug.assert(augmentsTags.length > 0); + if (augmentsTags.length > 1) { + error(augmentsTags[1], Diagnostics.The_total_number_of_augments_and_extends_tags_allowed_for_a_single_class_declaration_is_at_most_1); + } + const name = getIdentifierFromEntityNameExpression(node.class.expression); - const extend = getClassExtendsHeritageClauseElement(cls); + const extend = getClassExtendsHeritageClauseElement(classLike); if (extend) { const className = getIdentifierFromEntityNameExpression(extend.expression); if (className && name.escapedText !== className.escapedText) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index f3d6d4fcc47..64c4d99d349 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3527,6 +3527,10 @@ "category": "Error", "code": 8024 }, + "The total number of `@augments` and `@extends` tags allowed for a single class declaration is at most 1.": { + "category": "Error", + "code": 8025 + }, "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause.": { "category": "Error", "code": 9002 diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index f0eb394adb7..825b310ddeb 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4247,6 +4247,12 @@ namespace ts { return find(tags, doc => doc.kind === kind); } + /** Gets all JSDoc tags of a specified kind, or undefined if not present. */ + export function getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): ReadonlyArray | undefined { + const tags = getJSDocTags(node); + return filter(tags, doc => doc.kind === kind); + } + } // Simple node tests of the form `node.kind === SyntaxKind.Foo`. diff --git a/tests/cases/fourslash/jsDocAugmentsAndExtends.ts b/tests/cases/fourslash/jsDocAugmentsAndExtends.ts new file mode 100644 index 00000000000..e76a617a3cf --- /dev/null +++ b/tests/cases/fourslash/jsDocAugmentsAndExtends.ts @@ -0,0 +1,50 @@ +/// + +// @allowJs: true +// @checkJs: true +// @Filename: dummy.js + +//// /** +//// * @augments {Thing} +//// * @extends {Thing} +//// */ +//// class MyStringThing extends Thing { +//// constructor() { +//// var x = this.mine; +//// x/**/; +//// } +//// } + +// @Filename: declarations.d.ts +//// declare class Thing { +//// mine: T; +//// } + +// if more than one tag is present, report an error and take the type of the first entry. + +goTo.marker(); +verify.quickInfoIs("(local var) x: number"); +verify.getSemanticDiagnostics( +`[ + { + "message": "The total number of \`@augments\` and \`@extends\` tags allowed for a single class declaration is at most 1.", + "start": 36, + "length": 24, + "category": "error", + "code": 8025 + }, + { + "message": "Constructors for derived classes must contain a \'super\' call.", + "start": 105, + "length": 59, + "category": "error", + "code": 2377 + }, + { + "message": "\'super\' must be called before accessing \'this\' in the constructor of a derived class.", + "start": 137, + "length": 4, + "category": "error", + "code": 17009 + } +]`); \ No newline at end of file From 932b1b038c712b73eda432b5296263fe32af6a6d Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Fri, 6 Oct 2017 16:16:37 -0700 Subject: [PATCH 036/312] better error message --- src/compiler/checker.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- .../cases/fourslash/jsDocAugmentsAndExtends.ts | 17 ++--------------- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 31c9acd8fb1..aa5d10c475c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20018,7 +20018,7 @@ namespace ts { const augmentsTags = getAllJSDocTagsOfKind(classLike, SyntaxKind.JSDocAugmentsTag); Debug.assert(augmentsTags.length > 0); if (augmentsTags.length > 1) { - error(augmentsTags[1], Diagnostics.The_total_number_of_augments_and_extends_tags_allowed_for_a_single_class_declaration_is_at_most_1); + error(augmentsTags[1], Diagnostics.Class_declarations_cannot_have_more_than_one_augments_or_extends_tag); } const name = getIdentifierFromEntityNameExpression(node.class.expression); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 64c4d99d349..e0de43a97db 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3527,7 +3527,7 @@ "category": "Error", "code": 8024 }, - "The total number of `@augments` and `@extends` tags allowed for a single class declaration is at most 1.": { + "Class declarations cannot have more than one `@augments` or `@extends` tag.": { "category": "Error", "code": 8025 }, diff --git a/tests/cases/fourslash/jsDocAugmentsAndExtends.ts b/tests/cases/fourslash/jsDocAugmentsAndExtends.ts index e76a617a3cf..10f33260268 100644 --- a/tests/cases/fourslash/jsDocAugmentsAndExtends.ts +++ b/tests/cases/fourslash/jsDocAugmentsAndExtends.ts @@ -10,6 +10,7 @@ //// */ //// class MyStringThing extends Thing { //// constructor() { +//// super(); //// var x = this.mine; //// x/**/; //// } @@ -27,24 +28,10 @@ verify.quickInfoIs("(local var) x: number"); verify.getSemanticDiagnostics( `[ { - "message": "The total number of \`@augments\` and \`@extends\` tags allowed for a single class declaration is at most 1.", + "message": "Class declarations cannot have more than one \`@augments\` or \`@extends\` tag.", "start": 36, "length": 24, "category": "error", "code": 8025 - }, - { - "message": "Constructors for derived classes must contain a \'super\' call.", - "start": 105, - "length": 59, - "category": "error", - "code": 2377 - }, - { - "message": "\'super\' must be called before accessing \'this\' in the constructor of a derived class.", - "start": 137, - "length": 4, - "category": "error", - "code": 17009 } ]`); \ No newline at end of file From 9e00df590d638cad1266e388385396aea2879cc3 Mon Sep 17 00:00:00 2001 From: Charles Pierce Date: Fri, 6 Oct 2017 19:46:29 -0700 Subject: [PATCH 037/312] Error when accessing abstract property in constructor #9230 --- src/compiler/checker.ts | 28 ++++++++-- src/compiler/diagnosticMessages.json | 4 ++ .../abstractPropertyInConstructor.errors.txt | 25 +++++++++ .../abstractPropertyInConstructor.js | 30 ++++++++++ .../abstractPropertyInConstructor.symbols | 48 ++++++++++++++++ .../abstractPropertyInConstructor.types | 56 +++++++++++++++++++ .../compiler/abstractPropertyInConstructor.ts | 15 +++++ 7 files changed, 201 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/abstractPropertyInConstructor.errors.txt create mode 100644 tests/baselines/reference/abstractPropertyInConstructor.js create mode 100644 tests/baselines/reference/abstractPropertyInConstructor.symbols create mode 100644 tests/baselines/reference/abstractPropertyInConstructor.types create mode 100644 tests/cases/compiler/abstractPropertyInConstructor.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a8e18c432a6..9a483ae50ed 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14826,11 +14826,7 @@ namespace ts { // where this references the constructor function object of a derived class, // a super property access is permitted and must specify a public static member function of the base class. if (languageVersion < ScriptTarget.ES2015) { - const hasNonMethodDeclaration = forEachProperty(prop, p => { - const propKind = getDeclarationKindFromSymbol(p); - return propKind !== SyntaxKind.MethodDeclaration && propKind !== SyntaxKind.MethodSignature; - }); - if (hasNonMethodDeclaration) { + if (symbolHasNonMethodDeclaration(prop)) { error(errorNode, Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword); return false; } @@ -14845,6 +14841,17 @@ namespace ts { } } + // Referencing Abstract Properties within Constructors is not allowed + if ((flags & ModifierFlags.Abstract) && symbolHasNonMethodDeclaration(prop)) { + const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)); + const declaringClassConstructor = declaringClassDeclaration && findConstructorDeclaration(declaringClassDeclaration); + + if (declaringClassConstructor && isNodeWithinFunction(node, declaringClassConstructor)) { + error(errorNode, Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_constructor, symbolToString(prop), typeToString(getDeclaringClass(prop))); + return false; + } + } + // Public properties are otherwise accessible. if (!(flags & ModifierFlags.NonPublicAccessibilityModifier)) { return true; @@ -14896,6 +14903,13 @@ namespace ts { return true; } + function symbolHasNonMethodDeclaration(symbol: Symbol) { + return forEachProperty(symbol, prop => { + const propKind = getDeclarationKindFromSymbol(prop); + return propKind !== SyntaxKind.MethodDeclaration && propKind !== SyntaxKind.MethodSignature; + }); + } + function checkNonNullExpression(node: Expression | QualifiedName) { return checkNonNullType(checkExpression(node), node); } @@ -23139,6 +23153,10 @@ namespace ts { return result; } + function isNodeWithinFunction(node: Node, functionDeclaration: FunctionLike) { + return getContainingFunction(node) === functionDeclaration; + } + function isNodeWithinClass(node: Node, classDeclaration: ClassLikeDeclaration) { return !!forEachEnclosingClass(node, n => n === classDeclaration); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index f3d6d4fcc47..e2d514ba268 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2220,6 +2220,10 @@ "category": "Error", "code": 2714 }, + "Abstract property '{0}' in class '{1}' cannot be accessed in constructor.": { + "category": "Error", + "code": 2715 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/tests/baselines/reference/abstractPropertyInConstructor.errors.txt b/tests/baselines/reference/abstractPropertyInConstructor.errors.txt new file mode 100644 index 00000000000..7e654b440c6 --- /dev/null +++ b/tests/baselines/reference/abstractPropertyInConstructor.errors.txt @@ -0,0 +1,25 @@ +tests/cases/compiler/abstractPropertyInConstructor.ts(4,24): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in constructor. +tests/cases/compiler/abstractPropertyInConstructor.ts(5,14): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in constructor. + + +==== tests/cases/compiler/abstractPropertyInConstructor.ts (2 errors) ==== + abstract class AbstractClass { + constructor(str: string) { + this.method(parseInt(str)); + let val = this.prop.toLowerCase(); + ~~~~ +!!! error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in constructor. + this.prop = "Hello World"; + ~~~~ +!!! error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in constructor. + } + + abstract prop: string; + + abstract method(num: number): void; + + method2() { + this.prop = this.prop + "!"; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/abstractPropertyInConstructor.js b/tests/baselines/reference/abstractPropertyInConstructor.js new file mode 100644 index 00000000000..c6d7de6c037 --- /dev/null +++ b/tests/baselines/reference/abstractPropertyInConstructor.js @@ -0,0 +1,30 @@ +//// [abstractPropertyInConstructor.ts] +abstract class AbstractClass { + constructor(str: string) { + this.method(parseInt(str)); + let val = this.prop.toLowerCase(); + this.prop = "Hello World"; + } + + abstract prop: string; + + abstract method(num: number): void; + + method2() { + this.prop = this.prop + "!"; + } +} + + +//// [abstractPropertyInConstructor.js] +var AbstractClass = /** @class */ (function () { + function AbstractClass(str) { + this.method(parseInt(str)); + var val = this.prop.toLowerCase(); + this.prop = "Hello World"; + } + AbstractClass.prototype.method2 = function () { + this.prop = this.prop + "!"; + }; + return AbstractClass; +}()); diff --git a/tests/baselines/reference/abstractPropertyInConstructor.symbols b/tests/baselines/reference/abstractPropertyInConstructor.symbols new file mode 100644 index 00000000000..7d634f80267 --- /dev/null +++ b/tests/baselines/reference/abstractPropertyInConstructor.symbols @@ -0,0 +1,48 @@ +=== tests/cases/compiler/abstractPropertyInConstructor.ts === +abstract class AbstractClass { +>AbstractClass : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) + + constructor(str: string) { +>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16)) + + this.method(parseInt(str)); +>this.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 7, 26)) +>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) +>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 7, 26)) +>parseInt : Symbol(parseInt, Decl(lib.d.ts, --, --)) +>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16)) + + let val = this.prop.toLowerCase(); +>val : Symbol(val, Decl(abstractPropertyInConstructor.ts, 3, 11)) +>this.prop.toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --)) +>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) +>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) +>toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --)) + + this.prop = "Hello World"; +>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) +>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) + } + + abstract prop: string; +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) + + abstract method(num: number): void; +>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 7, 26)) +>num : Symbol(num, Decl(abstractPropertyInConstructor.ts, 9, 20)) + + method2() { +>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 9, 39)) + + this.prop = this.prop + "!"; +>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) +>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) +>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) +>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) + } +} + diff --git a/tests/baselines/reference/abstractPropertyInConstructor.types b/tests/baselines/reference/abstractPropertyInConstructor.types new file mode 100644 index 00000000000..05f7a7752e6 --- /dev/null +++ b/tests/baselines/reference/abstractPropertyInConstructor.types @@ -0,0 +1,56 @@ +=== tests/cases/compiler/abstractPropertyInConstructor.ts === +abstract class AbstractClass { +>AbstractClass : AbstractClass + + constructor(str: string) { +>str : string + + this.method(parseInt(str)); +>this.method(parseInt(str)) : void +>this.method : (num: number) => void +>this : this +>method : (num: number) => void +>parseInt(str) : number +>parseInt : (s: string, radix?: number) => number +>str : string + + let val = this.prop.toLowerCase(); +>val : string +>this.prop.toLowerCase() : string +>this.prop.toLowerCase : () => string +>this.prop : string +>this : this +>prop : string +>toLowerCase : () => string + + this.prop = "Hello World"; +>this.prop = "Hello World" : "Hello World" +>this.prop : string +>this : this +>prop : string +>"Hello World" : "Hello World" + } + + abstract prop: string; +>prop : string + + abstract method(num: number): void; +>method : (num: number) => void +>num : number + + method2() { +>method2 : () => void + + this.prop = this.prop + "!"; +>this.prop = this.prop + "!" : string +>this.prop : string +>this : this +>prop : string +>this.prop + "!" : string +>this.prop : string +>this : this +>prop : string +>"!" : "!" + } +} + diff --git a/tests/cases/compiler/abstractPropertyInConstructor.ts b/tests/cases/compiler/abstractPropertyInConstructor.ts new file mode 100644 index 00000000000..5376aae9d6f --- /dev/null +++ b/tests/cases/compiler/abstractPropertyInConstructor.ts @@ -0,0 +1,15 @@ +abstract class AbstractClass { + constructor(str: string) { + this.method(parseInt(str)); + let val = this.prop.toLowerCase(); + this.prop = "Hello World"; + } + + abstract prop: string; + + abstract method(num: number): void; + + method2() { + this.prop = this.prop + "!"; + } +} From 79f5d968a120e469dbaf432aaad101a708989a6d Mon Sep 17 00:00:00 2001 From: Charles Pierce Date: Mon, 9 Oct 2017 10:57:08 -0700 Subject: [PATCH 038/312] Use ancestor walk to determine if property access is within constructor #9230 --- src/compiler/checker.ts | 17 ++++-- src/compiler/diagnosticMessages.json | 2 +- .../abstractPropertyInConstructor.errors.txt | 26 +++++++--- .../abstractPropertyInConstructor.js | 20 ++++++- .../abstractPropertyInConstructor.symbols | 52 +++++++++++++------ .../abstractPropertyInConstructor.types | 27 +++++++++- .../compiler/abstractPropertyInConstructor.ts | 11 +++- 7 files changed, 123 insertions(+), 32 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9a483ae50ed..8afee9455cf 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14844,10 +14844,9 @@ namespace ts { // Referencing Abstract Properties within Constructors is not allowed if ((flags & ModifierFlags.Abstract) && symbolHasNonMethodDeclaration(prop)) { const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)); - const declaringClassConstructor = declaringClassDeclaration && findConstructorDeclaration(declaringClassDeclaration); - if (declaringClassConstructor && isNodeWithinFunction(node, declaringClassConstructor)) { - error(errorNode, Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_constructor, symbolToString(prop), typeToString(getDeclaringClass(prop))); + if (declaringClassDeclaration && isNodeWithinConstructor(node, declaringClassDeclaration)) { + error(errorNode, Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), typeToString(getDeclaringClass(prop))); return false; } } @@ -23153,8 +23152,16 @@ namespace ts { return result; } - function isNodeWithinFunction(node: Node, functionDeclaration: FunctionLike) { - return getContainingFunction(node) === functionDeclaration; + function isNodeWithinConstructor(node: Node, classDeclaration: ClassLikeDeclaration) { + return findAncestor(node, element => { + if (isConstructorDeclaration(element) && nodeIsPresent(element.body)) { + return true; + } else if (element === classDeclaration || isFunctionLikeDeclaration(element)) { + return "quit"; + } + + return false; + }); } function isNodeWithinClass(node: Node, classDeclaration: ClassLikeDeclaration) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index e2d514ba268..9b220a880b0 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2220,7 +2220,7 @@ "category": "Error", "code": 2714 }, - "Abstract property '{0}' in class '{1}' cannot be accessed in constructor.": { + "Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.": { "category": "Error", "code": 2715 }, diff --git a/tests/baselines/reference/abstractPropertyInConstructor.errors.txt b/tests/baselines/reference/abstractPropertyInConstructor.errors.txt index 7e654b440c6..461dd713d3b 100644 --- a/tests/baselines/reference/abstractPropertyInConstructor.errors.txt +++ b/tests/baselines/reference/abstractPropertyInConstructor.errors.txt @@ -1,20 +1,32 @@ -tests/cases/compiler/abstractPropertyInConstructor.ts(4,24): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in constructor. -tests/cases/compiler/abstractPropertyInConstructor.ts(5,14): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in constructor. +tests/cases/compiler/abstractPropertyInConstructor.ts(4,24): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor. +tests/cases/compiler/abstractPropertyInConstructor.ts(7,18): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor. +tests/cases/compiler/abstractPropertyInConstructor.ts(9,14): error TS2715: Abstract property 'cb' in class 'AbstractClass' cannot be accessed in the constructor. -==== tests/cases/compiler/abstractPropertyInConstructor.ts (2 errors) ==== +==== tests/cases/compiler/abstractPropertyInConstructor.ts (3 errors) ==== abstract class AbstractClass { constructor(str: string) { this.method(parseInt(str)); let val = this.prop.toLowerCase(); ~~~~ -!!! error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in constructor. - this.prop = "Hello World"; - ~~~~ -!!! error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in constructor. +!!! error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor. + + if (!str) { + this.prop = "Hello World"; + ~~~~ +!!! error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor. + } + this.cb(str); + ~~ +!!! error TS2715: Abstract property 'cb' in class 'AbstractClass' cannot be accessed in the constructor. + + const innerFunction = () => { + return this.prop; + } } abstract prop: string; + abstract cb: (s: string) => void; abstract method(num: number): void; diff --git a/tests/baselines/reference/abstractPropertyInConstructor.js b/tests/baselines/reference/abstractPropertyInConstructor.js index c6d7de6c037..18a2937a191 100644 --- a/tests/baselines/reference/abstractPropertyInConstructor.js +++ b/tests/baselines/reference/abstractPropertyInConstructor.js @@ -3,10 +3,19 @@ abstract class AbstractClass { constructor(str: string) { this.method(parseInt(str)); let val = this.prop.toLowerCase(); - this.prop = "Hello World"; + + if (!str) { + this.prop = "Hello World"; + } + this.cb(str); + + const innerFunction = () => { + return this.prop; + } } abstract prop: string; + abstract cb: (s: string) => void; abstract method(num: number): void; @@ -19,9 +28,16 @@ abstract class AbstractClass { //// [abstractPropertyInConstructor.js] var AbstractClass = /** @class */ (function () { function AbstractClass(str) { + var _this = this; this.method(parseInt(str)); var val = this.prop.toLowerCase(); - this.prop = "Hello World"; + if (!str) { + this.prop = "Hello World"; + } + this.cb(str); + var innerFunction = function () { + return _this.prop; + }; } AbstractClass.prototype.method2 = function () { this.prop = this.prop + "!"; diff --git a/tests/baselines/reference/abstractPropertyInConstructor.symbols b/tests/baselines/reference/abstractPropertyInConstructor.symbols index 7d634f80267..0d542ffb0a8 100644 --- a/tests/baselines/reference/abstractPropertyInConstructor.symbols +++ b/tests/baselines/reference/abstractPropertyInConstructor.symbols @@ -6,43 +6,65 @@ abstract class AbstractClass { >str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16)) this.method(parseInt(str)); ->this.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 7, 26)) +>this.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 16, 37)) >this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) ->method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 7, 26)) +>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 16, 37)) >parseInt : Symbol(parseInt, Decl(lib.d.ts, --, --)) >str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16)) let val = this.prop.toLowerCase(); >val : Symbol(val, Decl(abstractPropertyInConstructor.ts, 3, 11)) >this.prop.toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --)) ->this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) +>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) >this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) ->prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) >toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --)) - this.prop = "Hello World"; ->this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) + if (!str) { +>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16)) + + this.prop = "Hello World"; +>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) >this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) ->prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) + } + this.cb(str); +>this.cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 15, 26)) +>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) +>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 15, 26)) +>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16)) + + const innerFunction = () => { +>innerFunction : Symbol(innerFunction, Decl(abstractPropertyInConstructor.ts, 10, 13)) + + return this.prop; +>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) +>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) + } } abstract prop: string; ->prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) + + abstract cb: (s: string) => void; +>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 15, 26)) +>s : Symbol(s, Decl(abstractPropertyInConstructor.ts, 16, 18)) abstract method(num: number): void; ->method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 7, 26)) ->num : Symbol(num, Decl(abstractPropertyInConstructor.ts, 9, 20)) +>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 16, 37)) +>num : Symbol(num, Decl(abstractPropertyInConstructor.ts, 18, 20)) method2() { ->method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 9, 39)) +>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 18, 39)) this.prop = this.prop + "!"; ->this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) +>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) >this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) ->prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) ->this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) +>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) >this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) ->prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 5, 5)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) } } diff --git a/tests/baselines/reference/abstractPropertyInConstructor.types b/tests/baselines/reference/abstractPropertyInConstructor.types index 05f7a7752e6..0ffb5f1bdfd 100644 --- a/tests/baselines/reference/abstractPropertyInConstructor.types +++ b/tests/baselines/reference/abstractPropertyInConstructor.types @@ -23,17 +23,42 @@ abstract class AbstractClass { >prop : string >toLowerCase : () => string - this.prop = "Hello World"; + if (!str) { +>!str : boolean +>str : string + + this.prop = "Hello World"; >this.prop = "Hello World" : "Hello World" >this.prop : string >this : this >prop : string >"Hello World" : "Hello World" + } + this.cb(str); +>this.cb(str) : void +>this.cb : (s: string) => void +>this : this +>cb : (s: string) => void +>str : string + + const innerFunction = () => { +>innerFunction : () => string +>() => { return this.prop; } : () => string + + return this.prop; +>this.prop : string +>this : this +>prop : string + } } abstract prop: string; >prop : string + abstract cb: (s: string) => void; +>cb : (s: string) => void +>s : string + abstract method(num: number): void; >method : (num: number) => void >num : number diff --git a/tests/cases/compiler/abstractPropertyInConstructor.ts b/tests/cases/compiler/abstractPropertyInConstructor.ts index 5376aae9d6f..457fdb473b1 100644 --- a/tests/cases/compiler/abstractPropertyInConstructor.ts +++ b/tests/cases/compiler/abstractPropertyInConstructor.ts @@ -2,10 +2,19 @@ abstract class AbstractClass { constructor(str: string) { this.method(parseInt(str)); let val = this.prop.toLowerCase(); - this.prop = "Hello World"; + + if (!str) { + this.prop = "Hello World"; + } + this.cb(str); + + const innerFunction = () => { + return this.prop; + } } abstract prop: string; + abstract cb: (s: string) => void; abstract method(num: number): void; From 2796ebfe35ca08518ed196b522181bc0deff2373 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 9 Oct 2017 11:04:28 -0700 Subject: [PATCH 039/312] In resolveNameHelper, use a lastNonBlockLocation (#18918) --- src/compiler/checker.ts | 6 ++- .../noUnusedLocals_selfReference.errors.txt | 16 ++++-- .../reference/noUnusedLocals_selfReference.js | 14 ++++- .../noUnusedLocals_selfReference.symbols | 53 +++++++++++-------- .../noUnusedLocals_selfReference.types | 13 ++++- .../compiler/noUnusedLocals_selfReference.ts | 7 ++- 6 files changed, 77 insertions(+), 32 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a8e18c432a6..58ac3bc52c0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -908,6 +908,7 @@ namespace ts { const originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location let result: Symbol; let lastLocation: Node; + let lastNonBlockLocation: Node; let propertyWithInvalidInitializer: Node; const errorLocation = location; let grandparent: Node; @@ -1126,6 +1127,9 @@ namespace ts { } break; } + if (location.kind !== SyntaxKind.Block) { + lastNonBlockLocation = location; + } lastLocation = location; location = location.parent; } @@ -1133,7 +1137,7 @@ namespace ts { // We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`. // If `result === lastLocation.symbol`, that means that we are somewhere inside `lastLocation` looking up a name, and resolving to `lastLocation` itself. // That means that this is a self-reference of `lastLocation`, and shouldn't count this when considering whether `lastLocation` is used. - if (isUse && result && nameNotFoundMessage && noUnusedIdentifiers && result !== lastLocation.symbol) { + if (isUse && result && nameNotFoundMessage && noUnusedIdentifiers && result !== lastNonBlockLocation.symbol) { result.isReferenced = true; } diff --git a/tests/baselines/reference/noUnusedLocals_selfReference.errors.txt b/tests/baselines/reference/noUnusedLocals_selfReference.errors.txt index e4a0d478cb4..603bc54d448 100644 --- a/tests/baselines/reference/noUnusedLocals_selfReference.errors.txt +++ b/tests/baselines/reference/noUnusedLocals_selfReference.errors.txt @@ -1,14 +1,22 @@ tests/cases/compiler/noUnusedLocals_selfReference.ts(3,10): error TS6133: 'f' is declared but its value is never read. -tests/cases/compiler/noUnusedLocals_selfReference.ts(4,7): error TS6133: 'C' is declared but its value is never read. -tests/cases/compiler/noUnusedLocals_selfReference.ts(7,6): error TS6133: 'E' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_selfReference.ts(5,14): error TS6133: 'g' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_selfReference.ts(9,7): error TS6133: 'C' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_selfReference.ts(12,6): error TS6133: 'E' is declared but its value is never read. -==== tests/cases/compiler/noUnusedLocals_selfReference.ts (3 errors) ==== +==== tests/cases/compiler/noUnusedLocals_selfReference.ts (4 errors) ==== export {}; // Make this a module scope, so these are local variables. - function f() { f; } + function f() { ~ !!! error TS6133: 'f' is declared but its value is never read. + f; + function g() { + ~ +!!! error TS6133: 'g' is declared but its value is never read. + g; + } + } class C { ~ !!! error TS6133: 'C' is declared but its value is never read. diff --git a/tests/baselines/reference/noUnusedLocals_selfReference.js b/tests/baselines/reference/noUnusedLocals_selfReference.js index 5f206fbc3dc..a8f3d6a8aed 100644 --- a/tests/baselines/reference/noUnusedLocals_selfReference.js +++ b/tests/baselines/reference/noUnusedLocals_selfReference.js @@ -1,7 +1,12 @@ //// [noUnusedLocals_selfReference.ts] export {}; // Make this a module scope, so these are local variables. -function f() { f; } +function f() { + f; + function g() { + g; + } +} class C { m() { C; } } @@ -19,7 +24,12 @@ P; //// [noUnusedLocals_selfReference.js] "use strict"; exports.__esModule = true; -function f() { f; } +function f() { + f; + function g() { + g; + } +} var C = /** @class */ (function () { function C() { } diff --git a/tests/baselines/reference/noUnusedLocals_selfReference.symbols b/tests/baselines/reference/noUnusedLocals_selfReference.symbols index dcd815b2619..015a78d87d3 100644 --- a/tests/baselines/reference/noUnusedLocals_selfReference.symbols +++ b/tests/baselines/reference/noUnusedLocals_selfReference.symbols @@ -1,43 +1,52 @@ === tests/cases/compiler/noUnusedLocals_selfReference.ts === export {}; // Make this a module scope, so these are local variables. -function f() { f; } ->f : Symbol(f, Decl(noUnusedLocals_selfReference.ts, 0, 10)) +function f() { >f : Symbol(f, Decl(noUnusedLocals_selfReference.ts, 0, 10)) + f; +>f : Symbol(f, Decl(noUnusedLocals_selfReference.ts, 0, 10)) + + function g() { +>g : Symbol(g, Decl(noUnusedLocals_selfReference.ts, 3, 6)) + + g; +>g : Symbol(g, Decl(noUnusedLocals_selfReference.ts, 3, 6)) + } +} class C { ->C : Symbol(C, Decl(noUnusedLocals_selfReference.ts, 2, 19)) +>C : Symbol(C, Decl(noUnusedLocals_selfReference.ts, 7, 1)) m() { C; } ->m : Symbol(C.m, Decl(noUnusedLocals_selfReference.ts, 3, 9)) ->C : Symbol(C, Decl(noUnusedLocals_selfReference.ts, 2, 19)) +>m : Symbol(C.m, Decl(noUnusedLocals_selfReference.ts, 8, 9)) +>C : Symbol(C, Decl(noUnusedLocals_selfReference.ts, 7, 1)) } enum E { A = 0, B = E.A } ->E : Symbol(E, Decl(noUnusedLocals_selfReference.ts, 5, 1)) ->A : Symbol(E.A, Decl(noUnusedLocals_selfReference.ts, 6, 8)) ->B : Symbol(E.B, Decl(noUnusedLocals_selfReference.ts, 6, 15)) ->E.A : Symbol(E.A, Decl(noUnusedLocals_selfReference.ts, 6, 8)) ->E : Symbol(E, Decl(noUnusedLocals_selfReference.ts, 5, 1)) ->A : Symbol(E.A, Decl(noUnusedLocals_selfReference.ts, 6, 8)) +>E : Symbol(E, Decl(noUnusedLocals_selfReference.ts, 10, 1)) +>A : Symbol(E.A, Decl(noUnusedLocals_selfReference.ts, 11, 8)) +>B : Symbol(E.B, Decl(noUnusedLocals_selfReference.ts, 11, 15)) +>E.A : Symbol(E.A, Decl(noUnusedLocals_selfReference.ts, 11, 8)) +>E : Symbol(E, Decl(noUnusedLocals_selfReference.ts, 10, 1)) +>A : Symbol(E.A, Decl(noUnusedLocals_selfReference.ts, 11, 8)) // Does not detect mutual recursion. function g() { D; } ->g : Symbol(g, Decl(noUnusedLocals_selfReference.ts, 6, 25)) ->D : Symbol(D, Decl(noUnusedLocals_selfReference.ts, 9, 19)) +>g : Symbol(g, Decl(noUnusedLocals_selfReference.ts, 11, 25)) +>D : Symbol(D, Decl(noUnusedLocals_selfReference.ts, 14, 19)) class D { m() { g; } } ->D : Symbol(D, Decl(noUnusedLocals_selfReference.ts, 9, 19)) ->m : Symbol(D.m, Decl(noUnusedLocals_selfReference.ts, 10, 9)) ->g : Symbol(g, Decl(noUnusedLocals_selfReference.ts, 6, 25)) +>D : Symbol(D, Decl(noUnusedLocals_selfReference.ts, 14, 19)) +>m : Symbol(D.m, Decl(noUnusedLocals_selfReference.ts, 15, 9)) +>g : Symbol(g, Decl(noUnusedLocals_selfReference.ts, 11, 25)) // Does not work on private methods. class P { private m() { this.m; } } ->P : Symbol(P, Decl(noUnusedLocals_selfReference.ts, 10, 22)) ->m : Symbol(P.m, Decl(noUnusedLocals_selfReference.ts, 13, 9)) ->this.m : Symbol(P.m, Decl(noUnusedLocals_selfReference.ts, 13, 9)) ->this : Symbol(P, Decl(noUnusedLocals_selfReference.ts, 10, 22)) ->m : Symbol(P.m, Decl(noUnusedLocals_selfReference.ts, 13, 9)) +>P : Symbol(P, Decl(noUnusedLocals_selfReference.ts, 15, 22)) +>m : Symbol(P.m, Decl(noUnusedLocals_selfReference.ts, 18, 9)) +>this.m : Symbol(P.m, Decl(noUnusedLocals_selfReference.ts, 18, 9)) +>this : Symbol(P, Decl(noUnusedLocals_selfReference.ts, 15, 22)) +>m : Symbol(P.m, Decl(noUnusedLocals_selfReference.ts, 18, 9)) P; ->P : Symbol(P, Decl(noUnusedLocals_selfReference.ts, 10, 22)) +>P : Symbol(P, Decl(noUnusedLocals_selfReference.ts, 15, 22)) diff --git a/tests/baselines/reference/noUnusedLocals_selfReference.types b/tests/baselines/reference/noUnusedLocals_selfReference.types index 7d2741c5681..7e75062db34 100644 --- a/tests/baselines/reference/noUnusedLocals_selfReference.types +++ b/tests/baselines/reference/noUnusedLocals_selfReference.types @@ -1,10 +1,19 @@ === tests/cases/compiler/noUnusedLocals_selfReference.ts === export {}; // Make this a module scope, so these are local variables. -function f() { f; } ->f : () => void +function f() { >f : () => void + f; +>f : () => void + + function g() { +>g : () => void + + g; +>g : () => void + } +} class C { >C : C diff --git a/tests/cases/compiler/noUnusedLocals_selfReference.ts b/tests/cases/compiler/noUnusedLocals_selfReference.ts index 8eb528743c0..fc6b02b6006 100644 --- a/tests/cases/compiler/noUnusedLocals_selfReference.ts +++ b/tests/cases/compiler/noUnusedLocals_selfReference.ts @@ -2,7 +2,12 @@ export {}; // Make this a module scope, so these are local variables. -function f() { f; } +function f() { + f; + function g() { + g; + } +} class C { m() { C; } } From 517dbf3ca77863daa5376dfb4a95088d1f0dffab Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 9 Oct 2017 11:14:24 -0700 Subject: [PATCH 040/312] Fix semicolon lint --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d7585bd6e9a..a61ded007f4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13923,7 +13923,7 @@ namespace ts { t.flags |= propagatedFlags; t.flags |= TypeFlags.FreshLiteral; (t as ObjectType).objectFlags |= ObjectFlags.ObjectLiteral; - t.symbol = node.symbol + t.symbol = node.symbol; } }); return spread; From 8486c482371e800fcaa83c655f837f70d8ac02af Mon Sep 17 00:00:00 2001 From: Charles Pierce Date: Mon, 9 Oct 2017 13:01:30 -0700 Subject: [PATCH 041/312] Fix linting error in new function --- src/compiler/checker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8afee9455cf..26e851eb53d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23156,7 +23156,8 @@ namespace ts { return findAncestor(node, element => { if (isConstructorDeclaration(element) && nodeIsPresent(element.body)) { return true; - } else if (element === classDeclaration || isFunctionLikeDeclaration(element)) { + } + else if (element === classDeclaration || isFunctionLikeDeclaration(element)) { return "quit"; } From 264652c0ef7197116280af77c284b124071eb661 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 9 Oct 2017 13:12:27 -0700 Subject: [PATCH 042/312] Fix emit for classes with both fields and 'extends null' --- src/compiler/transformers/ts.ts | 28 +++++++++---------- .../baselines/reference/classExtendingNull.js | 17 ++++++++++- .../reference/classExtendingNull.symbols | 8 ++++++ .../reference/classExtendingNull.types | 13 +++++++++ .../classDeclarations/classExtendingNull.ts | 2 ++ 5 files changed, 53 insertions(+), 15 deletions(-) diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 4feb3ca0c26..e67918fd696 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -26,7 +26,7 @@ namespace ts { IsExportOfNamespace = 1 << 3, IsNamedExternalExport = 1 << 4, IsDefaultExternalExport = 1 << 5, - HasExtendsClause = 1 << 6, + IsDerivedClass = 1 << 6, UseImmediatelyInvokedFunctionExpression = 1 << 7, HasAnyDecorators = HasConstructorDecorators | HasMemberDecorators, @@ -553,7 +553,8 @@ namespace ts { function getClassFacts(node: ClassDeclaration, staticProperties: ReadonlyArray) { let facts = ClassFacts.None; if (some(staticProperties)) facts |= ClassFacts.HasStaticInitializedProperties; - if (getClassExtendsHeritageClauseElement(node)) facts |= ClassFacts.HasExtendsClause; + const extendsClauseElement = getClassExtendsHeritageClauseElement(node); + if (extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== SyntaxKind.NullKeyword) facts |= ClassFacts.IsDerivedClass; if (shouldEmitDecorateCallForClass(node)) facts |= ClassFacts.HasConstructorDecorators; if (childIsDecorated(node)) facts |= ClassFacts.HasMemberDecorators; if (isExportOfNamespace(node)) facts |= ClassFacts.IsExportOfNamespace; @@ -699,7 +700,7 @@ namespace ts { name, /*typeParameters*/ undefined, visitNodes(node.heritageClauses, visitor, isHeritageClause), - transformClassMembers(node, (facts & ClassFacts.HasExtendsClause) !== 0) + transformClassMembers(node, (facts & ClassFacts.IsDerivedClass) !== 0) ); // To better align with the old emitter, we should not emit a trailing source map @@ -814,7 +815,7 @@ namespace ts { // ${members} // } const heritageClauses = visitNodes(node.heritageClauses, visitor, isHeritageClause); - const members = transformClassMembers(node, (facts & ClassFacts.HasExtendsClause) !== 0); + const members = transformClassMembers(node, (facts & ClassFacts.IsDerivedClass) !== 0); const classExpression = createClassExpression(/*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members); setOriginalNode(classExpression, node); setTextRange(classExpression, location); @@ -887,11 +888,11 @@ namespace ts { * Transforms the members of a class. * * @param node The current class. - * @param hasExtendsClause A value indicating whether the class has an extends clause. + * @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'. */ - function transformClassMembers(node: ClassDeclaration | ClassExpression, hasExtendsClause: boolean) { + function transformClassMembers(node: ClassDeclaration | ClassExpression, isDerivedClass: boolean) { const members: ClassElement[] = []; - const constructor = transformConstructor(node, hasExtendsClause); + const constructor = transformConstructor(node, isDerivedClass); if (constructor) { members.push(constructor); } @@ -904,9 +905,9 @@ namespace ts { * Transforms (or creates) a constructor for a class. * * @param node The current class. - * @param hasExtendsClause A value indicating whether the class has an extends clause. + * @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'. */ - function transformConstructor(node: ClassDeclaration | ClassExpression, hasExtendsClause: boolean) { + function transformConstructor(node: ClassDeclaration | ClassExpression, isDerivedClass: boolean) { // Check if we have property assignment inside class declaration. // If there is a property assignment, we need to emit constructor whether users define it or not // If there is no property assignment, we can omit constructor if users do not define it @@ -921,7 +922,7 @@ namespace ts { } const parameters = transformConstructorParameters(constructor); - const body = transformConstructorBody(node, constructor, hasExtendsClause); + const body = transformConstructorBody(node, constructor, isDerivedClass); // constructor(${parameters}) { // ${body} @@ -947,7 +948,6 @@ namespace ts { * parameter property assignments or instance property initializers. * * @param constructor The constructor declaration. - * @param hasExtendsClause A value indicating whether the class has an extends clause. */ function transformConstructorParameters(constructor: ConstructorDeclaration) { // The ES2015 spec specifies in 14.5.14. Runtime Semantics: ClassDefinitionEvaluation: @@ -975,9 +975,9 @@ namespace ts { * * @param node The current class. * @param constructor The current class constructor. - * @param hasExtendsClause A value indicating whether the class has an extends clause. + * @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'. */ - function transformConstructorBody(node: ClassExpression | ClassDeclaration, constructor: ConstructorDeclaration, hasExtendsClause: boolean) { + function transformConstructorBody(node: ClassExpression | ClassDeclaration, constructor: ConstructorDeclaration, isDerivedClass: boolean) { let statements: Statement[] = []; let indexOfFirstStatement = 0; @@ -1001,7 +1001,7 @@ namespace ts { const propertyAssignments = getParametersWithPropertyAssignments(constructor); addRange(statements, map(propertyAssignments, transformParameterWithPropertyAssignment)); } - else if (hasExtendsClause) { + else if (isDerivedClass) { // Add a synthetic `super` call: // // super(...arguments); diff --git a/tests/baselines/reference/classExtendingNull.js b/tests/baselines/reference/classExtendingNull.js index 6c6ae8a0167..f405f6da84c 100644 --- a/tests/baselines/reference/classExtendingNull.js +++ b/tests/baselines/reference/classExtendingNull.js @@ -1,7 +1,8 @@ //// [classExtendingNull.ts] class C1 extends null { } class C2 extends (null) { } - +class C3 extends null { x = 1; } +class C4 extends (null) { x = 1; } //// [classExtendingNull.js] var __extends = (this && this.__extends) || (function () { @@ -26,3 +27,17 @@ var C2 = /** @class */ (function (_super) { } return C2; }((null))); +var C3 = /** @class */ (function (_super) { + __extends(C3, _super); + function C3() { + this.x = 1; + } + return C3; +}(null)); +var C4 = /** @class */ (function (_super) { + __extends(C4, _super); + function C4() { + this.x = 1; + } + return C4; +}((null))); diff --git a/tests/baselines/reference/classExtendingNull.symbols b/tests/baselines/reference/classExtendingNull.symbols index 37a6162f414..eff1f18c0ca 100644 --- a/tests/baselines/reference/classExtendingNull.symbols +++ b/tests/baselines/reference/classExtendingNull.symbols @@ -5,3 +5,11 @@ class C1 extends null { } class C2 extends (null) { } >C2 : Symbol(C2, Decl(classExtendingNull.ts, 0, 25)) +class C3 extends null { x = 1; } +>C3 : Symbol(C3, Decl(classExtendingNull.ts, 1, 27)) +>x : Symbol(C3.x, Decl(classExtendingNull.ts, 2, 23)) + +class C4 extends (null) { x = 1; } +>C4 : Symbol(C4, Decl(classExtendingNull.ts, 2, 32)) +>x : Symbol(C4.x, Decl(classExtendingNull.ts, 3, 25)) + diff --git a/tests/baselines/reference/classExtendingNull.types b/tests/baselines/reference/classExtendingNull.types index 3c572a3406c..e98f8daba06 100644 --- a/tests/baselines/reference/classExtendingNull.types +++ b/tests/baselines/reference/classExtendingNull.types @@ -8,3 +8,16 @@ class C2 extends (null) { } >(null) : null >null : null +class C3 extends null { x = 1; } +>C3 : C3 +>null : null +>x : number +>1 : 1 + +class C4 extends (null) { x = 1; } +>C4 : C4 +>(null) : null +>null : null +>x : number +>1 : 1 + diff --git a/tests/cases/conformance/classes/classDeclarations/classExtendingNull.ts b/tests/cases/conformance/classes/classDeclarations/classExtendingNull.ts index 655cf44ed57..b00c047a379 100644 --- a/tests/cases/conformance/classes/classDeclarations/classExtendingNull.ts +++ b/tests/cases/conformance/classes/classDeclarations/classExtendingNull.ts @@ -1,2 +1,4 @@ class C1 extends null { } class C2 extends (null) { } +class C3 extends null { x = 1; } +class C4 extends (null) { x = 1; } \ No newline at end of file From 8b60736b61b8559fc7bd542a5e8954e258f51bd3 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 9 Oct 2017 13:39:15 -0700 Subject: [PATCH 043/312] importFixes: Remove unnecessary undefined check (#19045) --- src/services/codefixes/importFixes.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index f516bc15de3..9b54543231d 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -16,7 +16,7 @@ namespace ts.codefix { moduleSpecifier?: string; } - enum ModuleSpecifierComparison { + const enum ModuleSpecifierComparison { Better, Equal, Worse @@ -26,10 +26,6 @@ namespace ts.codefix { private symbolIdToActionMap: ImportCodeAction[][] = []; addAction(symbolId: number, newAction: ImportCodeAction) { - if (!newAction) { - return; - } - const actions = this.symbolIdToActionMap[symbolId]; if (!actions) { this.symbolIdToActionMap[symbolId] = [newAction]; From 07ba90659404830f735f819b645476954c3c5d9a Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 9 Oct 2017 14:25:48 -0700 Subject: [PATCH 044/312] Handle the case when finishCachingPerDirectoryResolution is not called because of exception Fixes #18975 --- src/compiler/resolutionCache.ts | 10 ++++++++-- src/compiler/watch.ts | 10 +++++----- src/server/project.ts | 7 +++---- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index aecc6989891..680ed98a84a 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -141,7 +141,10 @@ namespace ts { resolvedModuleNames.clear(); resolvedTypeReferenceDirectives.clear(); allFilesHaveInvalidatedResolution = false; - Debug.assert(perDirectoryResolvedModuleNames.size === 0 && perDirectoryResolvedTypeReferenceDirectives.size === 0); + // perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update + // (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution) + perDirectoryResolvedModuleNames.clear(); + perDirectoryResolvedTypeReferenceDirectives.clear(); } function startRecordingFilesWithChangedResolutions() { @@ -166,7 +169,10 @@ namespace ts { } function startCachingPerDirectoryResolution() { - Debug.assert(perDirectoryResolvedModuleNames.size === 0 && perDirectoryResolvedTypeReferenceDirectives.size === 0); + // perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update + // (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution) + perDirectoryResolvedModuleNames.clear(); + perDirectoryResolvedTypeReferenceDirectives.clear(); } function finishCachingPerDirectoryResolution() { diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 2ab3ccc5ce6..1ab80e659f4 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -322,6 +322,9 @@ namespace ts { if (hasChangedCompilerOptions) { newLine = getNewLineCharacter(compilerOptions, system); + if (changesAffectModuleResolution(program && program.getCompilerOptions(), compilerOptions)) { + resolutionCache.clear(); + } } const hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(); @@ -329,14 +332,11 @@ namespace ts { return; } - if (hasChangedCompilerOptions && changesAffectModuleResolution(program && program.getCompilerOptions(), compilerOptions)) { - resolutionCache.clear(); - } - const needsUpdateInTypeRootWatch = hasChangedCompilerOptions || !program; - hasChangedCompilerOptions = false; beforeCompile(compilerOptions); // Compile the program + const needsUpdateInTypeRootWatch = hasChangedCompilerOptions || !program; + hasChangedCompilerOptions = false; resolutionCache.startCachingPerDirectoryResolution(); compilerHost.hasInvalidatedResolution = hasInvalidatedResolution; compilerHost.hasChangedAutomaticTypeDirectiveNames = hasChangedAutomaticTypeDirectiveNames; diff --git a/src/server/project.ts b/src/server/project.ts index ac18738027b..5132b82a804 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -229,8 +229,8 @@ namespace ts.server { this.realpath = path => host.realpath(path); } - this.languageService = createLanguageService(this, this.documentRegistry); this.resolutionCache = createResolutionCache(this, rootDirectoryForResolution); + this.languageService = createLanguageService(this, this.documentRegistry); if (!languageServiceEnabled) { this.disableLanguageService(); } @@ -732,7 +732,6 @@ namespace ts.server { */ updateGraph(): boolean { this.resolutionCache.startRecordingFilesWithChangedResolutions(); - this.hasInvalidatedResolution = this.resolutionCache.createHasInvalidatedResolution(); let hasChanges = this.updateGraphWorker(); @@ -795,6 +794,7 @@ namespace ts.server { this.writeLog(`Starting updateGraphWorker: Project: ${this.getProjectName()}`); const start = timestamp(); + this.hasInvalidatedResolution = this.resolutionCache.createHasInvalidatedResolution(); this.resolutionCache.startCachingPerDirectoryResolution(); this.program = this.languageService.getProgram(); this.resolutionCache.finishCachingPerDirectoryResolution(); @@ -1327,14 +1327,13 @@ namespace ts.server { } close() { - super.close(); - if (this.configFileWatcher) { this.configFileWatcher.close(); this.configFileWatcher = undefined; } this.stopWatchingWildCards(); + super.close(); } addOpenRef() { From 5f3d6e753e0c89419bd3734ccf991c26ba772131 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Mon, 9 Oct 2017 14:43:51 -0700 Subject: [PATCH 045/312] update baselines --- tests/baselines/reference/api/tsserverlibrary.d.ts | 2 ++ tests/baselines/reference/api/typescript.d.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index ca8696b11fb..5f4ef1dbdfe 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2870,6 +2870,8 @@ declare namespace ts { function getJSDocReturnType(node: Node): TypeNode | undefined; /** Get all JSDoc tags related to a node, including those on parent nodes. */ function getJSDocTags(node: Node): ReadonlyArray | undefined; + /** Gets all JSDoc tags of a specified kind, or undefined if not present. */ + function getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): ReadonlyArray | undefined; } declare namespace ts { function isNumericLiteral(node: Node): node is NumericLiteral; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 820be44f1f1..e608c7ffc3d 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2925,6 +2925,8 @@ declare namespace ts { function getJSDocReturnType(node: Node): TypeNode | undefined; /** Get all JSDoc tags related to a node, including those on parent nodes. */ function getJSDocTags(node: Node): ReadonlyArray | undefined; + /** Gets all JSDoc tags of a specified kind, or undefined if not present. */ + function getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): ReadonlyArray | undefined; } declare namespace ts { function isNumericLiteral(node: Node): node is NumericLiteral; From bb3467b8e1c2b7897bc30e282e59bd85a8b8c714 Mon Sep 17 00:00:00 2001 From: Joe Calzaretta Date: Mon, 9 Oct 2017 17:58:41 -0400 Subject: [PATCH 046/312] Handle type guard predicates on `Array.find` (#18160) * Handle type guard predicates on `Array.find` If the `predicate` function passed to `Array.find` or `ReadonlyArray.find` is a type guard narrowing `value` to type `S`, then any returned element should also be narrowed to `S`. Adding test case and associated baselines * trailing whitespace after merge conflict --- src/lib/es2015.core.d.ts | 2 + tests/baselines/reference/arrayFind.js | 22 ++++++++++ tests/baselines/reference/arrayFind.symbols | 33 +++++++++++++++ tests/baselines/reference/arrayFind.types | 46 +++++++++++++++++++++ tests/cases/compiler/arrayFind.ts | 12 ++++++ 5 files changed, 115 insertions(+) create mode 100644 tests/baselines/reference/arrayFind.js create mode 100644 tests/baselines/reference/arrayFind.symbols create mode 100644 tests/baselines/reference/arrayFind.types create mode 100644 tests/cases/compiler/arrayFind.ts diff --git a/src/lib/es2015.core.d.ts b/src/lib/es2015.core.d.ts index 5c2438d9052..9ea773e3eef 100644 --- a/src/lib/es2015.core.d.ts +++ b/src/lib/es2015.core.d.ts @@ -10,6 +10,7 @@ interface Array { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ + find(predicate: (this: void, value: T, index: number, obj: T[]) => value is S, thisArg?: any): S | undefined; find(predicate: (value: T, index: number, obj: T[]) => boolean, thisArg?: any): T | undefined; /** @@ -350,6 +351,7 @@ interface ReadonlyArray { * @param thisArg If provided, it will be used as the this value for each invocation of * predicate. If it is not provided, undefined is used instead. */ + find(predicate: (this: void, value: T, index: number, obj: ReadonlyArray) => value is S, thisArg?: any): S | undefined; find(predicate: (value: T, index: number, obj: ReadonlyArray) => boolean, thisArg?: any): T | undefined; /** diff --git a/tests/baselines/reference/arrayFind.js b/tests/baselines/reference/arrayFind.js new file mode 100644 index 00000000000..1926c3a8dcc --- /dev/null +++ b/tests/baselines/reference/arrayFind.js @@ -0,0 +1,22 @@ +//// [arrayFind.ts] +// test fix for #18112, type guard predicates should narrow returned element +function isNumber(x: any): x is number { + return typeof x === "number"; +} + +const arrayOfStringsNumbersAndBooleans = ["string", false, 0, "strung", 1, true]; +const foundNumber: number | undefined = arrayOfStringsNumbersAndBooleans.find(isNumber); + +const readonlyArrayOfStringsNumbersAndBooleans = arrayOfStringsNumbersAndBooleans as ReadonlyArray; +const readonlyFoundNumber: number | undefined = readonlyArrayOfStringsNumbersAndBooleans.find(isNumber); + + +//// [arrayFind.js] +// test fix for #18112, type guard predicates should narrow returned element +function isNumber(x) { + return typeof x === "number"; +} +var arrayOfStringsNumbersAndBooleans = ["string", false, 0, "strung", 1, true]; +var foundNumber = arrayOfStringsNumbersAndBooleans.find(isNumber); +var readonlyArrayOfStringsNumbersAndBooleans = arrayOfStringsNumbersAndBooleans; +var readonlyFoundNumber = readonlyArrayOfStringsNumbersAndBooleans.find(isNumber); diff --git a/tests/baselines/reference/arrayFind.symbols b/tests/baselines/reference/arrayFind.symbols new file mode 100644 index 00000000000..163d5d818ba --- /dev/null +++ b/tests/baselines/reference/arrayFind.symbols @@ -0,0 +1,33 @@ +=== tests/cases/compiler/arrayFind.ts === +// test fix for #18112, type guard predicates should narrow returned element +function isNumber(x: any): x is number { +>isNumber : Symbol(isNumber, Decl(arrayFind.ts, 0, 0)) +>x : Symbol(x, Decl(arrayFind.ts, 1, 18)) +>x : Symbol(x, Decl(arrayFind.ts, 1, 18)) + + return typeof x === "number"; +>x : Symbol(x, Decl(arrayFind.ts, 1, 18)) +} + +const arrayOfStringsNumbersAndBooleans = ["string", false, 0, "strung", 1, true]; +>arrayOfStringsNumbersAndBooleans : Symbol(arrayOfStringsNumbersAndBooleans, Decl(arrayFind.ts, 5, 5)) + +const foundNumber: number | undefined = arrayOfStringsNumbersAndBooleans.find(isNumber); +>foundNumber : Symbol(foundNumber, Decl(arrayFind.ts, 6, 5)) +>arrayOfStringsNumbersAndBooleans.find : Symbol(Array.find, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>arrayOfStringsNumbersAndBooleans : Symbol(arrayOfStringsNumbersAndBooleans, Decl(arrayFind.ts, 5, 5)) +>find : Symbol(Array.find, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>isNumber : Symbol(isNumber, Decl(arrayFind.ts, 0, 0)) + +const readonlyArrayOfStringsNumbersAndBooleans = arrayOfStringsNumbersAndBooleans as ReadonlyArray; +>readonlyArrayOfStringsNumbersAndBooleans : Symbol(readonlyArrayOfStringsNumbersAndBooleans, Decl(arrayFind.ts, 8, 5)) +>arrayOfStringsNumbersAndBooleans : Symbol(arrayOfStringsNumbersAndBooleans, Decl(arrayFind.ts, 5, 5)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) + +const readonlyFoundNumber: number | undefined = readonlyArrayOfStringsNumbersAndBooleans.find(isNumber); +>readonlyFoundNumber : Symbol(readonlyFoundNumber, Decl(arrayFind.ts, 9, 5)) +>readonlyArrayOfStringsNumbersAndBooleans.find : Symbol(ReadonlyArray.find, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>readonlyArrayOfStringsNumbersAndBooleans : Symbol(readonlyArrayOfStringsNumbersAndBooleans, Decl(arrayFind.ts, 8, 5)) +>find : Symbol(ReadonlyArray.find, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>isNumber : Symbol(isNumber, Decl(arrayFind.ts, 0, 0)) + diff --git a/tests/baselines/reference/arrayFind.types b/tests/baselines/reference/arrayFind.types new file mode 100644 index 00000000000..5c0769cb606 --- /dev/null +++ b/tests/baselines/reference/arrayFind.types @@ -0,0 +1,46 @@ +=== tests/cases/compiler/arrayFind.ts === +// test fix for #18112, type guard predicates should narrow returned element +function isNumber(x: any): x is number { +>isNumber : (x: any) => x is number +>x : any +>x : any + + return typeof x === "number"; +>typeof x === "number" : boolean +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : any +>"number" : "number" +} + +const arrayOfStringsNumbersAndBooleans = ["string", false, 0, "strung", 1, true]; +>arrayOfStringsNumbersAndBooleans : (string | number | boolean)[] +>["string", false, 0, "strung", 1, true] : (string | number | boolean)[] +>"string" : "string" +>false : false +>0 : 0 +>"strung" : "strung" +>1 : 1 +>true : true + +const foundNumber: number | undefined = arrayOfStringsNumbersAndBooleans.find(isNumber); +>foundNumber : number +>arrayOfStringsNumbersAndBooleans.find(isNumber) : number +>arrayOfStringsNumbersAndBooleans.find : { (predicate: (this: void, value: string | number | boolean, index: number, obj: (string | number | boolean)[]) => value is S, thisArg?: any): S; (predicate: (value: string | number | boolean, index: number, obj: (string | number | boolean)[]) => boolean, thisArg?: any): string | number | boolean; } +>arrayOfStringsNumbersAndBooleans : (string | number | boolean)[] +>find : { (predicate: (this: void, value: string | number | boolean, index: number, obj: (string | number | boolean)[]) => value is S, thisArg?: any): S; (predicate: (value: string | number | boolean, index: number, obj: (string | number | boolean)[]) => boolean, thisArg?: any): string | number | boolean; } +>isNumber : (x: any) => x is number + +const readonlyArrayOfStringsNumbersAndBooleans = arrayOfStringsNumbersAndBooleans as ReadonlyArray; +>readonlyArrayOfStringsNumbersAndBooleans : ReadonlyArray +>arrayOfStringsNumbersAndBooleans as ReadonlyArray : ReadonlyArray +>arrayOfStringsNumbersAndBooleans : (string | number | boolean)[] +>ReadonlyArray : ReadonlyArray + +const readonlyFoundNumber: number | undefined = readonlyArrayOfStringsNumbersAndBooleans.find(isNumber); +>readonlyFoundNumber : number +>readonlyArrayOfStringsNumbersAndBooleans.find(isNumber) : number +>readonlyArrayOfStringsNumbersAndBooleans.find : { (predicate: (this: void, value: string | number | boolean, index: number, obj: ReadonlyArray) => value is S, thisArg?: any): S; (predicate: (value: string | number | boolean, index: number, obj: ReadonlyArray) => boolean, thisArg?: any): string | number | boolean; } +>readonlyArrayOfStringsNumbersAndBooleans : ReadonlyArray +>find : { (predicate: (this: void, value: string | number | boolean, index: number, obj: ReadonlyArray) => value is S, thisArg?: any): S; (predicate: (value: string | number | boolean, index: number, obj: ReadonlyArray) => boolean, thisArg?: any): string | number | boolean; } +>isNumber : (x: any) => x is number + diff --git a/tests/cases/compiler/arrayFind.ts b/tests/cases/compiler/arrayFind.ts new file mode 100644 index 00000000000..90883974766 --- /dev/null +++ b/tests/cases/compiler/arrayFind.ts @@ -0,0 +1,12 @@ +// @lib: es2015 + +// test fix for #18112, type guard predicates should narrow returned element +function isNumber(x: any): x is number { + return typeof x === "number"; +} + +const arrayOfStringsNumbersAndBooleans = ["string", false, 0, "strung", 1, true]; +const foundNumber: number | undefined = arrayOfStringsNumbersAndBooleans.find(isNumber); + +const readonlyArrayOfStringsNumbersAndBooleans = arrayOfStringsNumbersAndBooleans as ReadonlyArray; +const readonlyFoundNumber: number | undefined = readonlyArrayOfStringsNumbersAndBooleans.find(isNumber); From 661ecc241ebd2ac6f29f6cd7d37273e4b963be09 Mon Sep 17 00:00:00 2001 From: falsandtru Date: Tue, 10 Oct 2017 07:08:22 +0900 Subject: [PATCH 047/312] Improve Object.{values,entries} static methods (#18875) --- src/lib/es2017.object.d.ts | 4 ++-- .../useObjectValuesAndEntries1.types | 20 +++++++++---------- .../useObjectValuesAndEntries4.types | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/lib/es2017.object.d.ts b/src/lib/es2017.object.d.ts index 1d8a52da758..4014e8c2927 100644 --- a/src/lib/es2017.object.d.ts +++ b/src/lib/es2017.object.d.ts @@ -3,7 +3,7 @@ interface ObjectConstructor { * Returns an array of values of the enumerable properties of an object * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. */ - values(o: { [s: string]: T }): T[]; + values(o: { [s: string]: T } | { [n: number]: T }): T[]; /** * Returns an array of values of the enumerable properties of an object @@ -15,7 +15,7 @@ interface ObjectConstructor { * Returns an array of key/values of the enumerable properties of an object * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. */ - entries(o: { [s: string]: T }): [string, T][]; + entries(o: { [s: string]: T } | { [n: number]: T }): [string, T][]; /** * Returns an array of key/values of the enumerable properties of an object diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.types b/tests/baselines/reference/useObjectValuesAndEntries1.types index 1b537ed063d..6ea45385bbc 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.types +++ b/tests/baselines/reference/useObjectValuesAndEntries1.types @@ -10,9 +10,9 @@ var o = { a: 1, b: 2 }; for (var x of Object.values(o)) { >x : number >Object.values(o) : number[] ->Object.values : { (o: { [s: string]: T; }): T[]; (o: any): any[]; } +>Object.values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: any): any[]; } >Object : ObjectConstructor ->values : { (o: { [s: string]: T; }): T[]; (o: any): any[]; } +>values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: any): any[]; } >o : { a: number; b: number; } let y = x; @@ -23,25 +23,25 @@ for (var x of Object.values(o)) { var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] >entries : [string, number][] >Object.entries(o) : [string, number][] ->Object.entries : { (o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; } +>entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } >o : { a: number; b: number; } var entries1 = Object.entries(1); // <-- entries: [string, any][] >entries1 : [string, any][] >Object.entries(1) : [string, any][] ->Object.entries : { (o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; } +>entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } >1 : 1 var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][] >entries2 : [string, number | boolean][] >Object.entries({a: true, b: 2}) : [string, number | boolean][] ->Object.entries : { (o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; } +>entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } >{a: true, b: 2} : { a: true; b: 2; } >a : boolean >true : true @@ -51,8 +51,8 @@ var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][ var entries3 = Object.entries({}) // [never, any][] >entries3 : [string, {}][] >Object.entries({}) : [string, {}][] ->Object.entries : { (o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; } +>entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } >{} : {} diff --git a/tests/baselines/reference/useObjectValuesAndEntries4.types b/tests/baselines/reference/useObjectValuesAndEntries4.types index 85810bccd26..245803a24d4 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries4.types +++ b/tests/baselines/reference/useObjectValuesAndEntries4.types @@ -10,9 +10,9 @@ var o = { a: 1, b: 2 }; for (var x of Object.values(o)) { >x : number >Object.values(o) : number[] ->Object.values : { (o: { [s: string]: T; }): T[]; (o: any): any[]; } +>Object.values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: any): any[]; } >Object : ObjectConstructor ->values : { (o: { [s: string]: T; }): T[]; (o: any): any[]; } +>values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: any): any[]; } >o : { a: number; b: number; } let y = x; @@ -23,8 +23,8 @@ for (var x of Object.values(o)) { var entries = Object.entries(o); >entries : [string, number][] >Object.entries(o) : [string, number][] ->Object.entries : { (o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; } +>entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: any): [string, any][]; } >o : { a: number; b: number; } From 6887dbc75028f225d25ed91815de1719e5a1e101 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 9 Oct 2017 15:24:00 -0700 Subject: [PATCH 048/312] Assert if the script info that is attached to closed project is present Adds assertion to investigate #19003 and #18928 --- src/server/editorServices.ts | 3 +++ src/server/project.ts | 21 ++++++++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 2916fb60c57..40c196009e3 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -832,6 +832,9 @@ namespace ts.server { this.logger.info(`remove project: ${project.getRootFiles().toString()}`); project.close(); + if (Debug.shouldAssert(AssertionLevel.Normal)) { + this.filenameToScriptInfo.forEach(info => Debug.assert(!info.isAttached(project))); + } // Remove the project from pending project updates this.pendingProjectUpdates.delete(project.getProjectName()); diff --git a/src/server/project.ts b/src/server/project.ts index 5132b82a804..e8bfd7c1b75 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -497,12 +497,7 @@ namespace ts.server { if (this.program) { // if we have a program - release all files that are enlisted in program for (const f of this.program.getSourceFiles()) { - const info = this.projectService.getScriptInfo(f.fileName); - // We might not find the script info in case its not associated with the project any more - // and project graph was not updated (eg delayed update graph in case of files changed/deleted on the disk) - if (info) { - info.detachFromProject(this); - } + this.detachScriptInfo(f.fileName); } } if (!this.program || !this.languageServiceEnabled) { @@ -512,10 +507,13 @@ namespace ts.server { root.detachFromProject(this); } } + this.rootFiles = undefined; this.rootFilesMap = undefined; this.program = undefined; this.builder = undefined; + forEach(this.externalFiles, externalFile => this.detachScriptInfo(externalFile)); + this.externalFiles = undefined; this.resolutionCache.clear(); this.resolutionCache = undefined; this.cachedUnresolvedImportsPerFile = undefined; @@ -532,6 +530,15 @@ namespace ts.server { this.languageService = undefined; } + private detachScriptInfo(uncheckedFilename: string) { + const info = this.projectService.getScriptInfo(uncheckedFilename); + // We might not find the script info in case its not associated with the project any more + // and project graph was not updated (eg delayed update graph in case of files changed/deleted on the disk) + if (info) { + info.detachFromProject(this); + } + } + isClosed() { return this.rootFiles === undefined; } @@ -791,7 +798,7 @@ namespace ts.server { private updateGraphWorker() { const oldProgram = this.program; - + Debug.assert(!this.isClosed(), "Called update graph worker of closed project"); this.writeLog(`Starting updateGraphWorker: Project: ${this.getProjectName()}`); const start = timestamp(); this.hasInvalidatedResolution = this.resolutionCache.createHasInvalidatedResolution(); From aaa06122b9d7b064d702591be063cea2c7c78e91 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 9 Oct 2017 15:40:52 -0700 Subject: [PATCH 049/312] Fix recursive reference in type parameter default --- src/compiler/checker.ts | 60 ++++++++++++++----- src/compiler/diagnosticMessages.json | 4 ++ tests/baselines/reference/genericDefaults.js | 7 ++- .../reference/genericDefaults.symbols | 6 ++ .../baselines/reference/genericDefaults.types | 6 ++ .../genericDefaultsErrors.errors.txt | 10 +++- .../reference/genericDefaultsErrors.js | 5 +- .../reference/genericDefaultsErrors.symbols | 6 ++ .../reference/genericDefaultsErrors.types | 6 ++ tests/cases/compiler/genericDefaults.ts | 5 +- tests/cases/compiler/genericDefaultsErrors.ts | 5 +- 11 files changed, 98 insertions(+), 22 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d47a77a7440..4c6973f3048 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -281,6 +281,7 @@ namespace ts { const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); const circularConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + const resolvingDefaultType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); const markerSuperType = createType(TypeFlags.TypeParameter); const markerSubType = createType(TypeFlags.TypeParameter); @@ -6055,27 +6056,51 @@ namespace ts { return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type)); } + function getResolvedTypeParameterDefault(typeParameter: TypeParameter): Type | undefined { + if (!typeParameter.default) { + if (typeParameter.target) { + const targetDefault = getResolvedTypeParameterDefault(typeParameter.target); + typeParameter.default = targetDefault ? instantiateType(targetDefault, typeParameter.mapper) : noConstraintType; + } + else { + // To block recursion, set the initial value to the resolvingDefaultType. + typeParameter.default = resolvingDefaultType; + const defaultDeclaration = typeParameter.symbol && forEach(typeParameter.symbol.declarations, decl => isTypeParameterDeclaration(decl) && decl.default); + const defaultType = defaultDeclaration ? getTypeFromTypeNode(defaultDeclaration) : noConstraintType; + if (typeParameter.default === resolvingDefaultType) { + // If we have not been called recursively, set the correct default type. + typeParameter.default = defaultType; + } + } + } + else if (typeParameter.default === resolvingDefaultType) { + // If we are called recursively for this type parameter, mark the default as circular. + typeParameter.default = circularConstraintType; + } + return typeParameter.default; + } + /** * Gets the default type for a type parameter. * * If the type parameter is the result of an instantiation, this gets the instantiated - * default type of its target. If the type parameter has no default type, `undefined` - * is returned. - * - * This function *does not* perform a circularity check. + * default type of its target. If the type parameter has no default type or the default is + * circular, `undefined` is returned. */ function getDefaultFromTypeParameter(typeParameter: TypeParameter): Type | undefined { - if (!typeParameter.default) { - if (typeParameter.target) { - const targetDefault = getDefaultFromTypeParameter(typeParameter.target); - typeParameter.default = targetDefault ? instantiateType(targetDefault, typeParameter.mapper) : noConstraintType; - } - else { - const defaultDeclaration = typeParameter.symbol && forEach(typeParameter.symbol.declarations, decl => isTypeParameterDeclaration(decl) && decl.default); - typeParameter.default = defaultDeclaration ? getTypeFromTypeNode(defaultDeclaration) : noConstraintType; - } - } - return typeParameter.default === noConstraintType ? undefined : typeParameter.default; + const defaultType = getResolvedTypeParameterDefault(typeParameter); + return defaultType !== noConstraintType && defaultType !== circularConstraintType ? defaultType : undefined; + } + + function hasNonCircularTypeParameterDefault(typeParameter: TypeParameter) { + return getResolvedTypeParameterDefault(typeParameter) !== circularConstraintType; + } + + /** + * Indicates whether the declaration of a typeParameter has a default type. + */ + function hasTypeParameterDefault(typeParameter: TypeParameter): boolean { + return !!(typeParameter.symbol && forEach(typeParameter.symbol.declarations, decl => isTypeParameterDeclaration(decl) && decl.default)); } /** @@ -6361,7 +6386,7 @@ namespace ts { let minTypeArgumentCount = 0; if (typeParameters) { for (let i = 0; i < typeParameters.length; i++) { - if (!getDefaultFromTypeParameter(typeParameters[i])) { + if (!hasTypeParameterDefault(typeParameters[i])) { minTypeArgumentCount = i + 1; } } @@ -18478,6 +18503,9 @@ namespace ts { if (!hasNonCircularBaseConstraint(typeParameter)) { error(node.constraint, Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(typeParameter)); } + if (!hasNonCircularTypeParameterDefault(typeParameter)) { + error(node.default, Diagnostics.Type_parameter_0_has_a_circular_default, typeToString(typeParameter)); + } const constraintType = getConstraintOfTypeParameter(typeParameter); const defaultType = getDefaultFromTypeParameter(typeParameter); if (constraintType && defaultType) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 91ad9e52bfd..3389bc1063e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2224,6 +2224,10 @@ "category": "Error", "code": 2715 }, + "Type parameter '{0}' has a circular default.": { + "category": "Error", + "code": 2716 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/tests/baselines/reference/genericDefaults.js b/tests/baselines/reference/genericDefaults.js index 06503b89d58..be6b76ea43c 100644 --- a/tests/baselines/reference/genericDefaults.js +++ b/tests/baselines/reference/genericDefaults.js @@ -487,7 +487,10 @@ const t03c00 = (>x).a; const t03c01 = (>x).a; const t03c02 = (>x).a; const t03c03 = (>x).a; -const t03c04 = (>x).a; +const t03c04 = (>x).a; + +// https://github.com/Microsoft/TypeScript/issues/16221 +interface SelfReference> {} //// [genericDefaults.js] // no inference @@ -1024,3 +1027,5 @@ declare const t03c01: [1, 1]; declare const t03c02: [number, number]; declare const t03c03: [1, 1]; declare const t03c04: [number, 1]; +interface SelfReference> { +} diff --git a/tests/baselines/reference/genericDefaults.symbols b/tests/baselines/reference/genericDefaults.symbols index 6c9e97b265e..755a34c7a63 100644 --- a/tests/baselines/reference/genericDefaults.symbols +++ b/tests/baselines/reference/genericDefaults.symbols @@ -2291,3 +2291,9 @@ const t03c04 = (>x).a; >x : Symbol(x, Decl(genericDefaults.ts, 13, 13)) >a : Symbol(a, Decl(genericDefaults.ts, 483, 47)) +// https://github.com/Microsoft/TypeScript/issues/16221 +interface SelfReference> {} +>SelfReference : Symbol(SelfReference, Decl(genericDefaults.ts, 488, 37)) +>T : Symbol(T, Decl(genericDefaults.ts, 491, 24)) +>SelfReference : Symbol(SelfReference, Decl(genericDefaults.ts, 488, 37)) + diff --git a/tests/baselines/reference/genericDefaults.types b/tests/baselines/reference/genericDefaults.types index 739588badb9..0013daefd89 100644 --- a/tests/baselines/reference/genericDefaults.types +++ b/tests/baselines/reference/genericDefaults.types @@ -2643,3 +2643,9 @@ const t03c04 = (>x).a; >x : any >a : [number, 1] +// https://github.com/Microsoft/TypeScript/issues/16221 +interface SelfReference> {} +>SelfReference : SelfReference +>T : T +>SelfReference : SelfReference + diff --git a/tests/baselines/reference/genericDefaultsErrors.errors.txt b/tests/baselines/reference/genericDefaultsErrors.errors.txt index 6200046c49f..762bb92535b 100644 --- a/tests/baselines/reference/genericDefaultsErrors.errors.txt +++ b/tests/baselines/reference/genericDefaultsErrors.errors.txt @@ -21,9 +21,10 @@ tests/cases/compiler/genericDefaultsErrors.ts(33,15): error TS2707: Generic type tests/cases/compiler/genericDefaultsErrors.ts(36,15): error TS2707: Generic type 'i09' requires between 2 and 3 type arguments. tests/cases/compiler/genericDefaultsErrors.ts(38,20): error TS2304: Cannot find name 'T'. tests/cases/compiler/genericDefaultsErrors.ts(38,20): error TS4033: Property 'x' of exported interface has or is using private name 'T'. +tests/cases/compiler/genericDefaultsErrors.ts(42,29): error TS2715: Type parameter 'T' has a circular default. -==== tests/cases/compiler/genericDefaultsErrors.ts (21 errors) ==== +==== tests/cases/compiler/genericDefaultsErrors.ts (22 errors) ==== declare const x: any; declare function f03(): void; // error @@ -106,4 +107,9 @@ tests/cases/compiler/genericDefaultsErrors.ts(38,20): error TS4033: Property 'x' !!! error TS2304: Cannot find name 'T'. ~ !!! error TS4033: Property 'x' of exported interface has or is using private name 'T'. - interface i10 {} \ No newline at end of file + interface i10 {} + + // https://github.com/Microsoft/TypeScript/issues/16221 + interface SelfReference {} + ~~~~~~~~~~~~~ +!!! error TS2715: Type parameter 'T' has a circular default. \ No newline at end of file diff --git a/tests/baselines/reference/genericDefaultsErrors.js b/tests/baselines/reference/genericDefaultsErrors.js index c737644e999..19201172b2f 100644 --- a/tests/baselines/reference/genericDefaultsErrors.js +++ b/tests/baselines/reference/genericDefaultsErrors.js @@ -37,7 +37,10 @@ type i09t03 = i09<1, 2, 3>; // ok type i09t04 = i09<1, 2, 3, 4>; // error interface i10 { x: T; } // error -interface i10 {} +interface i10 {} + +// https://github.com/Microsoft/TypeScript/issues/16221 +interface SelfReference {} //// [genericDefaultsErrors.js] f11(); // ok diff --git a/tests/baselines/reference/genericDefaultsErrors.symbols b/tests/baselines/reference/genericDefaultsErrors.symbols index 495b56ea25a..e6e5cb86062 100644 --- a/tests/baselines/reference/genericDefaultsErrors.symbols +++ b/tests/baselines/reference/genericDefaultsErrors.symbols @@ -136,3 +136,9 @@ interface i10 {} >i10 : Symbol(i10, Decl(genericDefaultsErrors.ts, 35, 30), Decl(genericDefaultsErrors.ts, 37, 23)) >T : Symbol(T, Decl(genericDefaultsErrors.ts, 38, 14)) +// https://github.com/Microsoft/TypeScript/issues/16221 +interface SelfReference {} +>SelfReference : Symbol(SelfReference, Decl(genericDefaultsErrors.ts, 38, 28)) +>T : Symbol(T, Decl(genericDefaultsErrors.ts, 41, 24)) +>SelfReference : Symbol(SelfReference, Decl(genericDefaultsErrors.ts, 38, 28)) + diff --git a/tests/baselines/reference/genericDefaultsErrors.types b/tests/baselines/reference/genericDefaultsErrors.types index 46bae67bc25..87e9af0bb07 100644 --- a/tests/baselines/reference/genericDefaultsErrors.types +++ b/tests/baselines/reference/genericDefaultsErrors.types @@ -145,3 +145,9 @@ interface i10 {} >i10 : i10 >T : T +// https://github.com/Microsoft/TypeScript/issues/16221 +interface SelfReference {} +>SelfReference : SelfReference +>T : T +>SelfReference : SelfReference + diff --git a/tests/cases/compiler/genericDefaults.ts b/tests/cases/compiler/genericDefaults.ts index 624b44c0829..e7b9c95edeb 100644 --- a/tests/cases/compiler/genericDefaults.ts +++ b/tests/cases/compiler/genericDefaults.ts @@ -487,4 +487,7 @@ const t03c00 = (>x).a; const t03c01 = (>x).a; const t03c02 = (>x).a; const t03c03 = (>x).a; -const t03c04 = (>x).a; \ No newline at end of file +const t03c04 = (>x).a; + +// https://github.com/Microsoft/TypeScript/issues/16221 +interface SelfReference> {} \ No newline at end of file diff --git a/tests/cases/compiler/genericDefaultsErrors.ts b/tests/cases/compiler/genericDefaultsErrors.ts index 4ea42beb3da..9cdba888327 100644 --- a/tests/cases/compiler/genericDefaultsErrors.ts +++ b/tests/cases/compiler/genericDefaultsErrors.ts @@ -38,4 +38,7 @@ type i09t03 = i09<1, 2, 3>; // ok type i09t04 = i09<1, 2, 3, 4>; // error interface i10 { x: T; } // error -interface i10 {} \ No newline at end of file +interface i10 {} + +// https://github.com/Microsoft/TypeScript/issues/16221 +interface SelfReference {} \ No newline at end of file From b9592d4186ac04ba9690ae6d2f86697ddcf820a9 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 9 Oct 2017 15:59:27 -0700 Subject: [PATCH 050/312] Use the parent most node_modules directory for module resolution failed lookup locations --- src/compiler/resolutionCache.ts | 14 +++---- .../unittests/tsserverProjectSystem.ts | 37 +++++++++++++++++++ 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index aecc6989891..25545c0efbc 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -323,19 +323,17 @@ namespace ts { let dir = getDirectoryPath(getNormalizedAbsolutePath(failedLookupLocation, getCurrentDirectory())); let dirPath = getDirectoryPath(failedLookupLocationPath); + // If directory path contains node module, get the most parent node_modules directory for watching + while (dirPath.indexOf("/node_modules/") !== -1) { + dir = getDirectoryPath(dir); + dirPath = getDirectoryPath(dirPath); + } + // If the directory is node_modules use it to watch if (isNodeModulesDirectory(dirPath)) { return { dir, dirPath }; } - // If directory path contains node module, get the node_modules directory for watching - if (dirPath.indexOf("/node_modules/") !== -1) { - while (!isNodeModulesDirectory(dirPath)) { - dir = getDirectoryPath(dir); - dirPath = getDirectoryPath(dirPath); - } - return { dir, dirPath }; - } // Use some ancestor of the root directory if (rootPath !== undefined) { diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 06e2beeaaa6..2f875456e06 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -2399,6 +2399,43 @@ namespace ts.projectSystem { checkWatchedDirectories(host, watchedRecursiveDirectories, /*recursive*/ true); }); + + it("Failed lookup locations are uses parent most node_modules directory", () => { + const file1: FileOrFolder = { + path: "/a/b/src/file1.ts", + content: 'import { classc } from "module1"' + }; + const module1: FileOrFolder = { + path: "/a/b/node_modules/module1/index.d.ts", + content: `import { class2 } from "module2"; + export classc { method2a(): class2; }` + }; + const module2: FileOrFolder = { + path: "/a/b/node_modules/module2/index.d.ts", + content: "export class2 { method2() { return 10; } }" + }; + const module3: FileOrFolder = { + path: "/a/b/node_modules/module/node_modules/module3/index.d.ts", + content: "export class3 { method2() { return 10; } }" + }; + const configFile: FileOrFolder = { + path: "/a/b/src/tsconfig.json", + content: JSON.stringify({ files: [file1.path] }) + }; + const files = [file1, module1, module2, module3, configFile, libFile]; + const host = createServerHost(files); + const projectService = createProjectService(host); + projectService.openClientFile(file1.path); + checkNumberOfProjects(projectService, { configuredProjects: 1 }); + const project = projectService.configuredProjects.get(configFile.path); + assert.isDefined(project); + checkProjectActualFiles(project, [file1.path, libFile.path, module1.path, module2.path, configFile.path]); + checkWatchedFiles(host, [libFile.path, module1.path, module2.path, configFile.path]); + checkWatchedDirectories(host, [], /*recursive*/ false); + const watchedRecursiveDirectories = getTypeRootsFromLocation("/a/b/src"); + watchedRecursiveDirectories.push("/a/b/src", "/a/b/node_modules"); + checkWatchedDirectories(host, watchedRecursiveDirectories, /*recursive*/ true); + }); }); describe("Proper errors", () => { From 17a1cd069dc4d1f45f09f57186f94e45505b5ed6 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 9 Oct 2017 16:55:20 -0700 Subject: [PATCH 051/312] Add deprecation warning to getSymbolDisplayBuilder (#18953) * Add deprecation warning to getSymbolDisplayBuilder * Accept API baselines --- src/compiler/types.ts | 4 ++++ tests/baselines/reference/api/tsserverlibrary.d.ts | 4 ++++ tests/baselines/reference/api/typescript.d.ts | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 13a23b77a0a..67b8606df5e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2653,6 +2653,10 @@ namespace ts { signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string; typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string; + /** + * @deprecated Use the createX factory functions or XToY typechecker methods and `createPrinter` or the `xToString` methods instead + * This will be removed in a future version. + */ getSymbolDisplayBuilder(): SymbolDisplayBuilder; getFullyQualifiedName(symbol: Symbol): string; getAugmentedPropertiesOfType(type: Type): Symbol[]; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index ce926dfc040..6da4262e0b7 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1731,6 +1731,10 @@ declare namespace ts { signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string; typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string; + /** + * @deprecated Use the createX factory functions or XToY typechecker methods and `createPrinter` or the `xToString` methods instead + * This will be removed in a future version. + */ getSymbolDisplayBuilder(): SymbolDisplayBuilder; getFullyQualifiedName(symbol: Symbol): string; getAugmentedPropertiesOfType(type: Type): Symbol[]; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index b8fd072c852..0c74f74c741 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1731,6 +1731,10 @@ declare namespace ts { signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string; typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string; + /** + * @deprecated Use the createX factory functions or XToY typechecker methods and `createPrinter` or the `xToString` methods instead + * This will be removed in a future version. + */ getSymbolDisplayBuilder(): SymbolDisplayBuilder; getFullyQualifiedName(symbol: Symbol): string; getAugmentedPropertiesOfType(type: Type): Symbol[]; From d23e5f1ee2fbe67db4ed0a5ac6dc856dfc7ce9c8 Mon Sep 17 00:00:00 2001 From: falsandtru Date: Tue, 10 Oct 2017 09:11:31 +0900 Subject: [PATCH 052/312] Fix Array.{reduce,reduceRight} methods (#18987) --- src/lib/es5.d.ts | 66 ++++++++++++------- .../anyInferenceAnonymousFunctions.symbols | 12 ++-- .../anyInferenceAnonymousFunctions.types | 12 ++-- ...plicateOverloadInTypeAugmentation1.symbols | 8 +-- ...duplicateOverloadInTypeAugmentation1.types | 8 +-- ...ericContextualTypingSpecialization.symbols | 4 +- ...enericContextualTypingSpecialization.types | 4 +- .../baselines/reference/genericReduce.symbols | 12 ++-- tests/baselines/reference/genericReduce.types | 12 ++-- ...ferFromGenericFunctionReturnTypes1.symbols | 4 +- ...inferFromGenericFunctionReturnTypes1.types | 4 +- ...ferFromGenericFunctionReturnTypes2.symbols | 4 +- ...inferFromGenericFunctionReturnTypes2.types | 4 +- .../baselines/reference/parserharness.symbols | 12 ++-- tests/baselines/reference/parserharness.types | 12 ++-- .../reference/recursiveTypeRelations.symbols | 4 +- .../reference/recursiveTypeRelations.types | 4 +- .../reference/restInvalidArgumentType.types | 2 +- .../returnTypeParameterWithModules.symbols | 4 +- .../returnTypeParameterWithModules.types | 4 +- .../reference/spreadInvalidArgumentType.types | 4 +- .../unknownSymbolOffContextualType1.symbols | 4 +- .../unknownSymbolOffContextualType1.types | 4 +- 23 files changed, 115 insertions(+), 93 deletions(-) diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index e08534d8ba9..fd2ae5b3fdf 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1050,7 +1050,8 @@ interface ReadonlyArray { * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array. * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value. */ - reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray) => T, initialValue?: T): T; + reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray) => T): T; + reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray) => T, initialValue: T): T; /** * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array. @@ -1062,7 +1063,8 @@ interface ReadonlyArray { * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value. */ - reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray) => T, initialValue?: T): T; + reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray) => T): T; + reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: ReadonlyArray) => T, initialValue: T): T; /** * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. @@ -1200,7 +1202,8 @@ interface Array { * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array. * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value. */ - reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T; + reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; + reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; /** * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array. @@ -1212,7 +1215,8 @@ interface Array { * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value. */ - reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T; + reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; + reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; /** * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. @@ -1647,7 +1651,8 @@ interface Int8Array { * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ - reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue?: number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array. The return value of @@ -1671,7 +1676,8 @@ interface Int8Array { * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ - reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue?: number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array, in descending order. @@ -1914,7 +1920,8 @@ interface Uint8Array { * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ - reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue?: number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array. The return value of @@ -1938,7 +1945,8 @@ interface Uint8Array { * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ - reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue?: number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array, in descending order. @@ -2181,7 +2189,8 @@ interface Uint8ClampedArray { * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ - reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number, initialValue?: number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array. The return value of @@ -2205,7 +2214,8 @@ interface Uint8ClampedArray { * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ - reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number, initialValue?: number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array, in descending order. @@ -2446,7 +2456,8 @@ interface Int16Array { * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ - reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number, initialValue?: number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array. The return value of @@ -2470,7 +2481,8 @@ interface Int16Array { * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ - reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number, initialValue?: number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array, in descending order. @@ -2714,7 +2726,8 @@ interface Uint16Array { * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ - reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number, initialValue?: number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array. The return value of @@ -2738,7 +2751,8 @@ interface Uint16Array { * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ - reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number, initialValue?: number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array, in descending order. @@ -2981,7 +2995,8 @@ interface Int32Array { * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ - reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number, initialValue?: number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array. The return value of @@ -3005,7 +3020,8 @@ interface Int32Array { * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ - reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number, initialValue?: number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array, in descending order. @@ -3247,7 +3263,8 @@ interface Uint32Array { * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ - reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number, initialValue?: number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array. The return value of @@ -3271,7 +3288,8 @@ interface Uint32Array { * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ - reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number, initialValue?: number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array, in descending order. @@ -3514,7 +3532,8 @@ interface Float32Array { * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ - reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number, initialValue?: number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array. The return value of @@ -3538,7 +3557,8 @@ interface Float32Array { * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ - reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number, initialValue?: number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array, in descending order. @@ -3782,7 +3802,8 @@ interface Float64Array { * the accumulation. The first call to the callbackfn function provides this value as an argument * instead of an array value. */ - reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number, initialValue?: number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number): number; + reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array. The return value of @@ -3806,7 +3827,8 @@ interface Float64Array { * the accumulation. The first call to the callbackfn function provides this value as an * argument instead of an array value. */ - reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number, initialValue?: number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number): number; + reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number, initialValue: number): number; /** * Calls the specified callback function for all the elements in an array, in descending order. diff --git a/tests/baselines/reference/anyInferenceAnonymousFunctions.symbols b/tests/baselines/reference/anyInferenceAnonymousFunctions.symbols index c1b5df88fb0..4aad165f40a 100644 --- a/tests/baselines/reference/anyInferenceAnonymousFunctions.symbols +++ b/tests/baselines/reference/anyInferenceAnonymousFunctions.symbols @@ -3,9 +3,9 @@ var paired: any[]; >paired : Symbol(paired, Decl(anyInferenceAnonymousFunctions.ts, 0, 3)) paired.reduce(function (a1, a2) { ->paired.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>paired.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >paired : Symbol(paired, Decl(anyInferenceAnonymousFunctions.ts, 0, 3)) ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >a1 : Symbol(a1, Decl(anyInferenceAnonymousFunctions.ts, 2, 24)) >a2 : Symbol(a2, Decl(anyInferenceAnonymousFunctions.ts, 2, 27)) @@ -15,9 +15,9 @@ paired.reduce(function (a1, a2) { } , []); paired.reduce((b1, b2) => { ->paired.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>paired.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >paired : Symbol(paired, Decl(anyInferenceAnonymousFunctions.ts, 0, 3)) ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >b1 : Symbol(b1, Decl(anyInferenceAnonymousFunctions.ts, 8, 15)) >b2 : Symbol(b2, Decl(anyInferenceAnonymousFunctions.ts, 8, 18)) @@ -27,9 +27,9 @@ paired.reduce((b1, b2) => { } , []); paired.reduce((b3, b4) => b3.concat({}), []); ->paired.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>paired.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >paired : Symbol(paired, Decl(anyInferenceAnonymousFunctions.ts, 0, 3)) ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >b3 : Symbol(b3, Decl(anyInferenceAnonymousFunctions.ts, 13, 15)) >b4 : Symbol(b4, Decl(anyInferenceAnonymousFunctions.ts, 13, 18)) >b3 : Symbol(b3, Decl(anyInferenceAnonymousFunctions.ts, 13, 15)) diff --git a/tests/baselines/reference/anyInferenceAnonymousFunctions.types b/tests/baselines/reference/anyInferenceAnonymousFunctions.types index 8dc7fdcb90f..d5f693b5453 100644 --- a/tests/baselines/reference/anyInferenceAnonymousFunctions.types +++ b/tests/baselines/reference/anyInferenceAnonymousFunctions.types @@ -4,9 +4,9 @@ var paired: any[]; paired.reduce(function (a1, a2) { >paired.reduce(function (a1, a2) { return a1.concat({});} , []) : any ->paired.reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue?: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } +>paired.reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any): any; (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } >paired : any[] ->reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue?: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any): any; (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } >function (a1, a2) { return a1.concat({});} : (a1: any, a2: any) => any >a1 : any >a2 : any @@ -23,9 +23,9 @@ paired.reduce(function (a1, a2) { paired.reduce((b1, b2) => { >paired.reduce((b1, b2) => { return b1.concat({});} , []) : any ->paired.reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue?: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } +>paired.reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any): any; (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } >paired : any[] ->reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue?: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any): any; (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } >(b1, b2) => { return b1.concat({});} : (b1: any, b2: any) => any >b1 : any >b2 : any @@ -42,9 +42,9 @@ paired.reduce((b1, b2) => { paired.reduce((b3, b4) => b3.concat({}), []); >paired.reduce((b3, b4) => b3.concat({}), []) : any ->paired.reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue?: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } +>paired.reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any): any; (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } >paired : any[] ->reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue?: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any): any; (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } >(b3, b4) => b3.concat({}) : (b3: any, b4: any) => any >b3 : any >b4 : any diff --git a/tests/baselines/reference/duplicateOverloadInTypeAugmentation1.symbols b/tests/baselines/reference/duplicateOverloadInTypeAugmentation1.symbols index 02589e011c4..31efb739e4c 100644 --- a/tests/baselines/reference/duplicateOverloadInTypeAugmentation1.symbols +++ b/tests/baselines/reference/duplicateOverloadInTypeAugmentation1.symbols @@ -4,7 +4,7 @@ interface Array { >T : Symbol(T, Decl(lib.d.ts, --, --), Decl(duplicateOverloadInTypeAugmentation1.ts, 0, 16)) reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(duplicateOverloadInTypeAugmentation1.ts, 0, 20), Decl(duplicateOverloadInTypeAugmentation1.ts, 2, 29)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(duplicateOverloadInTypeAugmentation1.ts, 0, 20), Decl(duplicateOverloadInTypeAugmentation1.ts, 2, 29)) >callbackfn : Symbol(callbackfn, Decl(duplicateOverloadInTypeAugmentation1.ts, 1, 11)) >previousValue : Symbol(previousValue, Decl(duplicateOverloadInTypeAugmentation1.ts, 1, 24)) >T : Symbol(T, Decl(lib.d.ts, --, --), Decl(duplicateOverloadInTypeAugmentation1.ts, 0, 16)) @@ -21,7 +21,7 @@ interface Array { >T : Symbol(T, Decl(lib.d.ts, --, --), Decl(duplicateOverloadInTypeAugmentation1.ts, 0, 16)) reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(duplicateOverloadInTypeAugmentation1.ts, 0, 20), Decl(duplicateOverloadInTypeAugmentation1.ts, 2, 29)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(duplicateOverloadInTypeAugmentation1.ts, 0, 20), Decl(duplicateOverloadInTypeAugmentation1.ts, 2, 29)) >U : Symbol(U, Decl(duplicateOverloadInTypeAugmentation1.ts, 3, 11)) >callbackfn : Symbol(callbackfn, Decl(duplicateOverloadInTypeAugmentation1.ts, 3, 14)) >previousValue : Symbol(previousValue, Decl(duplicateOverloadInTypeAugmentation1.ts, 3, 27)) @@ -44,9 +44,9 @@ var a: Array; var r5 = a.reduce((x, y) => x + y); >r5 : Symbol(r5, Decl(duplicateOverloadInTypeAugmentation1.ts, 7, 3)) ->a.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(duplicateOverloadInTypeAugmentation1.ts, 0, 20), Decl(duplicateOverloadInTypeAugmentation1.ts, 2, 29)) +>a.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(duplicateOverloadInTypeAugmentation1.ts, 0, 20), Decl(duplicateOverloadInTypeAugmentation1.ts, 2, 29)) >a : Symbol(a, Decl(duplicateOverloadInTypeAugmentation1.ts, 6, 3)) ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(duplicateOverloadInTypeAugmentation1.ts, 0, 20), Decl(duplicateOverloadInTypeAugmentation1.ts, 2, 29)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(duplicateOverloadInTypeAugmentation1.ts, 0, 20), Decl(duplicateOverloadInTypeAugmentation1.ts, 2, 29)) >x : Symbol(x, Decl(duplicateOverloadInTypeAugmentation1.ts, 7, 19)) >y : Symbol(y, Decl(duplicateOverloadInTypeAugmentation1.ts, 7, 21)) >x : Symbol(x, Decl(duplicateOverloadInTypeAugmentation1.ts, 7, 19)) diff --git a/tests/baselines/reference/duplicateOverloadInTypeAugmentation1.types b/tests/baselines/reference/duplicateOverloadInTypeAugmentation1.types index bc7214eb6b9..ea07ece4314 100644 --- a/tests/baselines/reference/duplicateOverloadInTypeAugmentation1.types +++ b/tests/baselines/reference/duplicateOverloadInTypeAugmentation1.types @@ -4,7 +4,7 @@ interface Array { >T : T reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, ->reduce : { (callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T; (callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; (callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T; (callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; (callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; (callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; (callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T; (callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } >callbackfn : (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T >previousValue : T >T : T @@ -21,7 +21,7 @@ interface Array { >T : T reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, ->reduce : { (callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T; (callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; (callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T; (callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; (callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; (callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; (callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T; (callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } >U : U >callbackfn : (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U >previousValue : U @@ -45,9 +45,9 @@ var a: Array; var r5 = a.reduce((x, y) => x + y); >r5 : string >a.reduce((x, y) => x + y) : string ->a.reduce : { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue?: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue?: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; } +>a.reduce : { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue?: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; } >a : string[] ->reduce : { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue?: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue?: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue?: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; } >(x, y) => x + y : (x: string, y: string) => string >x : string >y : string diff --git a/tests/baselines/reference/genericContextualTypingSpecialization.symbols b/tests/baselines/reference/genericContextualTypingSpecialization.symbols index b244ab496be..0dcc8cb5899 100644 --- a/tests/baselines/reference/genericContextualTypingSpecialization.symbols +++ b/tests/baselines/reference/genericContextualTypingSpecialization.symbols @@ -3,9 +3,9 @@ var b: number[]; >b : Symbol(b, Decl(genericContextualTypingSpecialization.ts, 0, 3)) b.reduce((c, d) => c + d, 0); // should not error on '+' ->b.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>b.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >b : Symbol(b, Decl(genericContextualTypingSpecialization.ts, 0, 3)) ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >c : Symbol(c, Decl(genericContextualTypingSpecialization.ts, 1, 18)) >d : Symbol(d, Decl(genericContextualTypingSpecialization.ts, 1, 20)) >c : Symbol(c, Decl(genericContextualTypingSpecialization.ts, 1, 18)) diff --git a/tests/baselines/reference/genericContextualTypingSpecialization.types b/tests/baselines/reference/genericContextualTypingSpecialization.types index 82255020347..d7d61010507 100644 --- a/tests/baselines/reference/genericContextualTypingSpecialization.types +++ b/tests/baselines/reference/genericContextualTypingSpecialization.types @@ -4,9 +4,9 @@ var b: number[]; b.reduce((c, d) => c + d, 0); // should not error on '+' >b.reduce((c, d) => c + d, 0) : number ->b.reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue?: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } +>b.reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } >b : number[] ->reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue?: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } >(c, d) => c + d : (c: number, d: number) => number >c : number >d : number diff --git a/tests/baselines/reference/genericReduce.symbols b/tests/baselines/reference/genericReduce.symbols index f220972a350..a939c5cf92d 100644 --- a/tests/baselines/reference/genericReduce.symbols +++ b/tests/baselines/reference/genericReduce.symbols @@ -14,9 +14,9 @@ var b = a.map(s => s.length); var n1 = b.reduce((x, y) => x + y); >n1 : Symbol(n1, Decl(genericReduce.ts, 2, 3)) ->b.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>b.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >b : Symbol(b, Decl(genericReduce.ts, 1, 3)) ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >x : Symbol(x, Decl(genericReduce.ts, 2, 19)) >y : Symbol(y, Decl(genericReduce.ts, 2, 21)) >x : Symbol(x, Decl(genericReduce.ts, 2, 19)) @@ -24,9 +24,9 @@ var n1 = b.reduce((x, y) => x + y); var n2 = b.reduceRight((x, y) => x + y); >n2 : Symbol(n2, Decl(genericReduce.ts, 3, 3)) ->b.reduceRight : Symbol(Array.reduceRight, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>b.reduceRight : Symbol(Array.reduceRight, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >b : Symbol(b, Decl(genericReduce.ts, 1, 3)) ->reduceRight : Symbol(Array.reduceRight, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>reduceRight : Symbol(Array.reduceRight, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >x : Symbol(x, Decl(genericReduce.ts, 3, 24)) >y : Symbol(y, Decl(genericReduce.ts, 3, 26)) >x : Symbol(x, Decl(genericReduce.ts, 3, 24)) @@ -50,9 +50,9 @@ n2.toExponential(2); // should not error if 'n2' is correctly number. var n3 = b.reduce( (x, y) => x + y, ""); // Initial value is of type string >n3 : Symbol(n3, Decl(genericReduce.ts, 10, 3)) ->b.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>b.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >b : Symbol(b, Decl(genericReduce.ts, 1, 3)) ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >x : Symbol(x, Decl(genericReduce.ts, 10, 28)) >y : Symbol(y, Decl(genericReduce.ts, 10, 30)) >x : Symbol(x, Decl(genericReduce.ts, 10, 28)) diff --git a/tests/baselines/reference/genericReduce.types b/tests/baselines/reference/genericReduce.types index 628398f86fd..65a069426a7 100644 --- a/tests/baselines/reference/genericReduce.types +++ b/tests/baselines/reference/genericReduce.types @@ -22,9 +22,9 @@ var b = a.map(s => s.length); var n1 = b.reduce((x, y) => x + y); >n1 : number >b.reduce((x, y) => x + y) : number ->b.reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue?: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } +>b.reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } >b : number[] ->reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue?: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } >(x, y) => x + y : (x: number, y: number) => number >x : number >y : number @@ -35,9 +35,9 @@ var n1 = b.reduce((x, y) => x + y); var n2 = b.reduceRight((x, y) => x + y); >n2 : number >b.reduceRight((x, y) => x + y) : number ->b.reduceRight : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue?: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } +>b.reduceRight : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } >b : number[] ->reduceRight : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue?: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } +>reduceRight : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } >(x, y) => x + y : (x: number, y: number) => number >x : number >y : number @@ -76,9 +76,9 @@ n2.toExponential(2); // should not error if 'n2' is correctly number. var n3 = b.reduce( (x, y) => x + y, ""); // Initial value is of type string >n3 : string >b.reduce( (x, y) => x + y, "") : string ->b.reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue?: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } +>b.reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } >b : number[] ->reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue?: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } >(x, y) => x + y : (x: string, y: number) => string >x : string >y : number diff --git a/tests/baselines/reference/inferFromGenericFunctionReturnTypes1.symbols b/tests/baselines/reference/inferFromGenericFunctionReturnTypes1.symbols index e18c80afcde..3060f44009b 100644 --- a/tests/baselines/reference/inferFromGenericFunctionReturnTypes1.symbols +++ b/tests/baselines/reference/inferFromGenericFunctionReturnTypes1.symbols @@ -124,9 +124,9 @@ function compose(...fns: ((x: T) => T)[]): (x: T) => T { return (x: T) => fns.reduce((prev, fn) => fn(prev), x); >x : Symbol(x, Decl(inferFromGenericFunctionReturnTypes1.ts, 27, 10)) >T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes1.ts, 26, 17)) ->fns.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>fns.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >fns : Symbol(fns, Decl(inferFromGenericFunctionReturnTypes1.ts, 26, 20)) ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >prev : Symbol(prev, Decl(inferFromGenericFunctionReturnTypes1.ts, 27, 31)) >fn : Symbol(fn, Decl(inferFromGenericFunctionReturnTypes1.ts, 27, 36)) >fn : Symbol(fn, Decl(inferFromGenericFunctionReturnTypes1.ts, 27, 36)) diff --git a/tests/baselines/reference/inferFromGenericFunctionReturnTypes1.types b/tests/baselines/reference/inferFromGenericFunctionReturnTypes1.types index dfbe6c2f2b6..9484b3aaa19 100644 --- a/tests/baselines/reference/inferFromGenericFunctionReturnTypes1.types +++ b/tests/baselines/reference/inferFromGenericFunctionReturnTypes1.types @@ -131,9 +131,9 @@ function compose(...fns: ((x: T) => T)[]): (x: T) => T { >x : T >T : T >fns.reduce((prev, fn) => fn(prev), x) : T ->fns.reduce : { (callbackfn: (previousValue: (x: T) => T, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => (x: T) => T, initialValue?: (x: T) => T): (x: T) => T; (callbackfn: (previousValue: U, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => U, initialValue: U): U; } +>fns.reduce : { (callbackfn: (previousValue: (x: T) => T, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => (x: T) => T): (x: T) => T; (callbackfn: (previousValue: (x: T) => T, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => (x: T) => T, initialValue: (x: T) => T): (x: T) => T; (callbackfn: (previousValue: U, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => U, initialValue: U): U; } >fns : ((x: T) => T)[] ->reduce : { (callbackfn: (previousValue: (x: T) => T, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => (x: T) => T, initialValue?: (x: T) => T): (x: T) => T; (callbackfn: (previousValue: U, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: (x: T) => T, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => (x: T) => T): (x: T) => T; (callbackfn: (previousValue: (x: T) => T, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => (x: T) => T, initialValue: (x: T) => T): (x: T) => T; (callbackfn: (previousValue: U, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => U, initialValue: U): U; } >(prev, fn) => fn(prev) : (prev: T, fn: (x: T) => T) => T >prev : T >fn : (x: T) => T diff --git a/tests/baselines/reference/inferFromGenericFunctionReturnTypes2.symbols b/tests/baselines/reference/inferFromGenericFunctionReturnTypes2.symbols index 7e4fe043b93..f7189682273 100644 --- a/tests/baselines/reference/inferFromGenericFunctionReturnTypes2.symbols +++ b/tests/baselines/reference/inferFromGenericFunctionReturnTypes2.symbols @@ -292,9 +292,9 @@ function compose(...fns: ((x: T) => T)[]): (x: T) => T { return (x: T) => fns.reduce((prev, fn) => fn(prev), x); >x : Symbol(x, Decl(inferFromGenericFunctionReturnTypes2.ts, 49, 10)) >T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes2.ts, 48, 17)) ->fns.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>fns.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >fns : Symbol(fns, Decl(inferFromGenericFunctionReturnTypes2.ts, 48, 20)) ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >prev : Symbol(prev, Decl(inferFromGenericFunctionReturnTypes2.ts, 49, 31)) >fn : Symbol(fn, Decl(inferFromGenericFunctionReturnTypes2.ts, 49, 36)) >fn : Symbol(fn, Decl(inferFromGenericFunctionReturnTypes2.ts, 49, 36)) diff --git a/tests/baselines/reference/inferFromGenericFunctionReturnTypes2.types b/tests/baselines/reference/inferFromGenericFunctionReturnTypes2.types index cf7752e237e..a36b7ed35be 100644 --- a/tests/baselines/reference/inferFromGenericFunctionReturnTypes2.types +++ b/tests/baselines/reference/inferFromGenericFunctionReturnTypes2.types @@ -358,9 +358,9 @@ function compose(...fns: ((x: T) => T)[]): (x: T) => T { >x : T >T : T >fns.reduce((prev, fn) => fn(prev), x) : T ->fns.reduce : { (callbackfn: (previousValue: (x: T) => T, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => (x: T) => T, initialValue?: (x: T) => T): (x: T) => T; (callbackfn: (previousValue: U, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => U, initialValue: U): U; } +>fns.reduce : { (callbackfn: (previousValue: (x: T) => T, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => (x: T) => T): (x: T) => T; (callbackfn: (previousValue: (x: T) => T, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => (x: T) => T, initialValue: (x: T) => T): (x: T) => T; (callbackfn: (previousValue: U, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => U, initialValue: U): U; } >fns : ((x: T) => T)[] ->reduce : { (callbackfn: (previousValue: (x: T) => T, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => (x: T) => T, initialValue?: (x: T) => T): (x: T) => T; (callbackfn: (previousValue: U, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: (x: T) => T, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => (x: T) => T): (x: T) => T; (callbackfn: (previousValue: (x: T) => T, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => (x: T) => T, initialValue: (x: T) => T): (x: T) => T; (callbackfn: (previousValue: U, currentValue: (x: T) => T, currentIndex: number, array: ((x: T) => T)[]) => U, initialValue: U): U; } >(prev, fn) => fn(prev) : (prev: T, fn: (x: T) => T) => T >prev : T >fn : (x: T) => T diff --git a/tests/baselines/reference/parserharness.symbols b/tests/baselines/reference/parserharness.symbols index 94ae5c87901..8382d6ab41a 100644 --- a/tests/baselines/reference/parserharness.symbols +++ b/tests/baselines/reference/parserharness.symbols @@ -4692,7 +4692,7 @@ module Harness { var minDistFromStart = entries.map(x => x.editRange.minChar).reduce((prev, current) => Math.min(prev, current)); >minDistFromStart : Symbol(minDistFromStart, Decl(parserharness.ts, 1595, 15)) ->entries.map(x => x.editRange.minChar).reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>entries.map(x => x.editRange.minChar).reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >entries.map : Symbol(Array.map, Decl(lib.d.ts, --, --)) >entries : Symbol(entries, Decl(parserharness.ts, 1593, 15)) >map : Symbol(Array.map, Decl(lib.d.ts, --, --)) @@ -4700,7 +4700,7 @@ module Harness { >x.editRange : Symbol(editRange, Decl(parserharness.ts, 1547, 44)) >x : Symbol(x, Decl(parserharness.ts, 1595, 47)) >editRange : Symbol(editRange, Decl(parserharness.ts, 1547, 44)) ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >prev : Symbol(prev, Decl(parserharness.ts, 1595, 81)) >current : Symbol(current, Decl(parserharness.ts, 1595, 86)) >Math.min : Symbol(Math.min, Decl(lib.d.ts, --, --)) @@ -4711,7 +4711,7 @@ module Harness { var minDistFromEnd = entries.map(x => x.length - x.editRange.limChar).reduce((prev, current) => Math.min(prev, current)); >minDistFromEnd : Symbol(minDistFromEnd, Decl(parserharness.ts, 1596, 15)) ->entries.map(x => x.length - x.editRange.limChar).reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>entries.map(x => x.length - x.editRange.limChar).reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >entries.map : Symbol(Array.map, Decl(lib.d.ts, --, --)) >entries : Symbol(entries, Decl(parserharness.ts, 1593, 15)) >map : Symbol(Array.map, Decl(lib.d.ts, --, --)) @@ -4722,7 +4722,7 @@ module Harness { >x.editRange : Symbol(editRange, Decl(parserharness.ts, 1547, 44)) >x : Symbol(x, Decl(parserharness.ts, 1596, 45)) >editRange : Symbol(editRange, Decl(parserharness.ts, 1547, 44)) ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >prev : Symbol(prev, Decl(parserharness.ts, 1596, 90)) >current : Symbol(current, Decl(parserharness.ts, 1596, 95)) >Math.min : Symbol(Math.min, Decl(lib.d.ts, --, --)) @@ -4733,7 +4733,7 @@ module Harness { var aggDelta = entries.map(x => x.editRange.delta).reduce((prev, current) => prev + current); >aggDelta : Symbol(aggDelta, Decl(parserharness.ts, 1597, 15)) ->entries.map(x => x.editRange.delta).reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>entries.map(x => x.editRange.delta).reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >entries.map : Symbol(Array.map, Decl(lib.d.ts, --, --)) >entries : Symbol(entries, Decl(parserharness.ts, 1593, 15)) >map : Symbol(Array.map, Decl(lib.d.ts, --, --)) @@ -4741,7 +4741,7 @@ module Harness { >x.editRange : Symbol(editRange, Decl(parserharness.ts, 1547, 44)) >x : Symbol(x, Decl(parserharness.ts, 1597, 39)) >editRange : Symbol(editRange, Decl(parserharness.ts, 1547, 44)) ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >prev : Symbol(prev, Decl(parserharness.ts, 1597, 71)) >current : Symbol(current, Decl(parserharness.ts, 1597, 76)) >prev : Symbol(prev, Decl(parserharness.ts, 1597, 71)) diff --git a/tests/baselines/reference/parserharness.types b/tests/baselines/reference/parserharness.types index 2fd260f5d2b..6ea78e22f2f 100644 --- a/tests/baselines/reference/parserharness.types +++ b/tests/baselines/reference/parserharness.types @@ -6604,7 +6604,7 @@ module Harness { var minDistFromStart = entries.map(x => x.editRange.minChar).reduce((prev, current) => Math.min(prev, current)); >minDistFromStart : any >entries.map(x => x.editRange.minChar).reduce((prev, current) => Math.min(prev, current)) : any ->entries.map(x => x.editRange.minChar).reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue?: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } +>entries.map(x => x.editRange.minChar).reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any): any; (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } >entries.map(x => x.editRange.minChar) : any[] >entries.map : (callbackfn: (value: { length: number; editRange: any; }, index: number, array: { length: number; editRange: any; }[]) => U, thisArg?: any) => U[] >entries : { length: number; editRange: any; }[] @@ -6616,7 +6616,7 @@ module Harness { >x : { length: number; editRange: any; } >editRange : any >minChar : any ->reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue?: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any): any; (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } >(prev, current) => Math.min(prev, current) : (prev: any, current: any) => number >prev : any >current : any @@ -6630,7 +6630,7 @@ module Harness { var minDistFromEnd = entries.map(x => x.length - x.editRange.limChar).reduce((prev, current) => Math.min(prev, current)); >minDistFromEnd : number >entries.map(x => x.length - x.editRange.limChar).reduce((prev, current) => Math.min(prev, current)) : number ->entries.map(x => x.length - x.editRange.limChar).reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue?: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } +>entries.map(x => x.length - x.editRange.limChar).reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } >entries.map(x => x.length - x.editRange.limChar) : number[] >entries.map : (callbackfn: (value: { length: number; editRange: any; }, index: number, array: { length: number; editRange: any; }[]) => U, thisArg?: any) => U[] >entries : { length: number; editRange: any; }[] @@ -6646,7 +6646,7 @@ module Harness { >x : { length: number; editRange: any; } >editRange : any >limChar : any ->reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue?: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } >(prev, current) => Math.min(prev, current) : (prev: number, current: number) => number >prev : number >current : number @@ -6660,7 +6660,7 @@ module Harness { var aggDelta = entries.map(x => x.editRange.delta).reduce((prev, current) => prev + current); >aggDelta : any >entries.map(x => x.editRange.delta).reduce((prev, current) => prev + current) : any ->entries.map(x => x.editRange.delta).reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue?: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } +>entries.map(x => x.editRange.delta).reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any): any; (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } >entries.map(x => x.editRange.delta) : any[] >entries.map : (callbackfn: (value: { length: number; editRange: any; }, index: number, array: { length: number; editRange: any; }[]) => U, thisArg?: any) => U[] >entries : { length: number; editRange: any; }[] @@ -6672,7 +6672,7 @@ module Harness { >x : { length: number; editRange: any; } >editRange : any >delta : any ->reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue?: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any): any; (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } >(prev, current) => prev + current : (prev: any, current: any) => any >prev : any >current : any diff --git a/tests/baselines/reference/recursiveTypeRelations.symbols b/tests/baselines/reference/recursiveTypeRelations.symbols index 9f656a789ed..2c940df2487 100644 --- a/tests/baselines/reference/recursiveTypeRelations.symbols +++ b/tests/baselines/reference/recursiveTypeRelations.symbols @@ -89,12 +89,12 @@ export function css(styles: S, ...classNam >arg : Symbol(arg, Decl(recursiveTypeRelations.ts, 18, 30)) return Object.keys(arg).reduce((obj: ClassNameObject, key: keyof S) => { ->Object.keys(arg).reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Object.keys(arg).reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >Object.keys : Symbol(ObjectConstructor.keys, Decl(lib.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >keys : Symbol(ObjectConstructor.keys, Decl(lib.d.ts, --, --)) >arg : Symbol(arg, Decl(recursiveTypeRelations.ts, 18, 30)) ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >obj : Symbol(obj, Decl(recursiveTypeRelations.ts, 26, 55)) >key : Symbol(key, Decl(recursiveTypeRelations.ts, 26, 76)) >S : Symbol(S, Decl(recursiveTypeRelations.ts, 17, 20)) diff --git a/tests/baselines/reference/recursiveTypeRelations.types b/tests/baselines/reference/recursiveTypeRelations.types index 6def28d4461..110ff8175c4 100644 --- a/tests/baselines/reference/recursiveTypeRelations.types +++ b/tests/baselines/reference/recursiveTypeRelations.types @@ -102,13 +102,13 @@ export function css(styles: S, ...classNam return Object.keys(arg).reduce((obj: ClassNameObject, key: keyof S) => { >Object.keys(arg).reduce((obj: ClassNameObject, key: keyof S) => { const exportedClassName = styles[key]; obj[exportedClassName] = (arg as ClassNameMap)[key]; return obj; }, {}) : any ->Object.keys(arg).reduce : { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue?: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; } +>Object.keys(arg).reduce : { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; } >Object.keys(arg) : string[] >Object.keys : (o: {}) => string[] >Object : ObjectConstructor >keys : (o: {}) => string[] >arg : keyof S | (object & { [K in keyof S]?: boolean; }) ->reduce : { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue?: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; } >ClassNameObject : No type information available! >(obj: ClassNameObject, key: keyof S) => { const exportedClassName = styles[key]; obj[exportedClassName] = (arg as ClassNameMap)[key]; return obj; } : (obj: any, key: keyof S) => any >obj : any diff --git a/tests/baselines/reference/restInvalidArgumentType.types b/tests/baselines/reference/restInvalidArgumentType.types index 28162bcc7cc..39495008877 100644 --- a/tests/baselines/reference/restInvalidArgumentType.types +++ b/tests/baselines/reference/restInvalidArgumentType.types @@ -87,7 +87,7 @@ function f(p1: T, p2: T[]) { >p1 : T var {...r2} = p2; // OK ->r2 : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ReadonlyArray[]): T[]; concat(...items: (T | ReadonlyArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } +>r2 : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ReadonlyArray[]): T[]; concat(...items: (T | ReadonlyArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } >p2 : T[] var {...r3} = t; // Error, generic type paramter diff --git a/tests/baselines/reference/returnTypeParameterWithModules.symbols b/tests/baselines/reference/returnTypeParameterWithModules.symbols index 7f8fab382a3..eb56940b604 100644 --- a/tests/baselines/reference/returnTypeParameterWithModules.symbols +++ b/tests/baselines/reference/returnTypeParameterWithModules.symbols @@ -13,11 +13,11 @@ module M1 { return Array.prototype.reduce.apply(ar, e ? [f, e] : [f]); >Array.prototype.reduce.apply : Symbol(Function.apply, Decl(lib.d.ts, --, --)) ->Array.prototype.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Array.prototype.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >Array.prototype : Symbol(ArrayConstructor.prototype, Decl(lib.d.ts, --, --)) >Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >prototype : Symbol(ArrayConstructor.prototype, Decl(lib.d.ts, --, --)) ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >apply : Symbol(Function.apply, Decl(lib.d.ts, --, --)) >ar : Symbol(ar, Decl(returnTypeParameterWithModules.ts, 1, 30)) >e : Symbol(e, Decl(returnTypeParameterWithModules.ts, 1, 36)) diff --git a/tests/baselines/reference/returnTypeParameterWithModules.types b/tests/baselines/reference/returnTypeParameterWithModules.types index 584c962a170..3aec0f14fcf 100644 --- a/tests/baselines/reference/returnTypeParameterWithModules.types +++ b/tests/baselines/reference/returnTypeParameterWithModules.types @@ -14,11 +14,11 @@ module M1 { return Array.prototype.reduce.apply(ar, e ? [f, e] : [f]); >Array.prototype.reduce.apply(ar, e ? [f, e] : [f]) : any >Array.prototype.reduce.apply : (this: Function, thisArg: any, argArray?: any) => any ->Array.prototype.reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue?: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } +>Array.prototype.reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any): any; (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } >Array.prototype : any[] >Array : ArrayConstructor >prototype : any[] ->reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue?: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any): any; (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } >apply : (this: Function, thisArg: any, argArray?: any) => any >ar : any >e ? [f, e] : [f] : any[] diff --git a/tests/baselines/reference/spreadInvalidArgumentType.types b/tests/baselines/reference/spreadInvalidArgumentType.types index 1eebc00850f..244d8515893 100644 --- a/tests/baselines/reference/spreadInvalidArgumentType.types +++ b/tests/baselines/reference/spreadInvalidArgumentType.types @@ -89,8 +89,8 @@ function f(p1: T, p2: T[]) { >p1 : T var o2 = { ...p2 }; // OK ->o2 : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ReadonlyArray[]): T[]; concat(...items: (T | ReadonlyArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } ->{ ...p2 } : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ReadonlyArray[]): T[]; concat(...items: (T | ReadonlyArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } +>o2 : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ReadonlyArray[]): T[]; concat(...items: (T | ReadonlyArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } +>{ ...p2 } : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ReadonlyArray[]): T[]; concat(...items: (T | ReadonlyArray)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; } >p2 : T[] var o3 = { ...t }; // Error, generic type paramter diff --git a/tests/baselines/reference/unknownSymbolOffContextualType1.symbols b/tests/baselines/reference/unknownSymbolOffContextualType1.symbols index 1e19afeb6a0..3acf34ec9bf 100644 --- a/tests/baselines/reference/unknownSymbolOffContextualType1.symbols +++ b/tests/baselines/reference/unknownSymbolOffContextualType1.symbols @@ -61,9 +61,9 @@ function getMaxWidth(elementNames: string[]) { }); var maxWidth = widths.reduce(function (a, b) { >maxWidth : Symbol(maxWidth, Decl(unknownSymbolOffContextualType1.ts, 17, 7)) ->widths.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>widths.reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >widths : Symbol(widths, Decl(unknownSymbolOffContextualType1.ts, 14, 7)) ->reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>reduce : Symbol(Array.reduce, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >a : Symbol(a, Decl(unknownSymbolOffContextualType1.ts, 17, 43)) >b : Symbol(b, Decl(unknownSymbolOffContextualType1.ts, 17, 45)) diff --git a/tests/baselines/reference/unknownSymbolOffContextualType1.types b/tests/baselines/reference/unknownSymbolOffContextualType1.types index c6f05b69b74..7df3bd52cc9 100644 --- a/tests/baselines/reference/unknownSymbolOffContextualType1.types +++ b/tests/baselines/reference/unknownSymbolOffContextualType1.types @@ -72,9 +72,9 @@ function getMaxWidth(elementNames: string[]) { var maxWidth = widths.reduce(function (a, b) { >maxWidth : any >widths.reduce(function (a, b) { return a > b ? a : b; }) : any ->widths.reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue?: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } +>widths.reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any): any; (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } >widths : any[] ->reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue?: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } +>reduce : { (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any): any; (callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue: any): any; (callbackfn: (previousValue: U, currentValue: any, currentIndex: number, array: any[]) => U, initialValue: U): U; } >function (a, b) { return a > b ? a : b; } : (a: any, b: any) => any >a : any >b : any From dc607c29b4f281d8734a70264525ecf3fbe64c25 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 9 Oct 2017 17:15:13 -0700 Subject: [PATCH 053/312] Fix 'this' capturing for dynamic import --- src/compiler/binder.ts | 6 ++ src/compiler/transformers/module/module.ts | 89 ++++++++++++++----- .../dynamicImportWithNestedThis_es2015.js | 37 ++++++++ ...dynamicImportWithNestedThis_es2015.symbols | 27 ++++++ .../dynamicImportWithNestedThis_es2015.types | 31 +++++++ .../dynamicImportWithNestedThis_es5.js | 39 ++++++++ .../dynamicImportWithNestedThis_es5.symbols | 27 ++++++ .../dynamicImportWithNestedThis_es5.types | 31 +++++++ .../dynamicImportWithNestedThis_es2015.ts | 14 +++ .../dynamicImportWithNestedThis_es5.ts | 14 +++ 10 files changed, 292 insertions(+), 23 deletions(-) create mode 100644 tests/baselines/reference/dynamicImportWithNestedThis_es2015.js create mode 100644 tests/baselines/reference/dynamicImportWithNestedThis_es2015.symbols create mode 100644 tests/baselines/reference/dynamicImportWithNestedThis_es2015.types create mode 100644 tests/baselines/reference/dynamicImportWithNestedThis_es5.js create mode 100644 tests/baselines/reference/dynamicImportWithNestedThis_es5.symbols create mode 100644 tests/baselines/reference/dynamicImportWithNestedThis_es5.types create mode 100644 tests/cases/compiler/dynamicImportWithNestedThis_es2015.ts create mode 100644 tests/cases/compiler/dynamicImportWithNestedThis_es5.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 9b977eb6bfc..48cace44841 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2699,6 +2699,12 @@ namespace ts { if (expression.kind === SyntaxKind.ImportKeyword) { transformFlags |= TransformFlags.ContainsDynamicImport; + + // A dynamic 'import()' call that contains a lexical 'this' will + // require a captured 'this' when emitting down-level. + if (subtreeFlags & TransformFlags.ContainsLexicalThis) { + transformFlags |= TransformFlags.ContainsCapturedLexicalThis; + } } node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index ecbef685649..ba262bf2c59 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -561,46 +561,89 @@ namespace ts { // }); const resolve = createUniqueName("resolve"); const reject = createUniqueName("reject"); - return createNew( - createIdentifier("Promise"), - /*typeArguments*/ undefined, - [createFunctionExpression( + const parameters = [ + createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ resolve), + createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ reject) + ]; + const body = createBlock([ + createStatement( + createCall( + createIdentifier("require"), + /*typeArguments*/ undefined, + [createArrayLiteral([firstOrUndefined(node.arguments) || createOmittedExpression()]), resolve, reject] + ) + ) + ]); + + let func: FunctionExpression | ArrowFunction; + if (languageVersion >= ScriptTarget.ES2015) { + func = createArrowFunction( + /*modifiers*/ undefined, + /*typeParameters*/ undefined, + parameters, + /*type*/ undefined, + /*equalsGreaterThanToken*/ undefined, + body); + } + else { + func = createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, - [createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ resolve), - createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ reject)], + parameters, /*type*/ undefined, - createBlock([createStatement( - createCall( - createIdentifier("require"), - /*typeArguments*/ undefined, - [createArrayLiteral([firstOrUndefined(node.arguments) || createOmittedExpression()]), resolve, reject] - ))]) - )]); + body); + + // if there is a lexical 'this' in the import call arguments, ensure we indicate + // that this new function expression indicates it captures 'this' so that the + // es2015 transformer will properly substitute 'this' with '_this'. + if (node.transformFlags & TransformFlags.ContainsLexicalThis) { + setEmitFlags(func, EmitFlags.CapturesThis); + } + } + + return createNew(createIdentifier("Promise"), /*typeArguments*/ undefined, [func]); } - function transformImportCallExpressionCommonJS(node: ImportCall): Expression { + function transformImportCallExpressionCommonJS(node: ImportCall): Expression { // import("./blah") // emit as // Promise.resolve().then(function () { return require(x); }) /*CommonJs Require*/ // We have to wrap require in then callback so that require is done in asynchronously // if we simply do require in resolve callback in Promise constructor. We will execute the loading immediately - return createCall( - createPropertyAccess( - createCall(createPropertyAccess(createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []), - "then"), - /*typeArguments*/ undefined, - [createFunctionExpression( + const promiseResolveCall = createCall(createPropertyAccess(createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []); + const requireCall = createCall(createIdentifier("require"), /*typeArguments*/ undefined, node.arguments); + + let func: FunctionExpression | ArrowFunction; + if (languageVersion >= ScriptTarget.ES2015) { + func = createArrowFunction( + /*modifiers*/ undefined, + /*typeParameters*/ undefined, + /*parameters*/ [], + /*type*/ undefined, + /*equalsGreaterThanToken*/ undefined, + requireCall); + } + else { + func = createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, - /*parameters*/ undefined, + /*parameters*/ [], /*type*/ undefined, - createBlock([createReturn(createCall(createIdentifier("require"), /*typeArguments*/ undefined, node.arguments))]) - )]); + createBlock([createReturn(requireCall)])); + + // if there is a lexical 'this' in the import call arguments, ensure we indicate + // that this new function expression indicates it captures 'this' so that the + // es2015 transformer will properly substitute 'this' with '_this'. + if (node.transformFlags & TransformFlags.ContainsLexicalThis) { + setEmitFlags(func, EmitFlags.CapturesThis); + } + } + + return createCall(createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]); } /** diff --git a/tests/baselines/reference/dynamicImportWithNestedThis_es2015.js b/tests/baselines/reference/dynamicImportWithNestedThis_es2015.js new file mode 100644 index 00000000000..86fba0c0b5d --- /dev/null +++ b/tests/baselines/reference/dynamicImportWithNestedThis_es2015.js @@ -0,0 +1,37 @@ +//// [dynamicImportWithNestedThis_es2015.ts] +// https://github.com/Microsoft/TypeScript/issues/17564 +class C { + private _path = './other'; + + dynamic() { + return import(this._path); + } +} + +const c = new C(); +c.dynamic(); + +//// [dynamicImportWithNestedThis_es2015.js] +(function (factory) { + if (typeof module === "object" && typeof module.exports === "object") { + var v = factory(require, exports); + if (v !== undefined) module.exports = v; + } + else if (typeof define === "function" && define.amd) { + define(["require", "exports"], factory); + } +})(function (require, exports) { + "use strict"; + var __syncRequire = typeof module === "object" && typeof module.exports === "object"; + // https://github.com/Microsoft/TypeScript/issues/17564 + class C { + constructor() { + this._path = './other'; + } + dynamic() { + return __syncRequire ? Promise.resolve().then(() => require(this._path)) : new Promise((resolve_1, reject_1) => { require([this._path], resolve_1, reject_1); }); + } + } + const c = new C(); + c.dynamic(); +}); diff --git a/tests/baselines/reference/dynamicImportWithNestedThis_es2015.symbols b/tests/baselines/reference/dynamicImportWithNestedThis_es2015.symbols new file mode 100644 index 00000000000..7043a071124 --- /dev/null +++ b/tests/baselines/reference/dynamicImportWithNestedThis_es2015.symbols @@ -0,0 +1,27 @@ +=== tests/cases/compiler/dynamicImportWithNestedThis_es2015.ts === +// https://github.com/Microsoft/TypeScript/issues/17564 +class C { +>C : Symbol(C, Decl(dynamicImportWithNestedThis_es2015.ts, 0, 0)) + + private _path = './other'; +>_path : Symbol(C._path, Decl(dynamicImportWithNestedThis_es2015.ts, 1, 9)) + + dynamic() { +>dynamic : Symbol(C.dynamic, Decl(dynamicImportWithNestedThis_es2015.ts, 2, 27)) + + return import(this._path); +>this._path : Symbol(C._path, Decl(dynamicImportWithNestedThis_es2015.ts, 1, 9)) +>this : Symbol(C, Decl(dynamicImportWithNestedThis_es2015.ts, 0, 0)) +>_path : Symbol(C._path, Decl(dynamicImportWithNestedThis_es2015.ts, 1, 9)) + } +} + +const c = new C(); +>c : Symbol(c, Decl(dynamicImportWithNestedThis_es2015.ts, 9, 5)) +>C : Symbol(C, Decl(dynamicImportWithNestedThis_es2015.ts, 0, 0)) + +c.dynamic(); +>c.dynamic : Symbol(C.dynamic, Decl(dynamicImportWithNestedThis_es2015.ts, 2, 27)) +>c : Symbol(c, Decl(dynamicImportWithNestedThis_es2015.ts, 9, 5)) +>dynamic : Symbol(C.dynamic, Decl(dynamicImportWithNestedThis_es2015.ts, 2, 27)) + diff --git a/tests/baselines/reference/dynamicImportWithNestedThis_es2015.types b/tests/baselines/reference/dynamicImportWithNestedThis_es2015.types new file mode 100644 index 00000000000..165929a43cf --- /dev/null +++ b/tests/baselines/reference/dynamicImportWithNestedThis_es2015.types @@ -0,0 +1,31 @@ +=== tests/cases/compiler/dynamicImportWithNestedThis_es2015.ts === +// https://github.com/Microsoft/TypeScript/issues/17564 +class C { +>C : C + + private _path = './other'; +>_path : string +>'./other' : "./other" + + dynamic() { +>dynamic : () => Promise + + return import(this._path); +>import(this._path) : Promise +>this._path : string +>this : this +>_path : string + } +} + +const c = new C(); +>c : C +>new C() : C +>C : typeof C + +c.dynamic(); +>c.dynamic() : Promise +>c.dynamic : () => Promise +>c : C +>dynamic : () => Promise + diff --git a/tests/baselines/reference/dynamicImportWithNestedThis_es5.js b/tests/baselines/reference/dynamicImportWithNestedThis_es5.js new file mode 100644 index 00000000000..cde1979b25b --- /dev/null +++ b/tests/baselines/reference/dynamicImportWithNestedThis_es5.js @@ -0,0 +1,39 @@ +//// [dynamicImportWithNestedThis_es5.ts] +// https://github.com/Microsoft/TypeScript/issues/17564 +class C { + private _path = './other'; + + dynamic() { + return import(this._path); + } +} + +const c = new C(); +c.dynamic(); + +//// [dynamicImportWithNestedThis_es5.js] +(function (factory) { + if (typeof module === "object" && typeof module.exports === "object") { + var v = factory(require, exports); + if (v !== undefined) module.exports = v; + } + else if (typeof define === "function" && define.amd) { + define(["require", "exports"], factory); + } +})(function (require, exports) { + "use strict"; + var __syncRequire = typeof module === "object" && typeof module.exports === "object"; + // https://github.com/Microsoft/TypeScript/issues/17564 + var C = /** @class */ (function () { + function C() { + this._path = './other'; + } + C.prototype.dynamic = function () { + var _this = this; + return __syncRequire ? Promise.resolve().then(function () { return require(_this._path); }) : new Promise(function (resolve_1, reject_1) { require([_this._path], resolve_1, reject_1); }); + }; + return C; + }()); + var c = new C(); + c.dynamic(); +}); diff --git a/tests/baselines/reference/dynamicImportWithNestedThis_es5.symbols b/tests/baselines/reference/dynamicImportWithNestedThis_es5.symbols new file mode 100644 index 00000000000..6a127548030 --- /dev/null +++ b/tests/baselines/reference/dynamicImportWithNestedThis_es5.symbols @@ -0,0 +1,27 @@ +=== tests/cases/compiler/dynamicImportWithNestedThis_es5.ts === +// https://github.com/Microsoft/TypeScript/issues/17564 +class C { +>C : Symbol(C, Decl(dynamicImportWithNestedThis_es5.ts, 0, 0)) + + private _path = './other'; +>_path : Symbol(C._path, Decl(dynamicImportWithNestedThis_es5.ts, 1, 9)) + + dynamic() { +>dynamic : Symbol(C.dynamic, Decl(dynamicImportWithNestedThis_es5.ts, 2, 27)) + + return import(this._path); +>this._path : Symbol(C._path, Decl(dynamicImportWithNestedThis_es5.ts, 1, 9)) +>this : Symbol(C, Decl(dynamicImportWithNestedThis_es5.ts, 0, 0)) +>_path : Symbol(C._path, Decl(dynamicImportWithNestedThis_es5.ts, 1, 9)) + } +} + +const c = new C(); +>c : Symbol(c, Decl(dynamicImportWithNestedThis_es5.ts, 9, 5)) +>C : Symbol(C, Decl(dynamicImportWithNestedThis_es5.ts, 0, 0)) + +c.dynamic(); +>c.dynamic : Symbol(C.dynamic, Decl(dynamicImportWithNestedThis_es5.ts, 2, 27)) +>c : Symbol(c, Decl(dynamicImportWithNestedThis_es5.ts, 9, 5)) +>dynamic : Symbol(C.dynamic, Decl(dynamicImportWithNestedThis_es5.ts, 2, 27)) + diff --git a/tests/baselines/reference/dynamicImportWithNestedThis_es5.types b/tests/baselines/reference/dynamicImportWithNestedThis_es5.types new file mode 100644 index 00000000000..78b0f472971 --- /dev/null +++ b/tests/baselines/reference/dynamicImportWithNestedThis_es5.types @@ -0,0 +1,31 @@ +=== tests/cases/compiler/dynamicImportWithNestedThis_es5.ts === +// https://github.com/Microsoft/TypeScript/issues/17564 +class C { +>C : C + + private _path = './other'; +>_path : string +>'./other' : "./other" + + dynamic() { +>dynamic : () => Promise + + return import(this._path); +>import(this._path) : Promise +>this._path : string +>this : this +>_path : string + } +} + +const c = new C(); +>c : C +>new C() : C +>C : typeof C + +c.dynamic(); +>c.dynamic() : Promise +>c.dynamic : () => Promise +>c : C +>dynamic : () => Promise + diff --git a/tests/cases/compiler/dynamicImportWithNestedThis_es2015.ts b/tests/cases/compiler/dynamicImportWithNestedThis_es2015.ts new file mode 100644 index 00000000000..3c7f2936931 --- /dev/null +++ b/tests/cases/compiler/dynamicImportWithNestedThis_es2015.ts @@ -0,0 +1,14 @@ +// @lib: es2015 +// @target: es2015 +// @module: umd +// https://github.com/Microsoft/TypeScript/issues/17564 +class C { + private _path = './other'; + + dynamic() { + return import(this._path); + } +} + +const c = new C(); +c.dynamic(); \ No newline at end of file diff --git a/tests/cases/compiler/dynamicImportWithNestedThis_es5.ts b/tests/cases/compiler/dynamicImportWithNestedThis_es5.ts new file mode 100644 index 00000000000..5740c3f6694 --- /dev/null +++ b/tests/cases/compiler/dynamicImportWithNestedThis_es5.ts @@ -0,0 +1,14 @@ +// @lib: es2015 +// @target: es5 +// @module: umd +// https://github.com/Microsoft/TypeScript/issues/17564 +class C { + private _path = './other'; + + dynamic() { + return import(this._path); + } +} + +const c = new C(); +c.dynamic(); \ No newline at end of file From aa22c56282021e19fe546d2f65f650836f826e3b Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 9 Oct 2017 18:03:05 -0700 Subject: [PATCH 054/312] Swallow the directory watcher exceptions --- src/server/server.ts | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/server/server.ts b/src/server/server.ts index 6fab1a3d08a..7917f6fb544 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -753,10 +753,21 @@ namespace ts.server { const sys = ts.sys; // use watchGuard process on Windows when node version is 4 or later const useWatchGuard = process.platform === "win32" && getNodeMajorVersion() >= 4; + const originalWatchDirectory = sys.watchDirectory; + const noopWatcher: FileWatcher = { close: noop }; + function watchDirectorySwallowingException(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher { + try { + return originalWatchDirectory.call(sys, path, callback, recursive); + } + catch (e) { + logger.info(`Exception when creating directory watcher: ${e.message}`); + return noopWatcher; + } + } + if (useWatchGuard) { const currentDrive = extractWatchDirectoryCacheKey(sys.resolvePath(sys.getCurrentDirectory()), /*currentDriveKey*/ undefined); const statusCache = createMap(); - const originalWatchDirectory = sys.watchDirectory; sys.watchDirectory = function (path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher { const cacheKey = extractWatchDirectoryCacheKey(path, currentDrive); let status = cacheKey && statusCache.get(cacheKey); @@ -790,14 +801,17 @@ namespace ts.server { } if (status) { // this drive is safe to use - call real 'watchDirectory' - return originalWatchDirectory.call(sys, path, callback, recursive); + return watchDirectorySwallowingException(path, callback, recursive); } else { // this drive is unsafe - return no-op watcher - return { close() { } }; + return noopWatcher; } }; } + else { + sys.watchDirectory = watchDirectorySwallowingException; + } // Override sys.write because fs.writeSync is not reliable on Node 4 sys.write = (s: string) => writeMessage(new Buffer(s, "utf8")); From 98d58d651747702f2f9252ad93125026a770c565 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 9 Oct 2017 20:12:53 -0700 Subject: [PATCH 055/312] Handle project close to release all the script infos held by the project --- src/server/project.ts | 24 +++++++++---------- .../reference/api/tsserverlibrary.d.ts | 1 + 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/server/project.ts b/src/server/project.ts index e8bfd7c1b75..db540ccfac2 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -495,25 +495,25 @@ namespace ts.server { close() { if (this.program) { - // if we have a program - release all files that are enlisted in program + // if we have a program - release all files that are enlisted in program but arent root + // The releasing of the roots happens later + // The project could have pending update remaining and hence the info could be in the files but not in program graph for (const f of this.program.getSourceFiles()) { - this.detachScriptInfo(f.fileName); + this.detachScriptInfoIfNotRoot(f.fileName); } } - if (!this.program || !this.languageServiceEnabled) { - // release all root files either if there is no program or language service is disabled. - // in the latter case set of root files can be larger than the set of files in program. - for (const root of this.rootFiles) { - root.detachFromProject(this); - } + // Release external files + forEach(this.externalFiles, externalFile => this.detachScriptInfoIfNotRoot(externalFile)); + // Always remove root files from the project + for (const root of this.rootFiles) { + root.detachFromProject(this); } this.rootFiles = undefined; this.rootFilesMap = undefined; + this.externalFiles = undefined; this.program = undefined; this.builder = undefined; - forEach(this.externalFiles, externalFile => this.detachScriptInfo(externalFile)); - this.externalFiles = undefined; this.resolutionCache.clear(); this.resolutionCache = undefined; this.cachedUnresolvedImportsPerFile = undefined; @@ -530,11 +530,11 @@ namespace ts.server { this.languageService = undefined; } - private detachScriptInfo(uncheckedFilename: string) { + private detachScriptInfoIfNotRoot(uncheckedFilename: string) { const info = this.projectService.getScriptInfo(uncheckedFilename); // We might not find the script info in case its not associated with the project any more // and project graph was not updated (eg delayed update graph in case of files changed/deleted on the disk) - if (info) { + if (info && !this.isRoot(info)) { info.detachFromProject(this); } } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 7fe07813adc..0097ba24942 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7136,6 +7136,7 @@ declare namespace ts.server { getExternalFiles(): SortedReadonlyArray; getSourceFile(path: Path): SourceFile; close(): void; + private detachScriptInfoIfNotRoot(uncheckedFilename); isClosed(): boolean; hasRoots(): boolean; getRootFiles(): NormalizedPath[]; From dca6e33ac7ba655af0d27a9d2e9555424c9cc67e Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 10 Oct 2017 10:03:18 -0700 Subject: [PATCH 056/312] baseline updates --- .../reference/importCallExpressionAsyncES6AMD.js | 10 +++++----- .../reference/importCallExpressionAsyncES6CJS.js | 10 +++++----- .../reference/importCallExpressionAsyncES6UMD.js | 10 +++++----- .../importCallExpressionCheckReturntype1.js | 6 +++--- .../importCallExpressionDeclarationEmit1.js | 10 +++++----- .../reference/importCallExpressionES6AMD.js | 12 ++++++------ .../reference/importCallExpressionES6CJS.js | 12 ++++++------ .../reference/importCallExpressionES6UMD.js | 12 ++++++------ .../importCallExpressionGrammarError.js | 10 +++++----- .../reference/importCallExpressionInAMD1.js | 8 ++++---- .../reference/importCallExpressionInAMD2.js | 2 +- .../reference/importCallExpressionInAMD3.js | 2 +- .../reference/importCallExpressionInAMD4.js | 12 ++++++------ .../reference/importCallExpressionInCJS1.js | 8 ++++---- .../reference/importCallExpressionInCJS2.js | 4 ++-- .../reference/importCallExpressionInCJS3.js | 2 +- .../reference/importCallExpressionInCJS4.js | 2 +- .../reference/importCallExpressionInCJS5.js | 12 ++++++------ .../importCallExpressionInExportEqualsAMD.js | 2 +- .../importCallExpressionInExportEqualsCJS.js | 2 +- .../importCallExpressionInExportEqualsUMD.js | 2 +- .../importCallExpressionInScriptContext1.js | 2 +- .../importCallExpressionInScriptContext2.js | 2 +- .../reference/importCallExpressionInUMD1.js | 8 ++++---- .../reference/importCallExpressionInUMD2.js | 2 +- .../reference/importCallExpressionInUMD3.js | 2 +- .../reference/importCallExpressionInUMD4.js | 12 ++++++------ .../importCallExpressionReturnPromiseOfAny.js | 16 ++++++++-------- ...tCallExpressionSpecifierNotStringTypeError.js | 10 +++++----- .../importCallExpressionWithTypeArgument.js | 4 ++-- 30 files changed, 104 insertions(+), 104 deletions(-) diff --git a/tests/baselines/reference/importCallExpressionAsyncES6AMD.js b/tests/baselines/reference/importCallExpressionAsyncES6AMD.js index 9819da8369b..7f86625bbfc 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES6AMD.js +++ b/tests/baselines/reference/importCallExpressionAsyncES6AMD.js @@ -42,34 +42,34 @@ define(["require", "exports"], function (require, exports) { Object.defineProperty(exports, "__esModule", { value: true }); function fn() { return __awaiter(this, void 0, void 0, function* () { - const req = yield new Promise(function (resolve_1, reject_1) { require(['./test'], resolve_1, reject_1); }); // ONE + const req = yield new Promise((resolve_1, reject_1) => { require(['./test'], resolve_1, reject_1); }); // ONE }); } exports.fn = fn; class cl1 { m() { return __awaiter(this, void 0, void 0, function* () { - const req = yield new Promise(function (resolve_2, reject_2) { require(['./test'], resolve_2, reject_2); }); // TWO + const req = yield new Promise((resolve_2, reject_2) => { require(['./test'], resolve_2, reject_2); }); // TWO }); } } exports.cl1 = cl1; exports.obj = { m: () => __awaiter(this, void 0, void 0, function* () { - const req = yield new Promise(function (resolve_3, reject_3) { require(['./test'], resolve_3, reject_3); }); // THREE + const req = yield new Promise((resolve_3, reject_3) => { require(['./test'], resolve_3, reject_3); }); // THREE }) }; class cl2 { constructor() { this.p = { m: () => __awaiter(this, void 0, void 0, function* () { - const req = yield new Promise(function (resolve_4, reject_4) { require(['./test'], resolve_4, reject_4); }); // FOUR + const req = yield new Promise((resolve_4, reject_4) => { require(['./test'], resolve_4, reject_4); }); // FOUR }) }; } } exports.cl2 = cl2; exports.l = () => __awaiter(this, void 0, void 0, function* () { - const req = yield new Promise(function (resolve_5, reject_5) { require(['./test'], resolve_5, reject_5); }); // FIVE + const req = yield new Promise((resolve_5, reject_5) => { require(['./test'], resolve_5, reject_5); }); // FIVE }); }); diff --git a/tests/baselines/reference/importCallExpressionAsyncES6CJS.js b/tests/baselines/reference/importCallExpressionAsyncES6CJS.js index b512ae94b48..20961f96330 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES6CJS.js +++ b/tests/baselines/reference/importCallExpressionAsyncES6CJS.js @@ -41,33 +41,33 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge Object.defineProperty(exports, "__esModule", { value: true }); function fn() { return __awaiter(this, void 0, void 0, function* () { - const req = yield Promise.resolve().then(function () { return require('./test'); }); // ONE + const req = yield Promise.resolve().then(() => require('./test')); // ONE }); } exports.fn = fn; class cl1 { m() { return __awaiter(this, void 0, void 0, function* () { - const req = yield Promise.resolve().then(function () { return require('./test'); }); // TWO + const req = yield Promise.resolve().then(() => require('./test')); // TWO }); } } exports.cl1 = cl1; exports.obj = { m: () => __awaiter(this, void 0, void 0, function* () { - const req = yield Promise.resolve().then(function () { return require('./test'); }); // THREE + const req = yield Promise.resolve().then(() => require('./test')); // THREE }) }; class cl2 { constructor() { this.p = { m: () => __awaiter(this, void 0, void 0, function* () { - const req = yield Promise.resolve().then(function () { return require('./test'); }); // FOUR + const req = yield Promise.resolve().then(() => require('./test')); // FOUR }) }; } } exports.cl2 = cl2; exports.l = () => __awaiter(this, void 0, void 0, function* () { - const req = yield Promise.resolve().then(function () { return require('./test'); }); // FIVE + const req = yield Promise.resolve().then(() => require('./test')); // FIVE }); diff --git a/tests/baselines/reference/importCallExpressionAsyncES6UMD.js b/tests/baselines/reference/importCallExpressionAsyncES6UMD.js index f77d5150118..1d4aff02670 100644 --- a/tests/baselines/reference/importCallExpressionAsyncES6UMD.js +++ b/tests/baselines/reference/importCallExpressionAsyncES6UMD.js @@ -51,34 +51,34 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge Object.defineProperty(exports, "__esModule", { value: true }); function fn() { return __awaiter(this, void 0, void 0, function* () { - const req = yield __syncRequire ? Promise.resolve().then(function () { return require('./test'); }) : new Promise(function (resolve_1, reject_1) { require(['./test'], resolve_1, reject_1); }); // ONE + const req = yield __syncRequire ? Promise.resolve().then(() => require('./test')) : new Promise((resolve_1, reject_1) => { require(['./test'], resolve_1, reject_1); }); // ONE }); } exports.fn = fn; class cl1 { m() { return __awaiter(this, void 0, void 0, function* () { - const req = yield __syncRequire ? Promise.resolve().then(function () { return require('./test'); }) : new Promise(function (resolve_2, reject_2) { require(['./test'], resolve_2, reject_2); }); // TWO + const req = yield __syncRequire ? Promise.resolve().then(() => require('./test')) : new Promise((resolve_2, reject_2) => { require(['./test'], resolve_2, reject_2); }); // TWO }); } } exports.cl1 = cl1; exports.obj = { m: () => __awaiter(this, void 0, void 0, function* () { - const req = yield __syncRequire ? Promise.resolve().then(function () { return require('./test'); }) : new Promise(function (resolve_3, reject_3) { require(['./test'], resolve_3, reject_3); }); // THREE + const req = yield __syncRequire ? Promise.resolve().then(() => require('./test')) : new Promise((resolve_3, reject_3) => { require(['./test'], resolve_3, reject_3); }); // THREE }) }; class cl2 { constructor() { this.p = { m: () => __awaiter(this, void 0, void 0, function* () { - const req = yield __syncRequire ? Promise.resolve().then(function () { return require('./test'); }) : new Promise(function (resolve_4, reject_4) { require(['./test'], resolve_4, reject_4); }); // FOUR + const req = yield __syncRequire ? Promise.resolve().then(() => require('./test')) : new Promise((resolve_4, reject_4) => { require(['./test'], resolve_4, reject_4); }); // FOUR }) }; } } exports.cl2 = cl2; exports.l = () => __awaiter(this, void 0, void 0, function* () { - const req = yield __syncRequire ? Promise.resolve().then(function () { return require('./test'); }) : new Promise(function (resolve_5, reject_5) { require(['./test'], resolve_5, reject_5); }); // FIVE + const req = yield __syncRequire ? Promise.resolve().then(() => require('./test')) : new Promise((resolve_5, reject_5) => { require(['./test'], resolve_5, reject_5); }); // FIVE }); }); diff --git a/tests/baselines/reference/importCallExpressionCheckReturntype1.js b/tests/baselines/reference/importCallExpressionCheckReturntype1.js index facb6913388..3cc4893ff67 100644 --- a/tests/baselines/reference/importCallExpressionCheckReturntype1.js +++ b/tests/baselines/reference/importCallExpressionCheckReturntype1.js @@ -30,6 +30,6 @@ exports.C = C; //// [1.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -let p1 = Promise.resolve().then(function () { return require("./defaultPath"); }); -let p2 = Promise.resolve().then(function () { return require("./defaultPath"); }); -let p3 = Promise.resolve().then(function () { return require("./defaultPath"); }); +let p1 = Promise.resolve().then(() => require("./defaultPath")); +let p2 = Promise.resolve().then(() => require("./defaultPath")); +let p3 = Promise.resolve().then(() => require("./defaultPath")); diff --git a/tests/baselines/reference/importCallExpressionDeclarationEmit1.js b/tests/baselines/reference/importCallExpressionDeclarationEmit1.js index 07f95d3b3b2..721d85abe71 100644 --- a/tests/baselines/reference/importCallExpressionDeclarationEmit1.js +++ b/tests/baselines/reference/importCallExpressionDeclarationEmit1.js @@ -15,12 +15,12 @@ function returnDynamicLoad(path: string) { } //// [importCallExpressionDeclarationEmit1.js] -Promise.resolve().then(function () { return require(getSpecifier()); }); -var p0 = Promise.resolve().then(function () { return require(`${directory}\${moduleFile}`); }); -var p1 = Promise.resolve().then(function () { return require(getSpecifier()); }); -const p2 = Promise.resolve().then(function () { return require(whatToLoad ? getSpecifier() : "defaulPath"); }); +Promise.resolve().then(() => require(getSpecifier())); +var p0 = Promise.resolve().then(() => require(`${directory}\${moduleFile}`)); +var p1 = Promise.resolve().then(() => require(getSpecifier())); +const p2 = Promise.resolve().then(() => require(whatToLoad ? getSpecifier() : "defaulPath")); function returnDynamicLoad(path) { - return Promise.resolve().then(function () { return require(path); }); + return Promise.resolve().then(() => require(path)); } diff --git a/tests/baselines/reference/importCallExpressionES6AMD.js b/tests/baselines/reference/importCallExpressionES6AMD.js index 08fec3b27fd..1c5430c9f04 100644 --- a/tests/baselines/reference/importCallExpressionES6AMD.js +++ b/tests/baselines/reference/importCallExpressionES6AMD.js @@ -39,23 +39,23 @@ define(["require", "exports"], function (require, exports) { define(["require", "exports"], function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); - new Promise(function (resolve_1, reject_1) { require(["./0"], resolve_1, reject_1); }); - var p1 = new Promise(function (resolve_2, reject_2) { require(["./0"], resolve_2, reject_2); }); + new Promise((resolve_1, reject_1) => { require(["./0"], resolve_1, reject_1); }); + var p1 = new Promise((resolve_2, reject_2) => { require(["./0"], resolve_2, reject_2); }); p1.then(zero => { return zero.foo(); }); - exports.p2 = new Promise(function (resolve_3, reject_3) { require(["./0"], resolve_3, reject_3); }); + exports.p2 = new Promise((resolve_3, reject_3) => { require(["./0"], resolve_3, reject_3); }); function foo() { - const p2 = new Promise(function (resolve_4, reject_4) { require(["./0"], resolve_4, reject_4); }); + const p2 = new Promise((resolve_4, reject_4) => { require(["./0"], resolve_4, reject_4); }); } class C { method() { - const loadAsync = new Promise(function (resolve_5, reject_5) { require(["./0"], resolve_5, reject_5); }); + const loadAsync = new Promise((resolve_5, reject_5) => { require(["./0"], resolve_5, reject_5); }); } } class D { method() { - const loadAsync = new Promise(function (resolve_6, reject_6) { require(["./0"], resolve_6, reject_6); }); + const loadAsync = new Promise((resolve_6, reject_6) => { require(["./0"], resolve_6, reject_6); }); } } exports.D = D; diff --git a/tests/baselines/reference/importCallExpressionES6CJS.js b/tests/baselines/reference/importCallExpressionES6CJS.js index 28833e17479..a1d8108bdea 100644 --- a/tests/baselines/reference/importCallExpressionES6CJS.js +++ b/tests/baselines/reference/importCallExpressionES6CJS.js @@ -36,23 +36,23 @@ exports.foo = foo; //// [1.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -Promise.resolve().then(function () { return require("./0"); }); -var p1 = Promise.resolve().then(function () { return require("./0"); }); +Promise.resolve().then(() => require("./0")); +var p1 = Promise.resolve().then(() => require("./0")); p1.then(zero => { return zero.foo(); }); -exports.p2 = Promise.resolve().then(function () { return require("./0"); }); +exports.p2 = Promise.resolve().then(() => require("./0")); function foo() { - const p2 = Promise.resolve().then(function () { return require("./0"); }); + const p2 = Promise.resolve().then(() => require("./0")); } class C { method() { - const loadAsync = Promise.resolve().then(function () { return require("./0"); }); + const loadAsync = Promise.resolve().then(() => require("./0")); } } class D { method() { - const loadAsync = Promise.resolve().then(function () { return require("./0"); }); + const loadAsync = Promise.resolve().then(() => require("./0")); } } exports.D = D; diff --git a/tests/baselines/reference/importCallExpressionES6UMD.js b/tests/baselines/reference/importCallExpressionES6UMD.js index cc7dfef0074..750a1a7cc0c 100644 --- a/tests/baselines/reference/importCallExpressionES6UMD.js +++ b/tests/baselines/reference/importCallExpressionES6UMD.js @@ -56,23 +56,23 @@ export class D { "use strict"; var __syncRequire = typeof module === "object" && typeof module.exports === "object"; Object.defineProperty(exports, "__esModule", { value: true }); - __syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_1, reject_1) { require(["./0"], resolve_1, reject_1); }); - var p1 = __syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_2, reject_2) { require(["./0"], resolve_2, reject_2); }); + __syncRequire ? Promise.resolve().then(() => require("./0")) : new Promise((resolve_1, reject_1) => { require(["./0"], resolve_1, reject_1); }); + var p1 = __syncRequire ? Promise.resolve().then(() => require("./0")) : new Promise((resolve_2, reject_2) => { require(["./0"], resolve_2, reject_2); }); p1.then(zero => { return zero.foo(); }); - exports.p2 = __syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_3, reject_3) { require(["./0"], resolve_3, reject_3); }); + exports.p2 = __syncRequire ? Promise.resolve().then(() => require("./0")) : new Promise((resolve_3, reject_3) => { require(["./0"], resolve_3, reject_3); }); function foo() { - const p2 = __syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_4, reject_4) { require(["./0"], resolve_4, reject_4); }); + const p2 = __syncRequire ? Promise.resolve().then(() => require("./0")) : new Promise((resolve_4, reject_4) => { require(["./0"], resolve_4, reject_4); }); } class C { method() { - const loadAsync = __syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_5, reject_5) { require(["./0"], resolve_5, reject_5); }); + const loadAsync = __syncRequire ? Promise.resolve().then(() => require("./0")) : new Promise((resolve_5, reject_5) => { require(["./0"], resolve_5, reject_5); }); } } class D { method() { - const loadAsync = __syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_6, reject_6) { require(["./0"], resolve_6, reject_6); }); + const loadAsync = __syncRequire ? Promise.resolve().then(() => require("./0")) : new Promise((resolve_6, reject_6) => { require(["./0"], resolve_6, reject_6); }); } } exports.D = D; diff --git a/tests/baselines/reference/importCallExpressionGrammarError.js b/tests/baselines/reference/importCallExpressionGrammarError.js index b30b0c9ddd5..e2ffc55577d 100644 --- a/tests/baselines/reference/importCallExpressionGrammarError.js +++ b/tests/baselines/reference/importCallExpressionGrammarError.js @@ -12,8 +12,8 @@ const p4 = import("pathToModule", "secondModule"); //// [importCallExpressionGrammarError.js] var a = ["./0"]; -Promise.resolve().then(function () { return require(...["PathModule"]); }); -var p1 = Promise.resolve().then(function () { return require(...a); }); -const p2 = Promise.resolve().then(function () { return require(); }); -const p3 = Promise.resolve().then(function () { return require(); }); -const p4 = Promise.resolve().then(function () { return require("pathToModule", "secondModule"); }); +Promise.resolve().then(() => require(...["PathModule"])); +var p1 = Promise.resolve().then(() => require(...a)); +const p2 = Promise.resolve().then(() => require()); +const p3 = Promise.resolve().then(() => require()); +const p4 = Promise.resolve().then(() => require("pathToModule", "secondModule")); diff --git a/tests/baselines/reference/importCallExpressionInAMD1.js b/tests/baselines/reference/importCallExpressionInAMD1.js index 5c858160353..64e5aee2dda 100644 --- a/tests/baselines/reference/importCallExpressionInAMD1.js +++ b/tests/baselines/reference/importCallExpressionInAMD1.js @@ -27,13 +27,13 @@ define(["require", "exports"], function (require, exports) { define(["require", "exports"], function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); - new Promise(function (resolve_1, reject_1) { require(["./0"], resolve_1, reject_1); }); - var p1 = new Promise(function (resolve_2, reject_2) { require(["./0"], resolve_2, reject_2); }); + new Promise((resolve_1, reject_1) => { require(["./0"], resolve_1, reject_1); }); + var p1 = new Promise((resolve_2, reject_2) => { require(["./0"], resolve_2, reject_2); }); p1.then(zero => { return zero.foo(); }); - exports.p2 = new Promise(function (resolve_3, reject_3) { require(["./0"], resolve_3, reject_3); }); + exports.p2 = new Promise((resolve_3, reject_3) => { require(["./0"], resolve_3, reject_3); }); function foo() { - const p2 = new Promise(function (resolve_4, reject_4) { require(["./0"], resolve_4, reject_4); }); + const p2 = new Promise((resolve_4, reject_4) => { require(["./0"], resolve_4, reject_4); }); } }); diff --git a/tests/baselines/reference/importCallExpressionInAMD2.js b/tests/baselines/reference/importCallExpressionInAMD2.js index 7347e2f8105..0d3f0e08d21 100644 --- a/tests/baselines/reference/importCallExpressionInAMD2.js +++ b/tests/baselines/reference/importCallExpressionInAMD2.js @@ -35,5 +35,5 @@ define(["require", "exports"], function (require, exports) { b.print(); }); } - foo(new Promise(function (resolve_1, reject_1) { require(["./0"], resolve_1, reject_1); })); + foo(new Promise((resolve_1, reject_1) => { require(["./0"], resolve_1, reject_1); })); }); diff --git a/tests/baselines/reference/importCallExpressionInAMD3.js b/tests/baselines/reference/importCallExpressionInAMD3.js index 471f35a6415..07e7e922541 100644 --- a/tests/baselines/reference/importCallExpressionInAMD3.js +++ b/tests/baselines/reference/importCallExpressionInAMD3.js @@ -26,7 +26,7 @@ define(["require", "exports"], function (require, exports) { define(["require", "exports"], function (require, exports) { "use strict"; async function foo() { - class C extends (await new Promise(function (resolve_1, reject_1) { require(["./0"], resolve_1, reject_1); })).B { + class C extends (await new Promise((resolve_1, reject_1) => { require(["./0"], resolve_1, reject_1); })).B { } var c = new C(); c.print(); diff --git a/tests/baselines/reference/importCallExpressionInAMD4.js b/tests/baselines/reference/importCallExpressionInAMD4.js index 43ba5afcd30..2fe29e5ae06 100644 --- a/tests/baselines/reference/importCallExpressionInAMD4.js +++ b/tests/baselines/reference/importCallExpressionInAMD4.js @@ -64,30 +64,30 @@ define(["require", "exports"], function (require, exports) { Object.defineProperty(exports, "__esModule", { value: true }); class C { constructor() { - this.myModule = new Promise(function (resolve_1, reject_1) { require(["./0"], resolve_1, reject_1); }); + this.myModule = new Promise((resolve_1, reject_1) => { require(["./0"], resolve_1, reject_1); }); } method() { - const loadAsync = new Promise(function (resolve_2, reject_2) { require(["./0"], resolve_2, reject_2); }); + const loadAsync = new Promise((resolve_2, reject_2) => { require(["./0"], resolve_2, reject_2); }); this.myModule.then(Zero => { console.log(Zero.foo()); }, async (err) => { console.log(err); - let one = await new Promise(function (resolve_3, reject_3) { require(["./1"], resolve_3, reject_3); }); + let one = await new Promise((resolve_3, reject_3) => { require(["./1"], resolve_3, reject_3); }); console.log(one.backup()); }); } } class D { constructor() { - this.myModule = new Promise(function (resolve_4, reject_4) { require(["./0"], resolve_4, reject_4); }); + this.myModule = new Promise((resolve_4, reject_4) => { require(["./0"], resolve_4, reject_4); }); } method() { - const loadAsync = new Promise(function (resolve_5, reject_5) { require(["./0"], resolve_5, reject_5); }); + const loadAsync = new Promise((resolve_5, reject_5) => { require(["./0"], resolve_5, reject_5); }); this.myModule.then(Zero => { console.log(Zero.foo()); }, async (err) => { console.log(err); - let one = await new Promise(function (resolve_6, reject_6) { require(["./1"], resolve_6, reject_6); }); + let one = await new Promise((resolve_6, reject_6) => { require(["./1"], resolve_6, reject_6); }); console.log(one.backup()); }); } diff --git a/tests/baselines/reference/importCallExpressionInCJS1.js b/tests/baselines/reference/importCallExpressionInCJS1.js index 359e743144b..c814f5e5671 100644 --- a/tests/baselines/reference/importCallExpressionInCJS1.js +++ b/tests/baselines/reference/importCallExpressionInCJS1.js @@ -24,12 +24,12 @@ exports.foo = foo; //// [1.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -Promise.resolve().then(function () { return require("./0"); }); -var p1 = Promise.resolve().then(function () { return require("./0"); }); +Promise.resolve().then(() => require("./0")); +var p1 = Promise.resolve().then(() => require("./0")); p1.then(zero => { return zero.foo(); }); -exports.p2 = Promise.resolve().then(function () { return require("./0"); }); +exports.p2 = Promise.resolve().then(() => require("./0")); function foo() { - const p2 = Promise.resolve().then(function () { return require("./0"); }); + const p2 = Promise.resolve().then(() => require("./0")); } diff --git a/tests/baselines/reference/importCallExpressionInCJS2.js b/tests/baselines/reference/importCallExpressionInCJS2.js index aa983a7a2fe..fb559cb1193 100644 --- a/tests/baselines/reference/importCallExpressionInCJS2.js +++ b/tests/baselines/reference/importCallExpressionInCJS2.js @@ -32,9 +32,9 @@ exports.backup = backup; async function compute(promise) { let j = await promise; if (!j) { - j = await Promise.resolve().then(function () { return require("./1"); }); + j = await Promise.resolve().then(() => require("./1")); return j.backup(); } return j.foo(); } -compute(Promise.resolve().then(function () { return require("./0"); })); +compute(Promise.resolve().then(() => require("./0"))); diff --git a/tests/baselines/reference/importCallExpressionInCJS3.js b/tests/baselines/reference/importCallExpressionInCJS3.js index 2f956d9ac3a..616fbc9c3f9 100644 --- a/tests/baselines/reference/importCallExpressionInCJS3.js +++ b/tests/baselines/reference/importCallExpressionInCJS3.js @@ -31,4 +31,4 @@ function foo(x) { b.print(); }); } -foo(Promise.resolve().then(function () { return require("./0"); })); +foo(Promise.resolve().then(() => require("./0"))); diff --git a/tests/baselines/reference/importCallExpressionInCJS4.js b/tests/baselines/reference/importCallExpressionInCJS4.js index 554a0b222ab..b88295110b8 100644 --- a/tests/baselines/reference/importCallExpressionInCJS4.js +++ b/tests/baselines/reference/importCallExpressionInCJS4.js @@ -22,7 +22,7 @@ class B { exports.B = B; //// [2.js] async function foo() { - class C extends (await Promise.resolve().then(function () { return require("./0"); })).B { + class C extends (await Promise.resolve().then(() => require("./0"))).B { } var c = new C(); c.print(); diff --git a/tests/baselines/reference/importCallExpressionInCJS5.js b/tests/baselines/reference/importCallExpressionInCJS5.js index eeb4db275fa..b32b0e52c50 100644 --- a/tests/baselines/reference/importCallExpressionInCJS5.js +++ b/tests/baselines/reference/importCallExpressionInCJS5.js @@ -59,30 +59,30 @@ exports.backup = backup; Object.defineProperty(exports, "__esModule", { value: true }); class C { constructor() { - this.myModule = Promise.resolve().then(function () { return require("./0"); }); + this.myModule = Promise.resolve().then(() => require("./0")); } method() { - const loadAsync = Promise.resolve().then(function () { return require("./0"); }); + const loadAsync = Promise.resolve().then(() => require("./0")); this.myModule.then(Zero => { console.log(Zero.foo()); }, async (err) => { console.log(err); - let one = await Promise.resolve().then(function () { return require("./1"); }); + let one = await Promise.resolve().then(() => require("./1")); console.log(one.backup()); }); } } class D { constructor() { - this.myModule = Promise.resolve().then(function () { return require("./0"); }); + this.myModule = Promise.resolve().then(() => require("./0")); } method() { - const loadAsync = Promise.resolve().then(function () { return require("./0"); }); + const loadAsync = Promise.resolve().then(() => require("./0")); this.myModule.then(Zero => { console.log(Zero.foo()); }, async (err) => { console.log(err); - let one = await Promise.resolve().then(function () { return require("./1"); }); + let one = await Promise.resolve().then(() => require("./1")); console.log(one.backup()); }); } diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsAMD.js b/tests/baselines/reference/importCallExpressionInExportEqualsAMD.js index f2fda1fadd7..1fcef2bde39 100644 --- a/tests/baselines/reference/importCallExpressionInExportEqualsAMD.js +++ b/tests/baselines/reference/importCallExpressionInExportEqualsAMD.js @@ -17,6 +17,6 @@ define(["require", "exports"], function (require, exports) { define(["require", "exports"], function (require, exports) { "use strict"; return async function () { - const something = await new Promise(function (resolve_1, reject_1) { require(["./something"], resolve_1, reject_1); }); + const something = await new Promise((resolve_1, reject_1) => { require(["./something"], resolve_1, reject_1); }); }; }); diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsCJS.js b/tests/baselines/reference/importCallExpressionInExportEqualsCJS.js index 5d7e2816116..72e3a0ec0af 100644 --- a/tests/baselines/reference/importCallExpressionInExportEqualsCJS.js +++ b/tests/baselines/reference/importCallExpressionInExportEqualsCJS.js @@ -14,5 +14,5 @@ module.exports = 42; //// [index.js] "use strict"; module.exports = async function () { - const something = await Promise.resolve().then(function () { return require("./something"); }); + const something = await Promise.resolve().then(() => require("./something")); }; diff --git a/tests/baselines/reference/importCallExpressionInExportEqualsUMD.js b/tests/baselines/reference/importCallExpressionInExportEqualsUMD.js index e0c6e2a925f..5f70891b09e 100644 --- a/tests/baselines/reference/importCallExpressionInExportEqualsUMD.js +++ b/tests/baselines/reference/importCallExpressionInExportEqualsUMD.js @@ -34,6 +34,6 @@ export = async function() { "use strict"; var __syncRequire = typeof module === "object" && typeof module.exports === "object"; return async function () { - const something = await (__syncRequire ? Promise.resolve().then(function () { return require("./something"); }) : new Promise(function (resolve_1, reject_1) { require(["./something"], resolve_1, reject_1); })); + const something = await (__syncRequire ? Promise.resolve().then(() => require("./something")) : new Promise((resolve_1, reject_1) => { require(["./something"], resolve_1, reject_1); })); }; }); diff --git a/tests/baselines/reference/importCallExpressionInScriptContext1.js b/tests/baselines/reference/importCallExpressionInScriptContext1.js index 2c2d2f904d5..53c6118f61b 100644 --- a/tests/baselines/reference/importCallExpressionInScriptContext1.js +++ b/tests/baselines/reference/importCallExpressionInScriptContext1.js @@ -13,5 +13,5 @@ Object.defineProperty(exports, "__esModule", { value: true }); function foo() { return "foo"; } exports.foo = foo; //// [1.js] -var p1 = Promise.resolve().then(function () { return require("./0"); }); +var p1 = Promise.resolve().then(() => require("./0")); function arguments() { } // this is allow as the file doesn't have implicit "use strict" diff --git a/tests/baselines/reference/importCallExpressionInScriptContext2.js b/tests/baselines/reference/importCallExpressionInScriptContext2.js index 6b6e0109fda..4a0d4a1bf5a 100644 --- a/tests/baselines/reference/importCallExpressionInScriptContext2.js +++ b/tests/baselines/reference/importCallExpressionInScriptContext2.js @@ -15,5 +15,5 @@ function foo() { return "foo"; } exports.foo = foo; //// [1.js] "use strict"; -var p1 = Promise.resolve().then(function () { return require("./0"); }); +var p1 = Promise.resolve().then(() => require("./0")); function arguments() { } diff --git a/tests/baselines/reference/importCallExpressionInUMD1.js b/tests/baselines/reference/importCallExpressionInUMD1.js index ee99468f7f3..597e68e2d6f 100644 --- a/tests/baselines/reference/importCallExpressionInUMD1.js +++ b/tests/baselines/reference/importCallExpressionInUMD1.js @@ -44,13 +44,13 @@ function foo() { "use strict"; var __syncRequire = typeof module === "object" && typeof module.exports === "object"; Object.defineProperty(exports, "__esModule", { value: true }); - __syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_1, reject_1) { require(["./0"], resolve_1, reject_1); }); - var p1 = __syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_2, reject_2) { require(["./0"], resolve_2, reject_2); }); + __syncRequire ? Promise.resolve().then(() => require("./0")) : new Promise((resolve_1, reject_1) => { require(["./0"], resolve_1, reject_1); }); + var p1 = __syncRequire ? Promise.resolve().then(() => require("./0")) : new Promise((resolve_2, reject_2) => { require(["./0"], resolve_2, reject_2); }); p1.then(zero => { return zero.foo(); }); - exports.p2 = __syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_3, reject_3) { require(["./0"], resolve_3, reject_3); }); + exports.p2 = __syncRequire ? Promise.resolve().then(() => require("./0")) : new Promise((resolve_3, reject_3) => { require(["./0"], resolve_3, reject_3); }); function foo() { - const p2 = __syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_4, reject_4) { require(["./0"], resolve_4, reject_4); }); + const p2 = __syncRequire ? Promise.resolve().then(() => require("./0")) : new Promise((resolve_4, reject_4) => { require(["./0"], resolve_4, reject_4); }); } }); diff --git a/tests/baselines/reference/importCallExpressionInUMD2.js b/tests/baselines/reference/importCallExpressionInUMD2.js index db8b87a2f79..516800968c1 100644 --- a/tests/baselines/reference/importCallExpressionInUMD2.js +++ b/tests/baselines/reference/importCallExpressionInUMD2.js @@ -52,5 +52,5 @@ foo(import("./0")); b.print(); }); } - foo(__syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_1, reject_1) { require(["./0"], resolve_1, reject_1); })); + foo(__syncRequire ? Promise.resolve().then(() => require("./0")) : new Promise((resolve_1, reject_1) => { require(["./0"], resolve_1, reject_1); })); }); diff --git a/tests/baselines/reference/importCallExpressionInUMD3.js b/tests/baselines/reference/importCallExpressionInUMD3.js index 41106e3ab78..57d200ca70c 100644 --- a/tests/baselines/reference/importCallExpressionInUMD3.js +++ b/tests/baselines/reference/importCallExpressionInUMD3.js @@ -43,7 +43,7 @@ foo(); "use strict"; var __syncRequire = typeof module === "object" && typeof module.exports === "object"; async function foo() { - class C extends (await (__syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_1, reject_1) { require(["./0"], resolve_1, reject_1); }))).B { + class C extends (await (__syncRequire ? Promise.resolve().then(() => require("./0")) : new Promise((resolve_1, reject_1) => { require(["./0"], resolve_1, reject_1); }))).B { } var c = new C(); c.print(); diff --git a/tests/baselines/reference/importCallExpressionInUMD4.js b/tests/baselines/reference/importCallExpressionInUMD4.js index 477a7826bc0..70a574f0302 100644 --- a/tests/baselines/reference/importCallExpressionInUMD4.js +++ b/tests/baselines/reference/importCallExpressionInUMD4.js @@ -89,30 +89,30 @@ export class D { Object.defineProperty(exports, "__esModule", { value: true }); class C { constructor() { - this.myModule = __syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_1, reject_1) { require(["./0"], resolve_1, reject_1); }); + this.myModule = __syncRequire ? Promise.resolve().then(() => require("./0")) : new Promise((resolve_1, reject_1) => { require(["./0"], resolve_1, reject_1); }); } method() { - const loadAsync = __syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_2, reject_2) { require(["./0"], resolve_2, reject_2); }); + const loadAsync = __syncRequire ? Promise.resolve().then(() => require("./0")) : new Promise((resolve_2, reject_2) => { require(["./0"], resolve_2, reject_2); }); this.myModule.then(Zero => { console.log(Zero.foo()); }, async (err) => { console.log(err); - let one = await (__syncRequire ? Promise.resolve().then(function () { return require("./1"); }) : new Promise(function (resolve_3, reject_3) { require(["./1"], resolve_3, reject_3); })); + let one = await (__syncRequire ? Promise.resolve().then(() => require("./1")) : new Promise((resolve_3, reject_3) => { require(["./1"], resolve_3, reject_3); })); console.log(one.backup()); }); } } class D { constructor() { - this.myModule = __syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_4, reject_4) { require(["./0"], resolve_4, reject_4); }); + this.myModule = __syncRequire ? Promise.resolve().then(() => require("./0")) : new Promise((resolve_4, reject_4) => { require(["./0"], resolve_4, reject_4); }); } method() { - const loadAsync = __syncRequire ? Promise.resolve().then(function () { return require("./0"); }) : new Promise(function (resolve_5, reject_5) { require(["./0"], resolve_5, reject_5); }); + const loadAsync = __syncRequire ? Promise.resolve().then(() => require("./0")) : new Promise((resolve_5, reject_5) => { require(["./0"], resolve_5, reject_5); }); this.myModule.then(Zero => { console.log(Zero.foo()); }, async (err) => { console.log(err); - let one = await (__syncRequire ? Promise.resolve().then(function () { return require("./1"); }) : new Promise(function (resolve_6, reject_6) { require(["./1"], resolve_6, reject_6); })); + let one = await (__syncRequire ? Promise.resolve().then(() => require("./1")) : new Promise((resolve_6, reject_6) => { require(["./1"], resolve_6, reject_6); })); console.log(one.backup()); }); } diff --git a/tests/baselines/reference/importCallExpressionReturnPromiseOfAny.js b/tests/baselines/reference/importCallExpressionReturnPromiseOfAny.js index 728d6636953..8c94510b609 100644 --- a/tests/baselines/reference/importCallExpressionReturnPromiseOfAny.js +++ b/tests/baselines/reference/importCallExpressionReturnPromiseOfAny.js @@ -42,20 +42,20 @@ exports.C = C; //// [1.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -Promise.resolve().then(function () { return require(`${directory}\${moduleFile}`); }); -Promise.resolve().then(function () { return require(getSpecifier()); }); -var p1 = Promise.resolve().then(function () { return require(ValidSomeCondition() ? "./0" : "externalModule"); }); -var p1 = Promise.resolve().then(function () { return require(getSpecifier()); }); -var p11 = Promise.resolve().then(function () { return require(getSpecifier()); }); -const p2 = Promise.resolve().then(function () { return require(whatToLoad ? getSpecifier() : "defaulPath"); }); +Promise.resolve().then(() => require(`${directory}\${moduleFile}`)); +Promise.resolve().then(() => require(getSpecifier())); +var p1 = Promise.resolve().then(() => require(ValidSomeCondition() ? "./0" : "externalModule")); +var p1 = Promise.resolve().then(() => require(getSpecifier())); +var p11 = Promise.resolve().then(() => require(getSpecifier())); +const p2 = Promise.resolve().then(() => require(whatToLoad ? getSpecifier() : "defaulPath")); p1.then(zero => { return zero.foo(); // ok, zero is any }); let j; -var p3 = Promise.resolve().then(function () { return require(j = getSpecifier()); }); +var p3 = Promise.resolve().then(() => require(j = getSpecifier())); function* loadModule(directories) { for (const directory of directories) { const path = `${directory}\moduleFile`; - Promise.resolve().then(function () { return require(yield path); }); + Promise.resolve().then(() => require(yield path)); } } diff --git a/tests/baselines/reference/importCallExpressionSpecifierNotStringTypeError.js b/tests/baselines/reference/importCallExpressionSpecifierNotStringTypeError.js index dde35d8048b..5e2ace1c401 100644 --- a/tests/baselines/reference/importCallExpressionSpecifierNotStringTypeError.js +++ b/tests/baselines/reference/importCallExpressionSpecifierNotStringTypeError.js @@ -15,11 +15,11 @@ var p4 = import(()=>"PathToModule"); //// [importCallExpressionSpecifierNotStringTypeError.js] // Error specifier is not assignable to string -Promise.resolve().then(function () { return require(getSpecifier()); }); -var p1 = Promise.resolve().then(function () { return require(getSpecifier()); }); -const p2 = Promise.resolve().then(function () { return require(whatToLoad ? getSpecifier() : "defaulPath"); }); +Promise.resolve().then(() => require(getSpecifier())); +var p1 = Promise.resolve().then(() => require(getSpecifier())); +const p2 = Promise.resolve().then(() => require(whatToLoad ? getSpecifier() : "defaulPath")); p1.then(zero => { return zero.foo(); // ok, zero is any }); -var p3 = Promise.resolve().then(function () { return require(["path1", "path2"]); }); -var p4 = Promise.resolve().then(function () { return require(() => "PathToModule"); }); +var p3 = Promise.resolve().then(() => require(["path1", "path2"])); +var p4 = Promise.resolve().then(() => require(() => "PathToModule")); diff --git a/tests/baselines/reference/importCallExpressionWithTypeArgument.js b/tests/baselines/reference/importCallExpressionWithTypeArgument.js index 2915669eae5..885992a798b 100644 --- a/tests/baselines/reference/importCallExpressionWithTypeArgument.js +++ b/tests/baselines/reference/importCallExpressionWithTypeArgument.js @@ -15,5 +15,5 @@ function foo() { return "foo"; } exports.foo = foo; //// [1.js] "use strict"; -var p1 = Promise.resolve().then(function () { return require("./0"); }); // error -var p2 = Promise.resolve().then(function () { return require("./0"); }); // error +var p1 = Promise.resolve().then(() => require("./0")); // error +var p2 = Promise.resolve().then(() => require("./0")); // error From 3eeb54861d310a37518e81642bee77120c097e00 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 10 Oct 2017 10:53:43 -0700 Subject: [PATCH 057/312] Fix invalid cast (#18821) --- src/compiler/binder.ts | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 48cace44841..4cacb5765db 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2271,16 +2271,13 @@ namespace ts { function isExportsOrModuleExportsOrAlias(node: Node): boolean { return isExportsIdentifier(node) || isModuleExportsPropertyAccessExpression(node) || - isNameOfExportsOrModuleExportsAliasDeclaration(node); + isIdentifier(node) && isNameOfExportsOrModuleExportsAliasDeclaration(node); } - function isNameOfExportsOrModuleExportsAliasDeclaration(node: Node) { - if (isIdentifier(node)) { - const symbol = lookupSymbolForName(node.escapedText); - return symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) && - symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(symbol.valueDeclaration.initializer); - } - return false; + function isNameOfExportsOrModuleExportsAliasDeclaration(node: Identifier): boolean { + const symbol = lookupSymbolForName(node.escapedText); + return symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) && + symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(symbol.valueDeclaration.initializer); } function isExportsOrModuleExportsOrAliasOrAssignment(node: Node): boolean { @@ -2354,20 +2351,22 @@ namespace ts { // Look up the function in the local scope, since prototype assignments should // follow the function declaration const leftSideOfAssignment = node.left as PropertyAccessExpression; - const target = leftSideOfAssignment.expression as Identifier; + const target = leftSideOfAssignment.expression; - // Fix up parent pointers since we're going to use these nodes before we bind into them - leftSideOfAssignment.parent = node; - target.parent = leftSideOfAssignment; + if (isIdentifier(target)) { + // Fix up parent pointers since we're going to use these nodes before we bind into them + leftSideOfAssignment.parent = node; + target.parent = leftSideOfAssignment; - if (isNameOfExportsOrModuleExportsAliasDeclaration(target)) { - // This can be an alias for the 'exports' or 'module.exports' names, e.g. - // var util = module.exports; - // util.property = function ... - bindExportsPropertyAssignment(node); - } - else { - bindPropertyAssignment(target.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ false); + if (isNameOfExportsOrModuleExportsAliasDeclaration(target)) { + // This can be an alias for the 'exports' or 'module.exports' names, e.g. + // var util = module.exports; + // util.property = function ... + bindExportsPropertyAssignment(node); + } + else { + bindPropertyAssignment(target.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ false); + } } } From 9ccc1b48873bb2cd1e1a0cf9eabc0232c26c200d Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 10 Oct 2017 10:54:29 -0700 Subject: [PATCH 058/312] Remove unnecessary uses of `any` in shims.ts (#19038) --- src/services/shims.ts | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/services/shims.ts b/src/services/shims.ts index 737db44b83f..9d4baccc3c4 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -16,7 +16,7 @@ /// /* @internal */ -let debugObjectHost = (function (this: any) { return this; })(); +let debugObjectHost: { CollectGarbage(): void } = (function (this: any) { return this; })(); // We need to use 'null' to interface with the managed side. /* tslint:disable:no-null-keyword */ @@ -119,13 +119,13 @@ namespace ts { } export interface Shim { - dispose(_dummy: any): void; + dispose(_dummy: {}): void; } export interface LanguageServiceShim extends Shim { languageService: LanguageService; - dispose(_dummy: any): void; + dispose(_dummy: {}): void; refresh(throwOnError: boolean): void; @@ -417,7 +417,7 @@ namespace ts { return this.shimHost.getScriptVersion(fileName); } - public getLocalizedDiagnosticMessages(): any { + public getLocalizedDiagnosticMessages() { const diagnosticMessagesJson = this.shimHost.getLocalizedDiagnosticMessages(); if (diagnosticMessagesJson === null || diagnosticMessagesJson === "") { return null; @@ -515,7 +515,7 @@ namespace ts { } } - function simpleForwardCall(logger: Logger, actionDescription: string, action: () => any, logPerformance: boolean): any { + function simpleForwardCall(logger: Logger, actionDescription: string, action: () => {}, logPerformance: boolean): {} { let start: number; if (logPerformance) { logger.log(actionDescription); @@ -539,14 +539,14 @@ namespace ts { return result; } - function forwardJSONCall(logger: Logger, actionDescription: string, action: () => any, logPerformance: boolean): string { + function forwardJSONCall(logger: Logger, actionDescription: string, action: () => {}, logPerformance: boolean): string { return forwardCall(logger, actionDescription, /*returnJson*/ true, action, logPerformance); } function forwardCall(logger: Logger, actionDescription: string, returnJson: boolean, action: () => T, logPerformance: boolean): T | string { try { const result = simpleForwardCall(logger, actionDescription, action, logPerformance); - return returnJson ? JSON.stringify({ result }) : result; + return returnJson ? JSON.stringify({ result }) : result as T; } catch (err) { if (err instanceof OperationCanceledException) { @@ -563,7 +563,7 @@ namespace ts { constructor(private factory: ShimFactory) { factory.registerShim(this); } - public dispose(_dummy: any): void { + public dispose(_dummy: {}): void { this.factory.unregisterShim(this); } } @@ -601,7 +601,7 @@ namespace ts { this.logger = this.host; } - public forwardJSONCall(actionDescription: string, action: () => any): string { + public forwardJSONCall(actionDescription: string, action: () => {}): string { return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance); } @@ -611,7 +611,7 @@ namespace ts { * Ensure (almost) deterministic release of internal Javascript resources when * some external native objects holds onto us (e.g. Com/Interop). */ - public dispose(dummy: any): void { + public dispose(dummy: {}): void { this.logger.log("dispose()"); this.languageService.dispose(); this.languageService = null; @@ -635,7 +635,7 @@ namespace ts { public refresh(throwOnError: boolean): void { this.forwardJSONCall( `refresh(${throwOnError})`, - () => null + () => null ); } @@ -644,7 +644,7 @@ namespace ts { "cleanupSemanticCache()", () => { this.languageService.cleanupSemanticCache(); - return null; + return null; }); } @@ -980,13 +980,13 @@ namespace ts { ); } - public getEmitOutputObject(fileName: string): any { + public getEmitOutputObject(fileName: string): EmitOutput { return forwardCall( this.logger, `getEmitOutput('${fileName}')`, /*returnJson*/ false, () => this.languageService.getEmitOutput(fileName), - this.logPerformance); + this.logPerformance) as EmitOutput; } } @@ -1030,7 +1030,7 @@ namespace ts { super(factory); } - private forwardJSONCall(actionDescription: string, action: () => any): any { + private forwardJSONCall(actionDescription: string, action: () => {}): string { return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance); } @@ -1221,7 +1221,7 @@ namespace ts { // Here we expose the TypeScript services as an external module // so that it may be consumed easily like a node module. - declare const module: any; + declare const module: { exports: {} }; if (typeof module !== "undefined" && module.exports) { module.exports = ts; } From 3171d082a6c126a0930e3b94cb2f791e2d059069 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 10 Oct 2017 10:52:29 -0700 Subject: [PATCH 059/312] Handle the case of completion of class member when member name is being edited Fixes #17977 --- src/services/completions.ts | 5 +++ .../completionEntryForClassMembers3.ts | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 tests/cases/fourslash/completionEntryForClassMembers3.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index 44ad611de79..c2224256937 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1195,6 +1195,11 @@ namespace ts.Completions { if (isClassLike(location)) { return location; } + // class c { method() { } b| } + if (isFromClassElementDeclaration(location) && + (location.parent as ClassElement).name === location) { + return location.parent.parent as ClassLikeDeclaration; + } break; default: diff --git a/tests/cases/fourslash/completionEntryForClassMembers3.ts b/tests/cases/fourslash/completionEntryForClassMembers3.ts new file mode 100644 index 00000000000..a27c5959e6d --- /dev/null +++ b/tests/cases/fourslash/completionEntryForClassMembers3.ts @@ -0,0 +1,32 @@ +/// + +////interface IFoo { +//// bar(): void; +////} +////class Foo1 implements IFoo { +//// zap() { } +//// /*1*/ +////} +////class Foo2 implements IFoo { +//// zap() { } +//// b/*2*/() { } +////} +////class Foo3 implements IFoo { +//// zap() { } +//// b/*3*/: any; +////} +const allowedKeywordCount = verify.allowedClassElementKeywords.length; +function verifyHasBar() { + verify.completionListContains("bar", "(method) IFoo.bar(): void", /*documentation*/ undefined, "method"); + verify.completionListContainsClassElementKeywords(); + verify.completionListCount(allowedKeywordCount + 1); +} + +goTo.marker("1"); +verifyHasBar(); +edit.insert("b"); +verifyHasBar(); +goTo.marker("2"); +verifyHasBar(); +goTo.marker("3"); +verifyHasBar(); \ No newline at end of file From b839e17e178d27e4ffbc97121246c14d1f07149a Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 10 Oct 2017 11:27:53 -0700 Subject: [PATCH 060/312] Improve JSDoc @augments diagnostics (#19011) --- src/compiler/checker.ts | 4 ++-- src/compiler/diagnosticMessages.json | 4 ++-- tests/baselines/reference/jsdocAugments_notAClass.errors.txt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d47a77a7440..2cad5dbf652 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20034,7 +20034,7 @@ namespace ts { function checkJSDocAugmentsTag(node: JSDocAugmentsTag): void { const classLike = getJSDocHost(node); if (!isClassDeclaration(classLike) && !isClassExpression(classLike)) { - error(classLike, Diagnostics.JSDoc_augments_is_not_attached_to_a_class_declaration); + error(classLike, Diagnostics.JSDoc_0_is_not_attached_to_a_class, idText(node.tagName)); return; } @@ -20049,7 +20049,7 @@ namespace ts { if (extend) { const className = getIdentifierFromEntityNameExpression(extend.expression); if (className && name.escapedText !== className.escapedText) { - error(name, Diagnostics.JSDoc_augments_0_does_not_match_the_extends_1_clause, idText(name), idText(className)); + error(name, Diagnostics.JSDoc_0_1_does_not_match_the_extends_2_clause, idText(node.tagName), idText(name), idText(className)); } } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 91ad9e52bfd..e5e7b774884 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3519,11 +3519,11 @@ "category": "Error", "code": 8021 }, - "JSDoc '@augments' is not attached to a class declaration.": { + "JSDoc '@{0}' is not attached to a class.": { "category": "Error", "code": 8022 }, - "JSDoc '@augments {0}' does not match the 'extends {1}' clause.": { + "JSDoc '@{0} {1}' does not match the 'extends {2}' clause.": { "category": "Error", "code": 8023 }, diff --git a/tests/baselines/reference/jsdocAugments_notAClass.errors.txt b/tests/baselines/reference/jsdocAugments_notAClass.errors.txt index 9f8528f0cd8..daf20aaf884 100644 --- a/tests/baselines/reference/jsdocAugments_notAClass.errors.txt +++ b/tests/baselines/reference/jsdocAugments_notAClass.errors.txt @@ -1,4 +1,4 @@ -/b.js(3,10): error TS8022: JSDoc '@augments' is not attached to a class declaration. +/b.js(3,10): error TS8022: JSDoc '@augments' is not attached to a class. ==== /b.js (1 errors) ==== @@ -6,5 +6,5 @@ /** @augments A */ function b() {} ~ -!!! error TS8022: JSDoc '@augments' is not attached to a class declaration. +!!! error TS8022: JSDoc '@augments' is not attached to a class. \ No newline at end of file From 927ffefcf43727bf3168ee2e10fe7ed30e731a9f Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 10 Oct 2017 11:28:05 -0700 Subject: [PATCH 061/312] Replace more 'verify.rangeAfterCodeFix' with 'verify.codeFix' (#18800) --- src/compiler/diagnosticMessages.json | 2 +- src/harness/fourslash.ts | 2 +- .../codeFixChangeExtendsToImplements.ts | 5 +- ...angeExtendsToImplementsAbstractModifier.ts | 6 ++- ...eFixChangeExtendsToImplementsTypeParams.ts | 5 +- ...xChangeExtendsToImplementsWithDecorator.ts | 6 ++- .../fourslash/codeFixChangeJSDocSyntax1.ts | 5 +- .../fourslash/codeFixChangeJSDocSyntax10.ts | 8 ++- .../fourslash/codeFixChangeJSDocSyntax11.ts | 8 ++- .../fourslash/codeFixChangeJSDocSyntax12.ts | 8 ++- .../fourslash/codeFixChangeJSDocSyntax13.ts | 8 ++- .../fourslash/codeFixChangeJSDocSyntax14.ts | 7 ++- .../fourslash/codeFixChangeJSDocSyntax15.ts | 7 ++- .../fourslash/codeFixChangeJSDocSyntax16.ts | 5 +- .../fourslash/codeFixChangeJSDocSyntax17.ts | 6 ++- .../fourslash/codeFixChangeJSDocSyntax18.ts | 6 ++- .../fourslash/codeFixChangeJSDocSyntax19.ts | 6 ++- .../fourslash/codeFixChangeJSDocSyntax2.ts | 5 +- .../fourslash/codeFixChangeJSDocSyntax20.ts | 6 ++- .../fourslash/codeFixChangeJSDocSyntax21.ts | 6 ++- .../fourslash/codeFixChangeJSDocSyntax22.ts | 6 ++- .../fourslash/codeFixChangeJSDocSyntax23.ts | 6 ++- .../fourslash/codeFixChangeJSDocSyntax24.ts | 6 ++- .../fourslash/codeFixChangeJSDocSyntax25.ts | 6 ++- .../fourslash/codeFixChangeJSDocSyntax26.ts | 6 ++- .../fourslash/codeFixChangeJSDocSyntax27.ts | 8 ++- .../fourslash/codeFixChangeJSDocSyntax3.ts | 5 +- .../fourslash/codeFixChangeJSDocSyntax4.ts | 5 +- .../fourslash/codeFixChangeJSDocSyntax5.ts | 7 ++- .../fourslash/codeFixChangeJSDocSyntax6.ts | 6 ++- .../fourslash/codeFixChangeJSDocSyntax7.ts | 5 +- .../fourslash/codeFixChangeJSDocSyntax8.ts | 5 +- .../fourslash/codeFixChangeJSDocSyntax9.ts | 5 +- ...ClassImplementClassFunctionVoidInferred.ts | 21 ++++---- ...prExtendsAbstractExpressionWithTypeArgs.ts | 23 ++++---- ...assExtendAbstractExpressionWithTypeArgs.ts | 23 ++++---- .../codeFixClassExtendAbstractGetterSetter.ts | 53 ++++++++++--------- .../codeFixClassExtendAbstractMethod.ts | 33 ++++++------ .../codeFixClassExtendAbstractMethodThis.ts | 19 ++++--- ...stractMethodTypeParamsInstantiateNumber.ts | 18 ++++--- ...endAbstractMethodTypeParamsInstantiateU.ts | 18 ++++--- .../codeFixClassExtendAbstractProperty.ts | 19 ++++--- tests/cases/fourslash/unusedMethodInClass1.ts | 11 ++-- tests/cases/fourslash/unusedMethodInClass2.ts | 12 +++-- tests/cases/fourslash/unusedMethodInClass3.ts | 11 ++-- tests/cases/fourslash/unusedMethodInClass4.ts | 8 ++- tests/cases/fourslash/unusedMethodInClass5.ts | 11 ++-- tests/cases/fourslash/unusedMethodInClass6.ts | 11 ++-- .../fourslash/unusedNamespaceInNamespace.ts | 16 +++--- .../unusedParameterInConstructor1.ts | 6 ++- ...sedParameterInConstructor1AddUnderscore.ts | 6 ++- .../unusedParameterInConstructor2.ts | 6 ++- .../unusedParameterInConstructor3.ts | 6 ++- .../unusedParameterInConstructor4.ts | 6 ++- .../fourslash/unusedParameterInFunction1.ts | 6 ++- ...unusedParameterInFunction1AddUnderscore.ts | 6 ++- .../fourslash/unusedParameterInFunction2.ts | 6 ++- .../fourslash/unusedParameterInFunction3.ts | 6 ++- .../fourslash/unusedParameterInFunction4.ts | 6 ++- .../fourslash/unusedParameterInLambda1.ts | 6 ++- .../unusedParameterInLambda1AddUnderscore.ts | 6 ++- .../fourslash/unusedTypeAliasInNamespace1.ts | 15 +++--- .../fourslash/unusedTypeParametersInClass1.ts | 5 +- .../fourslash/unusedTypeParametersInClass2.ts | 5 +- .../fourslash/unusedTypeParametersInClass3.ts | 5 +- .../unusedTypeParametersInFunction1.ts | 5 +- .../unusedTypeParametersInFunction2.ts | 5 +- .../unusedTypeParametersInFunction3.ts | 5 +- .../unusedTypeParametersInInterface1.ts | 5 +- .../unusedTypeParametersInLambda1.ts | 5 +- .../unusedTypeParametersInLambda2.ts | 5 +- .../unusedTypeParametersInLambda3.ts | 5 +- .../unusedTypeParametersInLambda4.ts | 5 +- .../unusedTypeParametersInMethod1.ts | 5 +- .../unusedTypeParametersInMethod2.ts | 5 +- .../unusedTypeParametersInMethods1.ts | 5 +- .../cases/fourslash/unusedVariableInBlocks.ts | 15 +++--- .../cases/fourslash/unusedVariableInClass1.ts | 5 +- .../cases/fourslash/unusedVariableInClass2.ts | 5 +- .../cases/fourslash/unusedVariableInClass3.ts | 5 +- .../fourslash/unusedVariableInForLoop1FS.ts | 6 ++- .../fourslash/unusedVariableInForLoop2FS.ts | 5 +- .../fourslash/unusedVariableInForLoop3FS.ts | 5 +- .../fourslash/unusedVariableInForLoop4FS.ts | 5 +- ...unusedVariableInForLoop5FSAddUnderscore.ts | 5 +- .../fourslash/unusedVariableInForLoop6FS.ts | 7 ++- ...unusedVariableInForLoop6FSAddUnderscore.ts | 6 ++- .../fourslash/unusedVariableInForLoop7FS.ts | 7 ++- .../fourslash/unusedVariableInModule1.ts | 5 +- .../fourslash/unusedVariableInModule2.ts | 5 +- .../fourslash/unusedVariableInModule3.ts | 5 +- .../fourslash/unusedVariableInModule4.ts | 6 ++- .../fourslash/unusedVariableInNamespace1.ts | 5 +- .../fourslash/unusedVariableInNamespace2.ts | 5 +- .../fourslash/unusedVariableInNamespace3.ts | 5 +- 95 files changed, 545 insertions(+), 224 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index e5e7b774884..251e84ca8f4 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3661,7 +3661,7 @@ "category": "Message", "code": 90013 }, - "Change {0} to {1}.": { + "Change '{0}' to '{1}'.": { "category": "Message", "code": 90014 }, diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index debb7290678..de6d92eda05 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2381,7 +2381,7 @@ Actual: ${stringify(fullActual)}`); })); return ts.flatMap(ts.deduplicate(diagnosticsForCodeFix, ts.equalOwnProperties), diagnostic => { - if (errorCode && errorCode !== diagnostic.code) { + if (errorCode !== undefined && errorCode !== diagnostic.code) { return; } diff --git a/tests/cases/fourslash/codeFixChangeExtendsToImplements.ts b/tests/cases/fourslash/codeFixChangeExtendsToImplements.ts index bfaedf2818a..bf3b8b7b8a4 100644 --- a/tests/cases/fourslash/codeFixChangeExtendsToImplements.ts +++ b/tests/cases/fourslash/codeFixChangeExtendsToImplements.ts @@ -3,4 +3,7 @@ //// interface I {} //// [|/* */ class /* */ C /* */ extends /* */ I|]{} -verify.rangeAfterCodeFix("/* */ class /* */ C /* */ implements /* */ I"); \ No newline at end of file +verify.codeFix({ + description: "Change 'extends' to 'implements'.", + newRangeContent: "/* */ class /* */ C /* */ implements /* */ I", +}); diff --git a/tests/cases/fourslash/codeFixChangeExtendsToImplementsAbstractModifier.ts b/tests/cases/fourslash/codeFixChangeExtendsToImplementsAbstractModifier.ts index 5f5ca93c28f..7f309a22965 100644 --- a/tests/cases/fourslash/codeFixChangeExtendsToImplementsAbstractModifier.ts +++ b/tests/cases/fourslash/codeFixChangeExtendsToImplementsAbstractModifier.ts @@ -5,4 +5,8 @@ //// [|abstract class A extends I1 implements I2|] { } -verify.rangeAfterCodeFix("abstract class A implements I1, I2"); \ No newline at end of file +verify.codeFix({ + description: "Change 'extends' to 'implements'.", + // TODO: GH#18794 + newRangeContent: "abstract class A implements I1 , I2", +}); diff --git a/tests/cases/fourslash/codeFixChangeExtendsToImplementsTypeParams.ts b/tests/cases/fourslash/codeFixChangeExtendsToImplementsTypeParams.ts index 869bd1a5dc0..2cca0b277fd 100644 --- a/tests/cases/fourslash/codeFixChangeExtendsToImplementsTypeParams.ts +++ b/tests/cases/fourslash/codeFixChangeExtendsToImplementsTypeParams.ts @@ -3,4 +3,7 @@ ////interface I { x: X} ////[|class C extends I|]{} -verify.rangeAfterCodeFix("class C implements I"); \ No newline at end of file +verify.codeFix({ + description: "Change 'extends' to 'implements'.", + newRangeContent: "class C implements I", +}); diff --git a/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithDecorator.ts b/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithDecorator.ts index 9671f41def3..e031251ac1b 100644 --- a/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithDecorator.ts +++ b/tests/cases/fourslash/codeFixChangeExtendsToImplementsWithDecorator.ts @@ -10,4 +10,8 @@ //// @sealed //// [|class A extends I1 implements I2 { }|] -verify.rangeAfterCodeFix("class A implements I1, I2 { }"); \ No newline at end of file +verify.codeFix({ + description: "Change 'extends' to 'implements'.", + // TODO: GH#18794 + newRangeContent: "class A implements I1 , I2 { }", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax1.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax1.ts index 93107ef669b..1a4e967df45 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax1.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax1.ts @@ -1,4 +1,7 @@ /// //// var x: [|?|] = 12; -verify.rangeAfterCodeFix("any"); +verify.codeFix({ + description: "Change '?' to 'any'.", + newRangeContent: "any", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax10.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax10.ts index 3e6754588fd..12ddb66c6fd 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax10.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax10.ts @@ -2,4 +2,10 @@ /// //// function f(x: [|number?|]) { //// } -verify.rangeAfterCodeFix("number | null", /*includeWhiteSpace*/ false, /*errorCode*/ 8020, 0); + +verify.codeFix({ + description: "Change 'number?' to 'number | null'.", + errorCode: 8020, + index: 0, + newRangeContent: "number | null", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax11.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax11.ts index 7ac80125775..8edcbb35da2 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax11.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax11.ts @@ -2,4 +2,10 @@ /// //// var f = function f(x: [|string?|]) { //// } -verify.rangeAfterCodeFix("string | null | undefined", /*includeWhiteSpace*/ false, /*errorCode*/ 8020, 1); + +verify.codeFix({ + description: "Change 'string?' to 'string | null | undefined'.", + errorCode: 8020, + index: 1, + newRangeContent: "string | null | undefined", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax12.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax12.ts index 37eb5df41ee..a2221897aa8 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax12.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax12.ts @@ -3,4 +3,10 @@ ////class C { //// p: [|*|] ////} -verify.rangeAfterCodeFix("any", /*includeWhiteSpace*/ false, /*errorCode*/ 8020, 0); + +verify.codeFix({ + description: "Change '*' to 'any'.", + errorCode: 8020, + index: 0, + newRangeContent: "any", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax13.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax13.ts index 5b374b508f1..65fef47feda 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax13.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax13.ts @@ -3,4 +3,10 @@ ////class C { //// p: [|*|] = 12 ////} -verify.rangeAfterCodeFix("any", /*includeWhiteSpace*/ false, /*errorCode*/ 8020, 0); + +verify.codeFix({ + description: "Change '*' to 'any'.", + errorCode: 8020, + index: 0, + newRangeContent: "any", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax14.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax14.ts index 69478fc3abc..71f21dd8301 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax14.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax14.ts @@ -2,4 +2,9 @@ /// //// var x = 12 as [|number?|]; -verify.rangeAfterCodeFix("number | null", /*includeWhiteSpace*/ false, /*errorCode*/ 8020, 0); +verify.codeFix({ + description: "Change 'number?' to 'number | null'.", + errorCode: 8020, + index: 0, + newRangeContent: "number | null", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax15.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax15.ts index 9482830c19d..b0e8c069e1e 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax15.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax15.ts @@ -2,4 +2,9 @@ //// var f = <[|function(number?): number|]>(x => x); // note: without --strict, number? --> number, not number | null -verify.rangeAfterCodeFix("(arg0: number) => number", /*includeWhiteSpace*/ false, /*errorCode*/ 8020, 0); +verify.codeFix({ + description: "Change 'function(number?): number' to '(arg0: number) => number'.", + errorCode: 8020, + index: 0, + newRangeContent: "(arg0: number) => number", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax16.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax16.ts index 111aec1dce7..264e490d961 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax16.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax16.ts @@ -1,4 +1,7 @@ /// //// var f: { [K in keyof number]: [|*|] }; -verify.rangeAfterCodeFix("any"); +verify.codeFix({ + description: "Change '*' to 'any'.", + newRangeContent: "any", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax17.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax17.ts index 6a3ce2ed3df..63973222a8a 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax17.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax17.ts @@ -1,3 +1,7 @@ /// //// declare function index(ix: number): [|*|]; -verify.rangeAfterCodeFix("any"); + +verify.codeFix({ + description: "Change '*' to 'any'.", + newRangeContent: "any", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax18.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax18.ts index 30a3815516a..31b04bef0f6 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax18.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax18.ts @@ -1,3 +1,7 @@ /// //// var index: { (ix: number): [|?|] }; -verify.rangeAfterCodeFix("any"); + +verify.codeFix({ + description: "Change '?' to 'any'.", + newRangeContent: "any", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax19.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax19.ts index e6344881227..d254cf6d8dd 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax19.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax19.ts @@ -1,3 +1,7 @@ /// //// var index: { new (ix: number): [|?|] }; -verify.rangeAfterCodeFix("any"); + +verify.codeFix({ + description: "Change '?' to 'any'.", + newRangeContent: "any", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax2.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax2.ts index 333b108538f..d2dc0986a59 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax2.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax2.ts @@ -1,4 +1,7 @@ /// //// var x: [|*|] = 12; -verify.rangeAfterCodeFix("any"); +verify.codeFix({ + description: "Change '*' to 'any'.", + newRangeContent: "any", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax20.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax20.ts index dc153730841..32cfe73fd4a 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax20.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax20.ts @@ -1,3 +1,7 @@ /// //// var index = { get p(): [|*|] { return 12 } }; -verify.rangeAfterCodeFix("any"); + +verify.codeFix({ + description: "Change '*' to 'any'.", + newRangeContent: "any", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax21.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax21.ts index 442414e4577..efb53d53009 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax21.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax21.ts @@ -1,3 +1,7 @@ /// //// var index = { set p(x: [|*|]) { } }; -verify.rangeAfterCodeFix("any"); + +verify.codeFix({ + description: "Change '*' to 'any'.", + newRangeContent: "any", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax22.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax22.ts index c575f1ca7ce..06ff23c3cf5 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax22.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax22.ts @@ -1,3 +1,7 @@ /// //// var index: { [s: string]: [|*|] }; -verify.rangeAfterCodeFix("any"); + +verify.codeFix({ + description: "Change '*' to 'any'.", + newRangeContent: "any", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax23.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax23.ts index 7ab70e18ee7..29a49ff641c 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax23.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax23.ts @@ -3,4 +3,8 @@ //// m(): [|*|] { //// } ////} -verify.rangeAfterCodeFix("any"); + +verify.codeFix({ + description: "Change '*' to 'any'.", + newRangeContent: "any", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax24.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax24.ts index 7ea2d1f6faf..6c9a840a373 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax24.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax24.ts @@ -2,4 +2,8 @@ ////declare class C { //// m(): [|*|]; ////} -verify.rangeAfterCodeFix("any"); + +verify.codeFix({ + description: "Change '*' to 'any'.", + newRangeContent: "any", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax25.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax25.ts index 6486a70417e..74a7ea9fa18 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax25.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax25.ts @@ -2,4 +2,8 @@ ////declare class C { //// p: [|*|]; ////} -verify.rangeAfterCodeFix("any"); + +verify.codeFix({ + description: "Change '*' to 'any'.", + newRangeContent: "any", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax26.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax26.ts index dc31f1dfffd..4287539173a 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax26.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax26.ts @@ -2,4 +2,8 @@ ////class C { //// p: [|*|] = 12; ////} -verify.rangeAfterCodeFix("any"); + +verify.codeFix({ + description: "Change '*' to 'any'.", + newRangeContent: "any", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax27.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax27.ts index a259b2dd719..998a9ebd28a 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax27.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax27.ts @@ -1,4 +1,10 @@ // @strict: true /// ////type T = [|...number?|]; -verify.rangeAfterCodeFix("number[] | null", /*includeWhiteSpace*/ false, /*errorCode*/ 8020, 0); + +verify.codeFix({ + description: "Change '...number?' to 'number[] | null'.", + errorCode: 8020, + index: 0, + newRangeContent: "number[] | null", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax3.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax3.ts index f3b02cb84f1..2c804edb615 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax3.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax3.ts @@ -1,4 +1,7 @@ /// //// var x: [|......number[][]|] = 12; -verify.rangeAfterCodeFix("number[][][][]"); +verify.codeFix({ + description: "Change '......number[][]' to 'number[][][][]'.", + newRangeContent: "number[][][][]", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax4.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax4.ts index e9522331d38..f2df4abfd33 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax4.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax4.ts @@ -1,4 +1,7 @@ /// //// var x: [|Array.|] = 12; -verify.rangeAfterCodeFix("number[]"); +verify.codeFix({ + description: "Change 'Array.' to 'number[]'.", + newRangeContent: "number[]", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax5.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax5.ts index 6f46f3082e1..39cca325a4c 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax5.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax5.ts @@ -2,4 +2,9 @@ /// //// var x: [|?number|] = 12; -verify.rangeAfterCodeFix("number | null", /*includeWhiteSpace*/ false, /*errorCode*/ 8020, 0); +verify.codeFix({ + description: "Change '?number' to 'number | null'.", + errorCode: 8020, + index: 0, + newRangeContent: "number | null", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax6.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax6.ts index 8af9f09d99d..da692d723bb 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax6.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax6.ts @@ -2,4 +2,8 @@ /// //// var x: [|number?|] = 12; -verify.rangeAfterCodeFix("number | null | undefined", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 1); +verify.codeFix({ + description: "Change 'number?' to 'number | null | undefined'.", + index: 1, + newRangeContent: "number | null | undefined", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax7.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax7.ts index c80d08b3bac..1d557896fe9 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax7.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax7.ts @@ -1,4 +1,7 @@ /// //// var x: [|!number|] = 12; -verify.rangeAfterCodeFix("number"); +verify.codeFix({ + description: "Change '!number' to 'number'.", + newRangeContent: "number", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax8.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax8.ts index 0fa7ddf229c..c35badc88cf 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax8.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax8.ts @@ -1,4 +1,7 @@ /// //// var x: [|function(this: number, number): string|] = 12; -verify.rangeAfterCodeFix("(this: number, arg1: number) => string"); +verify.codeFix({ + description: "Change 'function(this: number, number): string' to '(this: number, arg1: number) => string'.", + newRangeContent: "(this: number, arg1: number) => string", +}); diff --git a/tests/cases/fourslash/codeFixChangeJSDocSyntax9.ts b/tests/cases/fourslash/codeFixChangeJSDocSyntax9.ts index 061ded158ea..6ce049b6a42 100644 --- a/tests/cases/fourslash/codeFixChangeJSDocSyntax9.ts +++ b/tests/cases/fourslash/codeFixChangeJSDocSyntax9.ts @@ -1,4 +1,7 @@ /// //// var x: [|function(new: number)|] = 12; -verify.rangeAfterCodeFix("new () => number"); +verify.codeFix({ + description: "Change 'function(new: number)' to 'new () => number'.", + newRangeContent: "new () => number", +}); diff --git a/tests/cases/fourslash/codeFixClassExprClassImplementClassFunctionVoidInferred.ts b/tests/cases/fourslash/codeFixClassExprClassImplementClassFunctionVoidInferred.ts index 2568111fb90..b582c5e8960 100644 --- a/tests/cases/fourslash/codeFixClassExprClassImplementClassFunctionVoidInferred.ts +++ b/tests/cases/fourslash/codeFixClassExprClassImplementClassFunctionVoidInferred.ts @@ -1,13 +1,16 @@ /// -//// class A { -//// f() {} -//// } +////class A { +//// f() {} +////} //// -//// let B = class implements A {[| |]} +////let B = class implements A {[| |]} -verify.rangeAfterCodeFix(` -f(): void{ - throw new Error("Method not implemented."); -} -`); +verify.codeFix({ + description: "Implement interface 'A'.", + // TODO: GH#18795 + newRangeContent: `f(): void {\r + throw new Error("Method not implemented.");\r +}\r + ` +}); diff --git a/tests/cases/fourslash/codeFixClassExprExtendsAbstractExpressionWithTypeArgs.ts b/tests/cases/fourslash/codeFixClassExprExtendsAbstractExpressionWithTypeArgs.ts index a7690b4f5bf..198cb9ea673 100644 --- a/tests/cases/fourslash/codeFixClassExprExtendsAbstractExpressionWithTypeArgs.ts +++ b/tests/cases/fourslash/codeFixClassExprExtendsAbstractExpressionWithTypeArgs.ts @@ -1,14 +1,17 @@ /// -//// function foo(a: T) { -//// abstract class C { -//// abstract a: T | U; -//// } -//// return C; -//// } +////function foo(a: T) { +//// abstract class C { +//// abstract a: T | U; +//// } +//// return C; +////} //// -//// let B = class extends foo("s") {[| |]} +////let B = class extends foo("s") {[| |]} -verify.rangeAfterCodeFix(` -a: string | number; -`); +verify.codeFix({ + description: "Implement inherited abstract class.", + // TODO: GH#18795 + newRangeContent: `a: string | number;\r + ` +}); diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractExpressionWithTypeArgs.ts b/tests/cases/fourslash/codeFixClassExtendAbstractExpressionWithTypeArgs.ts index 5796bea6fb4..ed574348b9f 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractExpressionWithTypeArgs.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractExpressionWithTypeArgs.ts @@ -1,14 +1,17 @@ /// -//// function foo(a: T) { -//// abstract class C { -//// abstract a: T | U; -//// } -//// return C; -//// } +////function foo(a: T) { +//// abstract class C { +//// abstract a: T | U; +//// } +//// return C; +////} //// -//// class B extends foo("s") {[| |]} +////class B extends foo("s") {[| |]} -verify.rangeAfterCodeFix(` -a: string | number; -`); \ No newline at end of file +verify.codeFix({ + description: "Implement inherited abstract class.", + // TODO: GH#18795 + newRangeContent: `a: string | number;\r + ` +}); diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractGetterSetter.ts b/tests/cases/fourslash/codeFixClassExtendAbstractGetterSetter.ts index bc437c93bcd..3522b1d39da 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractGetterSetter.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractGetterSetter.ts @@ -1,31 +1,34 @@ /// -//// abstract class A { -//// private _a: string; +////abstract class A { +//// private _a: string; //// -//// abstract get a(): number | string; -//// abstract get b(): this; -//// abstract get c(): A; +//// abstract get a(): number | string; +//// abstract get b(): this; +//// abstract get c(): A; //// -//// abstract set d(arg: number | string); -//// abstract set e(arg: this); -//// abstract set f(arg: A); +//// abstract set d(arg: number | string); +//// abstract set e(arg: this); +//// abstract set f(arg: A); //// -//// abstract get g(): string; -//// abstract set g(newName: string); -//// } -//// -//// // Don't need to add anything in this case. -//// abstract class B extends A {} -//// -//// class C extends A {[| |]} +//// abstract get g(): string; +//// abstract set g(newName: string); +////} +//// +////// Don't need to add anything in this case. +////abstract class B extends A {} +//// +////class C extends A {[| |]} -verify.rangeAfterCodeFix(` - a: string | number; - b: this; - c: A; - d: string | number; - e: this; - f: A; - g: string; -`); +verify.codeFix({ + description: "Implement inherited abstract class.", + // TODO: GH#18795 + newRangeContent: `a: string | number;\r +b: this;\r +c: A;\r +d: string | number;\r +e: this;\r +f: A;\r +g: string;\r + ` +}); diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts index 7e51e2216dc..de9500552ab 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethod.ts @@ -1,24 +1,27 @@ /// -//// abstract class A { +////abstract class A { //// abstract f(a: number, b: string): boolean; //// abstract f(a: number, b: string): this; //// abstract f(a: string, b: number): Function; //// abstract f(a: string): Function; //// abstract foo(): number; -//// } +////} //// -//// class C extends A {[| |]} +////class C extends A {[| |]} -verify.rangeAfterCodeFix(` - f(a: number, b: string): boolean; - f(a: number, b: string): this; - f(a: string, b: number): Function; - f(a: string): Function; - f(a: any, b?: any) { - throw new Error("Method not implemented."); - } - foo(): number { - throw new Error("Method not implemented."); - } -`); +verify.codeFix({ + description: "Implement inherited abstract class.", + // TODO: GH#18795 + newRangeContent: `f(a: number, b: string): boolean;\r +f(a: number, b: string): this;\r +f(a: string, b: number): Function;\r +f(a: string): Function;\r +f(a: any, b?: any) {\r + throw new Error("Method not implemented.");\r +}\r +foo(): number {\r + throw new Error("Method not implemented.");\r +}\r + ` +}); diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethodThis.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethodThis.ts index a462ac98121..e33338b45a9 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractMethodThis.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethodThis.ts @@ -1,13 +1,16 @@ /// -//// abstract class A { +////abstract class A { //// abstract f(): this; -//// } +////} //// -//// class C extends A {[| |]} +////class C extends A {[| |]} -verify.rangeAfterCodeFix(` - f(): this { - throw new Error("Method not implemented."); - } -`); +verify.codeFix({ + description: "Implement inherited abstract class.", + // TODO: GH#18795 + newRangeContent: `f(): this {\r + throw new Error("Method not implemented.");\r +}\r + ` +}); diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateNumber.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateNumber.ts index c1a55e88034..395d9348b79 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateNumber.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateNumber.ts @@ -1,12 +1,16 @@ /// -//// abstract class A { +////abstract class A { //// abstract f(x: T): T; -//// } +////} //// -//// class C extends A {[| |]} +////class C extends A {[| |]} -verify.rangeAfterCodeFix(`f(x: number): number{ - throw new Error("Method not implemented."); -} -`); \ No newline at end of file +verify.codeFix({ + description: "Implement inherited abstract class.", + // TODO: GH#18795 + newRangeContent: `f(x: number): number {\r + throw new Error("Method not implemented.");\r +}\r + ` +}); diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateU.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateU.ts index c2ec5ff8035..408406a9efe 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateU.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethodTypeParamsInstantiateU.ts @@ -1,12 +1,16 @@ /// -//// abstract class A { +////abstract class A { //// abstract f(x: T): T; -//// } +////} //// -//// class C extends A {[| |]} +////class C extends A {[| |]} -verify.rangeAfterCodeFix(`f(x: U): U{ - throw new Error("Method not implemented."); -} -`); \ No newline at end of file +verify.codeFix({ + description: "Implement inherited abstract class.", + // TODO: GH#18795 + newRangeContent: `f(x: U): U {\r + throw new Error("Method not implemented.");\r +}\r + ` +}); diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts b/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts index 701903d6770..fbdb13f4f2c 100644 --- a/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts +++ b/tests/cases/fourslash/codeFixClassExtendAbstractProperty.ts @@ -1,15 +1,18 @@ /// -//// abstract class A { +////abstract class A { //// abstract x: number; //// abstract y: this; //// abstract z: A; -//// } +////} //// -//// class C extends A {[| |]} +////class C extends A {[| |]} -verify.rangeAfterCodeFix(` - x: number; - y: this; - z: A; -`); +verify.codeFix({ + description: "Implement inherited abstract class.", + // TODO: GH#18795 + newRangeContent: `x: number;\r +y: this;\r +z: A;\r + ` +}); diff --git a/tests/cases/fourslash/unusedMethodInClass1.ts b/tests/cases/fourslash/unusedMethodInClass1.ts index a5e3789c8af..175d95e2490 100644 --- a/tests/cases/fourslash/unusedMethodInClass1.ts +++ b/tests/cases/fourslash/unusedMethodInClass1.ts @@ -1,11 +1,12 @@ /// // @noUnusedLocals: true -////[| class greeter { +////class greeter { //// private function1() { //// } -////} |] +////} -verify.rangeAfterCodeFix(` -class greeter { -}`); +verify.codeFix({ + description: `Remove declaration for: 'function1'.`, + newFileContent: "class greeter {\n}", +}); diff --git a/tests/cases/fourslash/unusedMethodInClass2.ts b/tests/cases/fourslash/unusedMethodInClass2.ts index cce621236d4..884f7ecce4e 100644 --- a/tests/cases/fourslash/unusedMethodInClass2.ts +++ b/tests/cases/fourslash/unusedMethodInClass2.ts @@ -1,15 +1,17 @@ /// // @noUnusedLocals: true -//// [| class greeter { +////class greeter { //// public function2() { //// } //// private function1() { //// } -////} |] +////} -verify.rangeAfterCodeFix(` -class greeter { +verify.codeFix({ + description: `Remove declaration for: 'function1'.`, + newFileContent: `class greeter { public function2() { } -}`); +}`, +}); diff --git a/tests/cases/fourslash/unusedMethodInClass3.ts b/tests/cases/fourslash/unusedMethodInClass3.ts index ccf98c4bbc5..f76a1acde09 100644 --- a/tests/cases/fourslash/unusedMethodInClass3.ts +++ b/tests/cases/fourslash/unusedMethodInClass3.ts @@ -1,11 +1,12 @@ /// // @noUnusedLocals: true -////[|class greeter { +////class greeter { //// private function1 = function() { //// } -////} |] +////} -verify.rangeAfterCodeFix(` -class greeter { -}`); +verify.codeFix({ + description: `Remove declaration for: 'function1'.`, + newFileContent: "class greeter {\n}", +}); diff --git a/tests/cases/fourslash/unusedMethodInClass4.ts b/tests/cases/fourslash/unusedMethodInClass4.ts index 962b80f5bc1..9f882a3b76e 100644 --- a/tests/cases/fourslash/unusedMethodInClass4.ts +++ b/tests/cases/fourslash/unusedMethodInClass4.ts @@ -8,5 +8,9 @@ //// } |] ////} -verify.rangeAfterCodeFix(`public function2(){ -}`); +verify.codeFix({ + description: `Remove declaration for: 'function1'.`, + newRangeContent: `public function2(){ + } +`, +}); diff --git a/tests/cases/fourslash/unusedMethodInClass5.ts b/tests/cases/fourslash/unusedMethodInClass5.ts index 806e619817f..c53a31b5d36 100644 --- a/tests/cases/fourslash/unusedMethodInClass5.ts +++ b/tests/cases/fourslash/unusedMethodInClass5.ts @@ -1,8 +1,11 @@ /// // @noUnusedLocals: true -//// [|class C { -//// private ["string"] (){} -//// }|] +////class C { +//// private ["string"] (){} +////} -verify.rangeAfterCodeFix("class C { }"); \ No newline at end of file +verify.codeFix({ + description: `Remove declaration for: '"string"'.`, + newFileContent: "class C {\n}", +}); diff --git a/tests/cases/fourslash/unusedMethodInClass6.ts b/tests/cases/fourslash/unusedMethodInClass6.ts index d223b3d6857..eef00d1cdd0 100644 --- a/tests/cases/fourslash/unusedMethodInClass6.ts +++ b/tests/cases/fourslash/unusedMethodInClass6.ts @@ -1,8 +1,11 @@ /// // @noUnusedLocals: true -//// [|class C { -//// private "string" (){} -//// }|] +////class C { +//// private "string" (){} +////} -verify.rangeAfterCodeFix("class C { }"); \ No newline at end of file +verify.codeFix({ + description: `Remove declaration for: '"string"'.`, + newFileContent: "class C {\n}", +}); diff --git a/tests/cases/fourslash/unusedNamespaceInNamespace.ts b/tests/cases/fourslash/unusedNamespaceInNamespace.ts index 802336454c6..4391a6a158c 100644 --- a/tests/cases/fourslash/unusedNamespaceInNamespace.ts +++ b/tests/cases/fourslash/unusedNamespaceInNamespace.ts @@ -1,13 +1,13 @@ /// // @noUnusedLocals: true -//// [|namespace A { +////namespace A { //// namespace B { -//// } -//// }|] - -verify.rangeAfterCodeFix(` -namespace A { -} -`); +//// } +////} +verify.codeFix({ + description: "Remove declaration for: 'B'.", + newFileContent: `namespace A { +}`, +}); diff --git a/tests/cases/fourslash/unusedParameterInConstructor1.ts b/tests/cases/fourslash/unusedParameterInConstructor1.ts index 33fe34c7e61..46a8c1f3b52 100644 --- a/tests/cases/fourslash/unusedParameterInConstructor1.ts +++ b/tests/cases/fourslash/unusedParameterInConstructor1.ts @@ -5,4 +5,8 @@ //// [|constructor(private p1: string, public p2: boolean, public p3: any, p5)|] { p5; } //// } -verify.rangeAfterCodeFix("constructor(public p2: boolean, public p3: any, p5)", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); \ No newline at end of file +verify.codeFix({ + description: "Remove declaration for: 'p1'.", + index: 0, + newRangeContent: "constructor(public p2: boolean, public p3: any, p5)", +}); diff --git a/tests/cases/fourslash/unusedParameterInConstructor1AddUnderscore.ts b/tests/cases/fourslash/unusedParameterInConstructor1AddUnderscore.ts index 31882978951..634561a5c65 100644 --- a/tests/cases/fourslash/unusedParameterInConstructor1AddUnderscore.ts +++ b/tests/cases/fourslash/unusedParameterInConstructor1AddUnderscore.ts @@ -5,4 +5,8 @@ //// [|constructor(private p1: string, public p2: boolean, public p3: any, p5) |] { p5; } //// } -verify.rangeAfterCodeFix("constructor(private _p1: string, public p2: boolean, public p3: any, p5)", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 1); \ No newline at end of file +verify.codeFix({ + description: "Prefix 'p1' with an underscore.", + index: 1, + newRangeContent: "constructor(private _p1: string, public p2: boolean, public p3: any, p5)", +}); diff --git a/tests/cases/fourslash/unusedParameterInConstructor2.ts b/tests/cases/fourslash/unusedParameterInConstructor2.ts index 71595a9c81c..b8208bb5359 100644 --- a/tests/cases/fourslash/unusedParameterInConstructor2.ts +++ b/tests/cases/fourslash/unusedParameterInConstructor2.ts @@ -5,4 +5,8 @@ //// [|constructor(public p1: string, private p2: boolean, public p3: any, p5)|] { p5; } //// } -verify.rangeAfterCodeFix("constructor(public p1: string, public p3: any, p5)", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); \ No newline at end of file +verify.codeFix({ + description: "Remove declaration for: 'p2'.", + index: 0, + newRangeContent: "constructor(public p1: string, public p3: any, p5)", +}); diff --git a/tests/cases/fourslash/unusedParameterInConstructor3.ts b/tests/cases/fourslash/unusedParameterInConstructor3.ts index 3da0e85407f..c36f24595a7 100644 --- a/tests/cases/fourslash/unusedParameterInConstructor3.ts +++ b/tests/cases/fourslash/unusedParameterInConstructor3.ts @@ -5,4 +5,8 @@ //// [|constructor(public p1: string, public p2: boolean, private p3: any, p5)|] { p5; } //// } -verify.rangeAfterCodeFix("constructor(public p1: string, public p2: boolean, p5)", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); \ No newline at end of file +verify.codeFix({ + description: "Remove declaration for: 'p3'.", + index: 0, + newRangeContent: "constructor(public p1: string, public p2: boolean, p5)", +}); diff --git a/tests/cases/fourslash/unusedParameterInConstructor4.ts b/tests/cases/fourslash/unusedParameterInConstructor4.ts index 860a7befa9b..99e98d64cda 100644 --- a/tests/cases/fourslash/unusedParameterInConstructor4.ts +++ b/tests/cases/fourslash/unusedParameterInConstructor4.ts @@ -5,4 +5,8 @@ //// [|constructor(private readonly p2: boolean, p5)|] { p5; } //// } -verify.rangeAfterCodeFix("constructor(p5)", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); \ No newline at end of file +verify.codeFix({ + description: "Remove declaration for: 'p2'.", + index: 0, + newRangeContent: "constructor(p5)", +}); diff --git a/tests/cases/fourslash/unusedParameterInFunction1.ts b/tests/cases/fourslash/unusedParameterInFunction1.ts index bc6f081ecaa..3f979f78766 100644 --- a/tests/cases/fourslash/unusedParameterInFunction1.ts +++ b/tests/cases/fourslash/unusedParameterInFunction1.ts @@ -4,4 +4,8 @@ ////function [|greeter( x)|] { ////} -verify.rangeAfterCodeFix("greeter()", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); +verify.codeFix({ + description: "Remove declaration for: 'x'.", + index: 0, + newRangeContent: "greeter()", +}); diff --git a/tests/cases/fourslash/unusedParameterInFunction1AddUnderscore.ts b/tests/cases/fourslash/unusedParameterInFunction1AddUnderscore.ts index 137625869c8..c248c5e1a94 100644 --- a/tests/cases/fourslash/unusedParameterInFunction1AddUnderscore.ts +++ b/tests/cases/fourslash/unusedParameterInFunction1AddUnderscore.ts @@ -4,4 +4,8 @@ ////function [|greeter( x) |] { ////} -verify.rangeAfterCodeFix("greeter( _x)", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 1); +verify.codeFix({ + description: "Prefix 'x' with an underscore.", + index: 1, + newRangeContent: "greeter( _x)", +}); diff --git a/tests/cases/fourslash/unusedParameterInFunction2.ts b/tests/cases/fourslash/unusedParameterInFunction2.ts index 6d1a772b0a8..74d95c99221 100644 --- a/tests/cases/fourslash/unusedParameterInFunction2.ts +++ b/tests/cases/fourslash/unusedParameterInFunction2.ts @@ -5,4 +5,8 @@ //// use(x); ////} -verify.rangeAfterCodeFix("greeter(x)", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); \ No newline at end of file +verify.codeFix({ + description: "Remove declaration for: 'y'.", + index: 0, + newRangeContent: "greeter(x)", +}); diff --git a/tests/cases/fourslash/unusedParameterInFunction3.ts b/tests/cases/fourslash/unusedParameterInFunction3.ts index dcbe53163db..30dc2a94060 100644 --- a/tests/cases/fourslash/unusedParameterInFunction3.ts +++ b/tests/cases/fourslash/unusedParameterInFunction3.ts @@ -5,4 +5,8 @@ //// y++; ////} -verify.rangeAfterCodeFix("greeter(y)", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); \ No newline at end of file +verify.codeFix({ + description: "Remove declaration for: 'x'.", + index: 0, + newRangeContent: "greeter(y)", +}); diff --git a/tests/cases/fourslash/unusedParameterInFunction4.ts b/tests/cases/fourslash/unusedParameterInFunction4.ts index e3ee2585384..87b5880ba70 100644 --- a/tests/cases/fourslash/unusedParameterInFunction4.ts +++ b/tests/cases/fourslash/unusedParameterInFunction4.ts @@ -5,4 +5,8 @@ //// use(x, z); ////} -verify.rangeAfterCodeFix("function greeter(x,z)", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); \ No newline at end of file +verify.codeFix({ + description: "Remove declaration for: 'y'.", + index: 0, + newRangeContent: "function greeter(x,z) ", +}); diff --git a/tests/cases/fourslash/unusedParameterInLambda1.ts b/tests/cases/fourslash/unusedParameterInLambda1.ts index a5f735c7016..325502ebb6d 100644 --- a/tests/cases/fourslash/unusedParameterInLambda1.ts +++ b/tests/cases/fourslash/unusedParameterInLambda1.ts @@ -6,4 +6,8 @@ //// [|return (x:number) => {}|] //// } -verify.rangeAfterCodeFix("return () => {}", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); +verify.codeFix({ + description: "Remove declaration for: 'x'.", + index: 0, + newRangeContent: "return () => {}", +}); diff --git a/tests/cases/fourslash/unusedParameterInLambda1AddUnderscore.ts b/tests/cases/fourslash/unusedParameterInLambda1AddUnderscore.ts index 916c32d82eb..1b05c66dd2f 100644 --- a/tests/cases/fourslash/unusedParameterInLambda1AddUnderscore.ts +++ b/tests/cases/fourslash/unusedParameterInLambda1AddUnderscore.ts @@ -6,4 +6,8 @@ //// [|return (x:number) => {} |] //// } -verify.rangeAfterCodeFix("return (_x:number) => {}", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 1); +verify.codeFix({ + description: "Prefix 'x' with an underscore.", + index: 1, + newRangeContent: "return (_x:number) => {}", +}); diff --git a/tests/cases/fourslash/unusedTypeAliasInNamespace1.ts b/tests/cases/fourslash/unusedTypeAliasInNamespace1.ts index 2314ebbe447..13c87f6afd6 100644 --- a/tests/cases/fourslash/unusedTypeAliasInNamespace1.ts +++ b/tests/cases/fourslash/unusedTypeAliasInNamespace1.ts @@ -1,11 +1,14 @@ /// // @noUnusedLocals: true -//// [| namespace greeter { -//// type hw = "Hello" |"world"; -//// export type nw = "No" | "Way"; -//// } |] +////namespace greeter { +//// type hw = "Hello" |"world"; +//// export type nw = "No" | "Way"; +////} -verify.rangeAfterCodeFix(`namespace greeter { +verify.codeFix({ + description: "Remove declaration for: 'hw'.", + newFileContent: `namespace greeter { export type nw = "No" | "Way"; -}`); +}`, +}); diff --git a/tests/cases/fourslash/unusedTypeParametersInClass1.ts b/tests/cases/fourslash/unusedTypeParametersInClass1.ts index 322921ab471..6574362511f 100644 --- a/tests/cases/fourslash/unusedTypeParametersInClass1.ts +++ b/tests/cases/fourslash/unusedTypeParametersInClass1.ts @@ -4,4 +4,7 @@ ////[|class greeter |] { ////} -verify.rangeAfterCodeFix("class greeter"); \ No newline at end of file +verify.codeFix({ + description: "Remove declaration for: 'T'.", + newRangeContent: "class greeter ", +}); diff --git a/tests/cases/fourslash/unusedTypeParametersInClass2.ts b/tests/cases/fourslash/unusedTypeParametersInClass2.ts index feaf9d3a14b..3cb984a11ec 100644 --- a/tests/cases/fourslash/unusedTypeParametersInClass2.ts +++ b/tests/cases/fourslash/unusedTypeParametersInClass2.ts @@ -5,4 +5,7 @@ //// public a: X; ////} -verify.rangeAfterCodeFix("class greeter"); \ No newline at end of file +verify.codeFix({ + description: "Remove declaration for: 'Y'.", + newRangeContent: "class greeter ", +}); diff --git a/tests/cases/fourslash/unusedTypeParametersInClass3.ts b/tests/cases/fourslash/unusedTypeParametersInClass3.ts index b1151265fe3..13ebc352cb0 100644 --- a/tests/cases/fourslash/unusedTypeParametersInClass3.ts +++ b/tests/cases/fourslash/unusedTypeParametersInClass3.ts @@ -6,4 +6,7 @@ //// public b: Z; ////} -verify.rangeAfterCodeFix("class greeter"); +verify.codeFix({ + description: "Remove declaration for: 'Y'.", + newRangeContent: "class greeter ", +}); diff --git a/tests/cases/fourslash/unusedTypeParametersInFunction1.ts b/tests/cases/fourslash/unusedTypeParametersInFunction1.ts index a11156badaa..b7289fc1e0a 100644 --- a/tests/cases/fourslash/unusedTypeParametersInFunction1.ts +++ b/tests/cases/fourslash/unusedTypeParametersInFunction1.ts @@ -3,4 +3,7 @@ // @noUnusedLocals: true //// [|function f1() {}|] -verify.rangeAfterCodeFix("function f1() {}"); +verify.codeFix({ + description: "Remove declaration for: 'T'.", + newRangeContent: "function f1() {}", +}); diff --git a/tests/cases/fourslash/unusedTypeParametersInFunction2.ts b/tests/cases/fourslash/unusedTypeParametersInFunction2.ts index a011f093dab..e2851b34605 100644 --- a/tests/cases/fourslash/unusedTypeParametersInFunction2.ts +++ b/tests/cases/fourslash/unusedTypeParametersInFunction2.ts @@ -3,4 +3,7 @@ // @noUnusedLocals: true //// [|function f1(a: X) {a}|] -verify.rangeAfterCodeFix("function f1(a: X) {a}"); +verify.codeFix({ + description: "Remove declaration for: 'Y'.", + newRangeContent: "function f1(a: X) {a}", +}); diff --git a/tests/cases/fourslash/unusedTypeParametersInFunction3.ts b/tests/cases/fourslash/unusedTypeParametersInFunction3.ts index 6dc56ccc7cb..4be2dc5feb3 100644 --- a/tests/cases/fourslash/unusedTypeParametersInFunction3.ts +++ b/tests/cases/fourslash/unusedTypeParametersInFunction3.ts @@ -3,4 +3,7 @@ // @noUnusedLocals: true //// [|function f1(a: X) {a;var b:Z;b}|] -verify.rangeAfterCodeFix("function f1(a: X) {a;var b:Z;b}"); +verify.codeFix({ + description: "Remove declaration for: 'Y'.", + newRangeContent: "function f1(a: X) {a;var b:Z;b}", +}); diff --git a/tests/cases/fourslash/unusedTypeParametersInInterface1.ts b/tests/cases/fourslash/unusedTypeParametersInInterface1.ts index b5363b369be..bc3a95d63b6 100644 --- a/tests/cases/fourslash/unusedTypeParametersInInterface1.ts +++ b/tests/cases/fourslash/unusedTypeParametersInInterface1.ts @@ -4,4 +4,7 @@ // @noUnusedParameters: true //// [|interface I {}|] -verify.rangeAfterCodeFix("interface I {}"); \ No newline at end of file +verify.codeFix({ + description: "Remove declaration for: 'T'.", + newRangeContent: "interface I {}", +}); diff --git a/tests/cases/fourslash/unusedTypeParametersInLambda1.ts b/tests/cases/fourslash/unusedTypeParametersInLambda1.ts index 01c1ebd24f5..3d7310d6ae6 100644 --- a/tests/cases/fourslash/unusedTypeParametersInLambda1.ts +++ b/tests/cases/fourslash/unusedTypeParametersInLambda1.ts @@ -6,4 +6,7 @@ //// [|return (x:number) => {x}|] //// } -verify.rangeAfterCodeFix("return (x:number) => {x}"); +verify.codeFix({ + description: "Remove declaration for: 'T'.", + newRangeContent: "return(x:number) => {x}", +}); diff --git a/tests/cases/fourslash/unusedTypeParametersInLambda2.ts b/tests/cases/fourslash/unusedTypeParametersInLambda2.ts index e5a4acc31c5..b2b89d3373e 100644 --- a/tests/cases/fourslash/unusedTypeParametersInLambda2.ts +++ b/tests/cases/fourslash/unusedTypeParametersInLambda2.ts @@ -6,4 +6,7 @@ //// [|new (a: T): void;|] //// } -verify.rangeAfterCodeFix("new (a: T): void;"); +verify.codeFix({ + description: "Remove declaration for: 'U'.", + newRangeContent: "new (a: T): void;", +}); diff --git a/tests/cases/fourslash/unusedTypeParametersInLambda3.ts b/tests/cases/fourslash/unusedTypeParametersInLambda3.ts index e6d866dcb6a..1f994c45905 100644 --- a/tests/cases/fourslash/unusedTypeParametersInLambda3.ts +++ b/tests/cases/fourslash/unusedTypeParametersInLambda3.ts @@ -7,4 +7,7 @@ //// [|new (a: T): A;|] //// } -verify.rangeAfterCodeFix("new (a: T): A;"); +verify.codeFix({ + description: "Remove declaration for: 'K'.", + newRangeContent: "new (a: T): A;", +}); diff --git a/tests/cases/fourslash/unusedTypeParametersInLambda4.ts b/tests/cases/fourslash/unusedTypeParametersInLambda4.ts index 04bd7c7e9be..d5c01202d26 100644 --- a/tests/cases/fourslash/unusedTypeParametersInLambda4.ts +++ b/tests/cases/fourslash/unusedTypeParametersInLambda4.ts @@ -6,4 +6,7 @@ //// } //// [|var y: new (a:T)=>void;|] -verify.rangeAfterCodeFix("var y: new (a:T)=>void;"); \ No newline at end of file +verify.codeFix({ + description: "Remove declaration for: 'U'.", + newRangeContent: "var y: new (a:T)=>void;", +}); diff --git a/tests/cases/fourslash/unusedTypeParametersInMethod1.ts b/tests/cases/fourslash/unusedTypeParametersInMethod1.ts index bc14952eca9..f4d036f54f4 100644 --- a/tests/cases/fourslash/unusedTypeParametersInMethod1.ts +++ b/tests/cases/fourslash/unusedTypeParametersInMethod1.ts @@ -5,4 +5,7 @@ //// [|f1()|] {} //// } -verify.rangeAfterCodeFix("f1()"); \ No newline at end of file +verify.codeFix({ + description: "Remove declaration for: 'T'.", + newRangeContent: "f1()", +}); diff --git a/tests/cases/fourslash/unusedTypeParametersInMethod2.ts b/tests/cases/fourslash/unusedTypeParametersInMethod2.ts index c12fd53f66b..25556ebc57d 100644 --- a/tests/cases/fourslash/unusedTypeParametersInMethod2.ts +++ b/tests/cases/fourslash/unusedTypeParametersInMethod2.ts @@ -5,4 +5,7 @@ //// [|f1(a: U)|] {a;} //// } -verify.rangeAfterCodeFix("f1(a: U)"); \ No newline at end of file +verify.codeFix({ + description: "Remove declaration for: 'T'.", + newRangeContent: "f1(a: U)", +}); diff --git a/tests/cases/fourslash/unusedTypeParametersInMethods1.ts b/tests/cases/fourslash/unusedTypeParametersInMethods1.ts index d0b170491f5..62f22246431 100644 --- a/tests/cases/fourslash/unusedTypeParametersInMethods1.ts +++ b/tests/cases/fourslash/unusedTypeParametersInMethods1.ts @@ -5,4 +5,7 @@ //// [|public f1(a: X)|] { a; var b: Z; b } //// } -verify.rangeAfterCodeFix("public f1(a: X)"); +verify.codeFix({ + description: "Remove declaration for: 'Y'.", + newRangeContent: "public f1(a: X)", +}); diff --git a/tests/cases/fourslash/unusedVariableInBlocks.ts b/tests/cases/fourslash/unusedVariableInBlocks.ts index 2a33d0c4cf5..fe3c002916b 100644 --- a/tests/cases/fourslash/unusedVariableInBlocks.ts +++ b/tests/cases/fourslash/unusedVariableInBlocks.ts @@ -1,15 +1,18 @@ /// // @noUnusedLocals: true -//// function f1 () { +////function f1 () { //// [|let x = 10; //// { //// let x = 11; //// } //// x;|] -//// } +////} -verify.rangeAfterCodeFix(`let x = 10; - { - } - x;`); +verify.codeFix({ + description: "Remove declaration for: 'x'.", + newRangeContent: `let x = 10; + { + } + x;`, +}); diff --git a/tests/cases/fourslash/unusedVariableInClass1.ts b/tests/cases/fourslash/unusedVariableInClass1.ts index 8b0ca0db727..e4cec171e8e 100644 --- a/tests/cases/fourslash/unusedVariableInClass1.ts +++ b/tests/cases/fourslash/unusedVariableInClass1.ts @@ -5,4 +5,7 @@ //// [|private greeting: string;|] ////} -verify.rangeAfterCodeFix(""); +verify.codeFix({ + description: "Remove declaration for: 'greeting'.", + newRangeContent: "", +}); diff --git a/tests/cases/fourslash/unusedVariableInClass2.ts b/tests/cases/fourslash/unusedVariableInClass2.ts index 6503dd02872..1f632a43ce8 100644 --- a/tests/cases/fourslash/unusedVariableInClass2.ts +++ b/tests/cases/fourslash/unusedVariableInClass2.ts @@ -6,4 +6,7 @@ //// private greeting: string;|] ////} -verify.rangeAfterCodeFix("public greeting1;"); +verify.codeFix({ + description: "Remove declaration for: 'greeting'.", + newRangeContent: "public greeting1;\n", +}); diff --git a/tests/cases/fourslash/unusedVariableInClass3.ts b/tests/cases/fourslash/unusedVariableInClass3.ts index 3ac306170a2..eec4e6bbe8f 100644 --- a/tests/cases/fourslash/unusedVariableInClass3.ts +++ b/tests/cases/fourslash/unusedVariableInClass3.ts @@ -5,4 +5,7 @@ //// private X = function() {}; ////|]} -verify.rangeAfterCodeFix(""); +verify.codeFix({ + description: "Remove declaration for: 'X'.", + newRangeContent: "\n", +}); diff --git a/tests/cases/fourslash/unusedVariableInForLoop1FS.ts b/tests/cases/fourslash/unusedVariableInForLoop1FS.ts index 760d8487b34..2a4feffd474 100644 --- a/tests/cases/fourslash/unusedVariableInForLoop1FS.ts +++ b/tests/cases/fourslash/unusedVariableInForLoop1FS.ts @@ -7,5 +7,7 @@ //// } //// } -verify.rangeAfterCodeFix("for(; ;)"); - +verify.codeFix({ + description: "Remove declaration for: 'i'.", + newRangeContent: "for(; ;) ", +}); diff --git a/tests/cases/fourslash/unusedVariableInForLoop2FS.ts b/tests/cases/fourslash/unusedVariableInForLoop2FS.ts index a16f21e8417..d913ae5ce94 100644 --- a/tests/cases/fourslash/unusedVariableInForLoop2FS.ts +++ b/tests/cases/fourslash/unusedVariableInForLoop2FS.ts @@ -7,4 +7,7 @@ //// } //// } -verify.rangeAfterCodeFix("for(var i = 0; ;i++)"); +verify.codeFix({ + description: "Remove declaration for: 'j'.", + newRangeContent: "for(var i = 0; ;i++)", +}); diff --git a/tests/cases/fourslash/unusedVariableInForLoop3FS.ts b/tests/cases/fourslash/unusedVariableInForLoop3FS.ts index 07d13307ca7..6f3beae5c74 100644 --- a/tests/cases/fourslash/unusedVariableInForLoop3FS.ts +++ b/tests/cases/fourslash/unusedVariableInForLoop3FS.ts @@ -7,4 +7,7 @@ //// } //// } -verify.rangeAfterCodeFix("for(var i = 0, k=0; ;i++,k++)"); \ No newline at end of file +verify.codeFix({ + description: "Remove declaration for: 'j'.", + newRangeContent: "for(var i = 0, k=0; ;i++, k++)", +}); diff --git a/tests/cases/fourslash/unusedVariableInForLoop4FS.ts b/tests/cases/fourslash/unusedVariableInForLoop4FS.ts index d54f8baaa3d..661012958d4 100644 --- a/tests/cases/fourslash/unusedVariableInForLoop4FS.ts +++ b/tests/cases/fourslash/unusedVariableInForLoop4FS.ts @@ -7,4 +7,7 @@ //// } //// } -verify.rangeAfterCodeFix("for(var j = 0, k=0; ;j++,k++)"); +verify.codeFix({ + description: "Remove declaration for: 'i'.", + newRangeContent: "for(var j= 0, k=0; ;j++, k++) ", +}); diff --git a/tests/cases/fourslash/unusedVariableInForLoop5FSAddUnderscore.ts b/tests/cases/fourslash/unusedVariableInForLoop5FSAddUnderscore.ts index 2948bfab207..87783ff67fc 100644 --- a/tests/cases/fourslash/unusedVariableInForLoop5FSAddUnderscore.ts +++ b/tests/cases/fourslash/unusedVariableInForLoop5FSAddUnderscore.ts @@ -7,4 +7,7 @@ //// } //// } -verify.rangeAfterCodeFix(`for (const _elem in ["a", "b", "c"])`, /*includeWhiteSpace*/ true, /*errorCode*/ 0); +verify.codeFix({ + description: "Prefix 'elem' with an underscore.", + newRangeContent: 'for (const _elem in ["a", "b", "c"])' +}); diff --git a/tests/cases/fourslash/unusedVariableInForLoop6FS.ts b/tests/cases/fourslash/unusedVariableInForLoop6FS.ts index fa1948438bc..9661514d431 100644 --- a/tests/cases/fourslash/unusedVariableInForLoop6FS.ts +++ b/tests/cases/fourslash/unusedVariableInForLoop6FS.ts @@ -7,5 +7,8 @@ //// } //// } -verify.rangeAfterCodeFix("const {} of ", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); - +verify.codeFix({ + description: "Remove declaration for: 'elem'.", + index: 0, + newRangeContent: "const {} of", +}); diff --git a/tests/cases/fourslash/unusedVariableInForLoop6FSAddUnderscore.ts b/tests/cases/fourslash/unusedVariableInForLoop6FSAddUnderscore.ts index 4faa6893b7f..9f8c7b19f99 100644 --- a/tests/cases/fourslash/unusedVariableInForLoop6FSAddUnderscore.ts +++ b/tests/cases/fourslash/unusedVariableInForLoop6FSAddUnderscore.ts @@ -7,5 +7,9 @@ //// } //// } -verify.rangeAfterCodeFix("const _elem of", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 1); +verify.codeFix({ + description: "Prefix 'elem' with an underscore.", + index: 1, + newRangeContent: "const _elem of" +}); diff --git a/tests/cases/fourslash/unusedVariableInForLoop7FS.ts b/tests/cases/fourslash/unusedVariableInForLoop7FS.ts index 7f99863ba46..c42bf8bc97a 100644 --- a/tests/cases/fourslash/unusedVariableInForLoop7FS.ts +++ b/tests/cases/fourslash/unusedVariableInForLoop7FS.ts @@ -9,8 +9,11 @@ ////}|] //// -verify.rangeAfterCodeFix(`{ +verify.codeFix({ + description: "Remove declaration for: 'x'.", + newRangeContent: `{ for (const elem of ["a", "b", "c"]) { elem; } -}`, /*includeWhiteSpace*/ true); +}` +}); diff --git a/tests/cases/fourslash/unusedVariableInModule1.ts b/tests/cases/fourslash/unusedVariableInModule1.ts index e9fe9515e6d..7a0a3ad8601 100644 --- a/tests/cases/fourslash/unusedVariableInModule1.ts +++ b/tests/cases/fourslash/unusedVariableInModule1.ts @@ -6,4 +6,7 @@ //// [|var x: string; //// export var y: string;|] -verify.rangeAfterCodeFix("export var y: string;"); +verify.codeFix({ + description: "Remove declaration for: 'x'.", + newRangeContent: "export var y: string;", +}); diff --git a/tests/cases/fourslash/unusedVariableInModule2.ts b/tests/cases/fourslash/unusedVariableInModule2.ts index ac6e7120d8b..e8a1ae762d4 100644 --- a/tests/cases/fourslash/unusedVariableInModule2.ts +++ b/tests/cases/fourslash/unusedVariableInModule2.ts @@ -7,4 +7,7 @@ //// z; //// export var y: string; -verify.rangeAfterCodeFix("var z: number;"); +verify.codeFix({ + description: "Remove declaration for: 'x'.", + newRangeContent: "var z: number;", +}); diff --git a/tests/cases/fourslash/unusedVariableInModule3.ts b/tests/cases/fourslash/unusedVariableInModule3.ts index 0185b89e3a6..56b08f5499e 100644 --- a/tests/cases/fourslash/unusedVariableInModule3.ts +++ b/tests/cases/fourslash/unusedVariableInModule3.ts @@ -6,4 +6,7 @@ //// [|var x = function f1() {} //// export var y: string;|] -verify.rangeAfterCodeFix("export var y: string;"); +verify.codeFix({ + description: "Remove declaration for: 'x'.", + newRangeContent: "export var y: string;", +}); diff --git a/tests/cases/fourslash/unusedVariableInModule4.ts b/tests/cases/fourslash/unusedVariableInModule4.ts index 6d80d59c2ce..71890893b9e 100644 --- a/tests/cases/fourslash/unusedVariableInModule4.ts +++ b/tests/cases/fourslash/unusedVariableInModule4.ts @@ -7,4 +7,8 @@ //// x; //// export var y: string; -verify.rangeAfterCodeFix(`var x = function f1() {}`, /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0); +verify.codeFix({ + description: "Remove declaration for: 'm'.", + index: 0, + newRangeContent: `var x = function f1() {}`, +}); diff --git a/tests/cases/fourslash/unusedVariableInNamespace1.ts b/tests/cases/fourslash/unusedVariableInNamespace1.ts index c9f38473a51..6dd14233683 100644 --- a/tests/cases/fourslash/unusedVariableInNamespace1.ts +++ b/tests/cases/fourslash/unusedVariableInNamespace1.ts @@ -5,4 +5,7 @@ //// [|let a = "dummy entry";|] ////} -verify.rangeAfterCodeFix(""); +verify.codeFix({ + description: "Remove declaration for: 'a'.", + newRangeContent: "", +}); diff --git a/tests/cases/fourslash/unusedVariableInNamespace2.ts b/tests/cases/fourslash/unusedVariableInNamespace2.ts index 61fc3ec137c..9bf546f6f53 100644 --- a/tests/cases/fourslash/unusedVariableInNamespace2.ts +++ b/tests/cases/fourslash/unusedVariableInNamespace2.ts @@ -8,4 +8,7 @@ //// } ////} -verify.rangeAfterCodeFix(`let a = "dummy entry", c = 0;`); +verify.codeFix({ + description: "Remove declaration for: 'b'.", + newRangeContent: 'let a = "dummy entry", c = 0;', +}); diff --git a/tests/cases/fourslash/unusedVariableInNamespace3.ts b/tests/cases/fourslash/unusedVariableInNamespace3.ts index 7d2f3d251f3..85e1889c3e1 100644 --- a/tests/cases/fourslash/unusedVariableInNamespace3.ts +++ b/tests/cases/fourslash/unusedVariableInNamespace3.ts @@ -8,4 +8,7 @@ //// } ////} -verify.rangeAfterCodeFix(`let a = "dummy entry", b;`); +verify.codeFix({ + description: "Remove declaration for: 'c'.", + newRangeContent: 'let a = "dummy entry", b;', +}); From 9ece0cc956215ca1d82bf3f531a98ca44cdf5d66 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 10 Oct 2017 13:01:06 -0700 Subject: [PATCH 062/312] Move getSynthesizedDeepClone to services/utilities.ts --- src/compiler/factory.ts | 10 ---------- src/services/utilities.ts | 12 ++++++++++++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 7d703ffe062..fe183c5e806 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -71,16 +71,6 @@ namespace ts { return clone; } - /** - * Creates a deep, memberwise clone of a node with no source map location. - */ - /* @internal */ - export function getSynthesizedDeepClone(node: T | undefined): T | undefined { - return node - ? getSynthesizedClone(visitEachChild(node, child => getSynthesizedDeepClone(child), nullTransformationContext)) - : undefined; - } - // Literals export function createLiteral(value: string): StringLiteral; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 6166ceea28c..c22b981b4ff 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1334,4 +1334,16 @@ namespace ts { } return position; } + + /** + * Creates a deep, memberwise clone of a node with no source map location. + * + * WARNING: This is an expensive operation and is only intended to be used in refactorings + * and code fixes (because those are triggered by explicit user actions). + */ + export function getSynthesizedDeepClone(node: T | undefined): T | undefined { + return node + ? getSynthesizedClone(visitEachChild(node, child => getSynthesizedDeepClone(child), nullTransformationContext)) + : undefined; + } } From 18afd8a50d9d3430062b126c7404501c190376af Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 10 Oct 2017 13:08:57 -0700 Subject: [PATCH 063/312] Optimize getSynthesizedDeepClone --- src/services/utilities.ts | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/services/utilities.ts b/src/services/utilities.ts index c22b981b4ff..5affb8a8887 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1342,8 +1342,24 @@ namespace ts { * and code fixes (because those are triggered by explicit user actions). */ export function getSynthesizedDeepClone(node: T | undefined): T | undefined { - return node - ? getSynthesizedClone(visitEachChild(node, child => getSynthesizedDeepClone(child), nullTransformationContext)) - : undefined; + if (node === undefined) { + return undefined; + } + + const visited = visitEachChild(node, getSynthesizedDeepClone, nullTransformationContext); + if (visited === node) { + // This only happens for leaf nodes - internal nodes always see their children change. + return getSynthesizedClone(node); + } + + // PERF: As an optimization, rather than calling getSynthesizedClone, we'll update + // the new node created by visitEachChild with the extra changes getSynthesizedClone + // would have made. + + visited.pos = -1; + visited.end = -1; + visited.parent = undefined; + + return visited; } } From 75fea4f5c401c808a77744923b3ae712a0f540a9 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 10 Oct 2017 15:27:43 -0700 Subject: [PATCH 064/312] Update Authors for TS 2.6 --- .mailmap | 13 ++++++++++++- AUTHORS.md | 11 +++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index 7ae5cb19818..98f004c58dc 100644 --- a/.mailmap +++ b/.mailmap @@ -276,4 +276,15 @@ Francois Wouts Jan Melcher Jan Melcher Matt Mitchell Maxwell Paul Brickner -Tycho Grouwstra \ No newline at end of file +Tycho Grouwstra +Adrian Leonhard +Alex Chugaev +Henry Mercer +Ivan Enderlin +Joe Calzaretta +Magnus Kulke +Stas Vilchik +Taras Mankovski +Thomas den Hollander +Vakhurin Sergey +Zeeshan Ahmed \ No newline at end of file diff --git a/AUTHORS.md b/AUTHORS.md index 4f94a67f7dd..c554a588715 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -3,8 +3,10 @@ TypeScript is authored by: * Abubaker Bashir * Adam Freidin * Adi Dahiya +* Adrian Leonhard * Ahmad Farid * Akshar Patel +* Alex Chugaev * Alex Eagle * Alexander Kuvaev * Alexander Rusakov @@ -105,6 +107,7 @@ TypeScript is authored by: * Halasi Tamás * Harald Niesche * Hendrik Liebau +* Henry Mercer * Herrington Darkholme * Homa Wong * Iain Monro @@ -112,6 +115,7 @@ TypeScript is authored by: * Ika * Ingvar Stepanyan * Isiah Meadows +* Ivan Enderlin * Ivo Gabe de Wolff * Iwata Hidetaka * Jakub Młokosiewicz @@ -127,6 +131,7 @@ TypeScript is authored by: * Jeffrey Morlan * Jesse Schalken * Jiri Tobisek +* Joe Calzaretta * Joe Chung * Joel Day * Joey Wilson @@ -161,6 +166,7 @@ TypeScript is authored by: * Lucien Greathouse * Lukas Elmer * Magnus Hiie +* Magnus Kulke * Manish Giri * Marin Marinov * Marius Schulz @@ -232,13 +238,16 @@ TypeScript is authored by: * Soo Jae Hwang * Stan Thomas * Stanislav Sysoev +* Stas Vilchik * Steve Lucco * Sudheesh Singanamalla * Sébastien Arod * @T18970237136 * @t_ +* Taras Mankovski * Tarik Ozket * Tetsuharu Ohzeki +* Thomas den Hollander * Thomas Loubiou * Tien Hoanhtien * Tim Lancina @@ -253,6 +262,7 @@ TypeScript is authored by: * TruongSinh Tran-Nguyen * Tycho Grouwstra * Vadi Taslim +* Vakhurin Sergey * Vidar Tonaas Fauske * Viktor Zozulyak * Vilic Vane @@ -263,5 +273,6 @@ TypeScript is authored by: * York Yao * @yortus * Yuichi Nukiyama +* Zeeshan Ahmed * Zev Spitz * Zhengbo Li \ No newline at end of file From 611e0f7b4a86de98e96618296a1789a9c47e0223 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 10 Oct 2017 15:37:05 -0700 Subject: [PATCH 065/312] Do not rely on parent pointers in the binder (#19083) --- src/compiler/binder.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 4cacb5765db..35a62a644d8 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -143,6 +143,15 @@ namespace ts { let subtreeTransformFlags: TransformFlags = TransformFlags.None; let skipTransformFlagAggregation: boolean; + /** + * Inside the binder, we may create a diagnostic for an as-yet unbound node (with potentially no parent pointers, implying no accessible source file) + * If so, the node _must_ be in the current file (as that's the only way anything could have traversed to it to yield it as the error node) + * This version of `createDiagnosticForNode` uses the binder's context to account for this, and always yields correct diagnostics even in these situations. + */ + function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic { + return createDiagnosticForNodeInSourceFile(getSourceFileOfNode(node) || file, node, message, arg0, arg1, arg2); + } + function bindSourceFile(f: SourceFile, opts: CompilerOptions) { file = f; options = opts; From 249c2cbaf754164c3f6d0e7a03c53002575b4060 Mon Sep 17 00:00:00 2001 From: Charles Pierce Date: Tue, 10 Oct 2017 15:39:59 -0700 Subject: [PATCH 066/312] Maintain Export Modifier when Refactoring to ES6 Class #18435 (#19070) --- .../refactors/convertFunctionToEs6Class.ts | 10 ++++++++-- ...nvertFunctionToEs6Class_exportModifier1.ts | 19 +++++++++++++++++++ ...nvertFunctionToEs6Class_exportModifier2.ts | 19 +++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/convertFunctionToEs6Class_exportModifier1.ts create mode 100644 tests/cases/fourslash/convertFunctionToEs6Class_exportModifier2.ts diff --git a/src/services/refactors/convertFunctionToEs6Class.ts b/src/services/refactors/convertFunctionToEs6Class.ts index e4cd1a42083..110f64d1220 100644 --- a/src/services/refactors/convertFunctionToEs6Class.ts +++ b/src/services/refactors/convertFunctionToEs6Class.ts @@ -243,7 +243,8 @@ namespace ts.refactor.convertFunctionToES6Class { memberElements.unshift(createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, initializer.parameters, initializer.body)); } - const cls = createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, node.name, + const modifiers = getExportModifierFromSource(precedingNode); + const cls = createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements); // Don't call copyComments here because we'll already leave them in place return cls; @@ -255,10 +256,15 @@ namespace ts.refactor.convertFunctionToES6Class { memberElements.unshift(createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, node.parameters, node.body)); } - const cls = createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, node.name, + const modifiers = getExportModifierFromSource(node); + const cls = createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements); // Don't call copyComments here because we'll already leave them in place return cls; } + + function getExportModifierFromSource(source: Node) { + return filter(source.modifiers, modifier => modifier.kind === SyntaxKind.ExportKeyword); + } } } \ No newline at end of file diff --git a/tests/cases/fourslash/convertFunctionToEs6Class_exportModifier1.ts b/tests/cases/fourslash/convertFunctionToEs6Class_exportModifier1.ts new file mode 100644 index 00000000000..940a68a05b6 --- /dev/null +++ b/tests/cases/fourslash/convertFunctionToEs6Class_exportModifier1.ts @@ -0,0 +1,19 @@ +/// + +// @allowNonTsExtensions: true +// @Filename: test123.js +////export function /**/MyClass() { +////} +////MyClass.prototype.foo = function() { +////} + +verify.applicableRefactorAvailableAtMarker(""); +verify.fileAfterApplyingRefactorAtMarker("", +`export class MyClass { + constructor() { + } + foo() { + } +} +`, +'Convert to ES2015 class', 'convert'); diff --git a/tests/cases/fourslash/convertFunctionToEs6Class_exportModifier2.ts b/tests/cases/fourslash/convertFunctionToEs6Class_exportModifier2.ts new file mode 100644 index 00000000000..fb1276d4f03 --- /dev/null +++ b/tests/cases/fourslash/convertFunctionToEs6Class_exportModifier2.ts @@ -0,0 +1,19 @@ +/// + +// @allowNonTsExtensions: true +// @Filename: test123.js +////export const /**/foo = function() { +////}; +////foo.prototype.instanceMethod = function() { +////}; + +verify.applicableRefactorAvailableAtMarker(""); +verify.fileAfterApplyingRefactorAtMarker("", +`export class foo { + constructor() { + } + instanceMethod() { + } +} +`, +'Convert to ES2015 class', 'convert'); From d086b637c53b391922b8f2671a37f9f062e46102 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 10 Oct 2017 15:52:41 -0700 Subject: [PATCH 067/312] Remove `removeWhere` (#19082) --- src/compiler/core.ts | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 45a4a04b6ab..fb5000a58bf 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -356,21 +356,6 @@ namespace ts { return array; } - export function removeWhere(array: T[], f: (x: T) => boolean): boolean { - let outIndex = 0; - for (const item of array) { - if (!f(item)) { - array[outIndex] = item; - outIndex++; - } - } - if (outIndex !== array.length) { - array.length = outIndex; - return true; - } - return false; - } - export function filterMutate(array: T[], f: (x: T, i: number, array: T[]) => boolean): void { let outIndex = 0; for (let i = 0; i < array.length; i++) { From 55bbcff348b49d063efe91e5d22e957ddb358076 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 10 Oct 2017 16:36:09 -0700 Subject: [PATCH 068/312] Modify the changesAffectModuleResolution check --- src/compiler/watch.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 1ab80e659f4..4fc67c1cc8f 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -322,7 +322,7 @@ namespace ts { if (hasChangedCompilerOptions) { newLine = getNewLineCharacter(compilerOptions, system); - if (changesAffectModuleResolution(program && program.getCompilerOptions(), compilerOptions)) { + if (program && changesAffectModuleResolution(program.getCompilerOptions(), compilerOptions)) { resolutionCache.clear(); } } From cb326ed298599673a437ca719de032d8bed6501d Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 10 Oct 2017 16:39:13 -0700 Subject: [PATCH 069/312] Function to clear the per directory resolution --- src/compiler/resolutionCache.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index 680ed98a84a..faf5fb2a9f4 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -107,7 +107,9 @@ namespace ts { return { startRecordingFilesWithChangedResolutions, finishRecordingFilesWithChangedResolutions, - startCachingPerDirectoryResolution, + // perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update + // (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution) + startCachingPerDirectoryResolution: clearPerDirectoryResolutions, finishCachingPerDirectoryResolution, resolveModuleNames, resolveTypeReferenceDirectives, @@ -143,8 +145,7 @@ namespace ts { allFilesHaveInvalidatedResolution = false; // perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update // (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution) - perDirectoryResolvedModuleNames.clear(); - perDirectoryResolvedTypeReferenceDirectives.clear(); + clearPerDirectoryResolutions(); } function startRecordingFilesWithChangedResolutions() { @@ -168,9 +169,7 @@ namespace ts { return path => collected && collected.has(path); } - function startCachingPerDirectoryResolution() { - // perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update - // (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution) + function clearPerDirectoryResolutions() { perDirectoryResolvedModuleNames.clear(); perDirectoryResolvedTypeReferenceDirectives.clear(); } @@ -184,8 +183,7 @@ namespace ts { } }); - perDirectoryResolvedModuleNames.clear(); - perDirectoryResolvedTypeReferenceDirectives.clear(); + clearPerDirectoryResolutions(); } function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations { From edf0a95e891da48b6206710e13c55eb018870ddd Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 10 Oct 2017 16:41:54 -0700 Subject: [PATCH 070/312] Stop erroneous match of midfile sourceMappingUrl (#19084) --- src/harness/unittests/compileOnSave.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harness/unittests/compileOnSave.ts b/src/harness/unittests/compileOnSave.ts index 1e765054eee..fdec5b192ee 100644 --- a/src/harness/unittests/compileOnSave.ts +++ b/src/harness/unittests/compileOnSave.ts @@ -619,7 +619,7 @@ namespace ts.projectSystem { assert.isTrue(host.fileExists(expectedOutFileName)); const outFileContent = host.readFile(expectedOutFileName); verifyContentHasString(outFileContent, file1.content); - verifyContentHasString(outFileContent, `//# sourceMappingURL=${outFileName}.map`); + verifyContentHasString(outFileContent, `//# ${"sourceMappingURL"}=${outFileName}.map`); // Sometimes tools can sometimes see this line as a source mapping url comment, so we obfuscate it a little // Verify map file const expectedMapFileName = expectedOutFileName + ".map"; From e30a66d22f913b824427fd1323dfd82af20c8a76 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 10 Oct 2017 17:08:47 -0700 Subject: [PATCH 071/312] Add utitlity for stringContains --- src/compiler/checker.ts | 2 +- src/compiler/core.ts | 8 ++++++-- src/compiler/declarationEmitter.ts | 2 +- src/compiler/emitter.ts | 2 +- src/compiler/moduleNameResolver.ts | 2 +- src/compiler/resolutionCache.ts | 3 +-- src/server/editorServices.ts | 2 +- src/server/session.ts | 2 +- src/server/typingsInstaller/nodeTypingsInstaller.ts | 2 +- src/services/pathCompletions.ts | 4 ++-- src/services/refactors/extractSymbol.ts | 2 +- src/services/services.ts | 2 +- 12 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d47a77a7440..ab61d91ef15 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14012,7 +14012,7 @@ namespace ts { */ function isUnhyphenatedJsxName(name: string | __String) { // - is the only character supported in JSX attribute names that isn't valid in JavaScript identifiers - return (name as string).indexOf("-") < 0; + return !stringContains(name as string, "-"); } /** diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 45a4a04b6ab..442a262bbe2 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1663,7 +1663,7 @@ namespace ts { } export function isUrl(path: string) { - return path && !isRootedDiskPath(path) && path.indexOf("://") !== -1; + return path && !isRootedDiskPath(path) && stringContains(path, "://"); } export function pathIsRelative(path: string): boolean { @@ -1932,8 +1932,12 @@ namespace ts { return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos; } + export function stringContains(str: string, substring: string): boolean { + return str.indexOf(substring) !== -1; + } + export function hasExtension(fileName: string): boolean { - return getBaseFileName(fileName).indexOf(".") >= 0; + return stringContains(getBaseFileName(fileName), "."); } export function fileExtensionIs(path: string, extension: string): boolean { diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 3de20915029..48b97b048e9 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -172,7 +172,7 @@ namespace ts { function hasInternalAnnotation(range: CommentRange) { const comment = currentText.substring(range.pos, range.end); - return comment.indexOf("@internal") >= 0; + return stringContains(comment, "@internal"); } function stripInternal(node: Node) { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 8083b3841c8..da6c0e0fca8 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1226,7 +1226,7 @@ namespace ts { // check if numeric literal is a decimal literal that was originally written with a dot const text = getLiteralTextOfNode(expression); return !expression.numericLiteralFlags - && text.indexOf(tokenToString(SyntaxKind.DotToken)) < 0; + && !stringContains(text, tokenToString(SyntaxKind.DotToken)); } else if (isPropertyAccessExpression(expression) || isElementAccessExpression(expression)) { // check if constant enum value is integer diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 560beb39557..ac83dd41311 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -1061,7 +1061,7 @@ namespace ts { export function getPackageNameFromAtTypesDirectory(mangledName: string): string { const withoutAtTypePrefix = removePrefix(mangledName, "@types/"); if (withoutAtTypePrefix !== mangledName) { - return withoutAtTypePrefix.indexOf(mangledScopedPackageSeparator) !== -1 ? + return stringContains(withoutAtTypePrefix, mangledScopedPackageSeparator) ? "@" + withoutAtTypePrefix.replace(mangledScopedPackageSeparator, ts.directorySeparator) : withoutAtTypePrefix; } diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index 25545c0efbc..3f3955b294f 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -324,7 +324,7 @@ namespace ts { let dirPath = getDirectoryPath(failedLookupLocationPath); // If directory path contains node module, get the most parent node_modules directory for watching - while (dirPath.indexOf("/node_modules/") !== -1) { + while (stringContains(dirPath, "/node_modules/")) { dir = getDirectoryPath(dir); dirPath = getDirectoryPath(dirPath); } @@ -334,7 +334,6 @@ namespace ts { return { dir, dirPath }; } - // Use some ancestor of the root directory if (rootPath !== undefined) { while (!isInDirectoryPath(dirPath, rootPath)) { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 2916fb60c57..c683ff0080a 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1205,7 +1205,7 @@ namespace ts.server { projectRootPath?: NormalizedPath) { let searchPath = asNormalizedPath(getDirectoryPath(info.fileName)); - while (!projectRootPath || searchPath.indexOf(projectRootPath) >= 0) { + while (!projectRootPath || stringContains(searchPath, projectRootPath)) { const canonicalSearchPath = normalizedPathToPath(searchPath, this.currentDirectory, this.toCanonicalFileName); const tsconfigFileName = asNormalizedPath(combinePaths(searchPath, "tsconfig.json")); let result = action(tsconfigFileName, combinePaths(canonicalSearchPath, "tsconfig.json")); diff --git a/src/server/session.ts b/src/server/session.ts index 57dac7ec799..df9c77b9005 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1608,7 +1608,7 @@ namespace ts.server { } // No need to analyze lib.d.ts - const fileNamesInProject = fileNames.filter(value => value.indexOf("lib.d.ts") < 0); + const fileNamesInProject = fileNames.filter(value => !stringContains(value, "lib.d.ts")); if (fileNamesInProject.length === 0) { return; } diff --git a/src/server/typingsInstaller/nodeTypingsInstaller.ts b/src/server/typingsInstaller/nodeTypingsInstaller.ts index 6a31a114d23..f5d9b866376 100644 --- a/src/server/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/server/typingsInstaller/nodeTypingsInstaller.ts @@ -88,7 +88,7 @@ namespace ts.server.typingsInstaller { this.npmPath = npmLocation !== undefined ? npmLocation : getDefaultNPMLocation(process.argv[0]); // If the NPM path contains spaces and isn't wrapped in quotes, do so. - if (this.npmPath.indexOf(" ") !== -1 && this.npmPath[0] !== `"`) { + if (stringContains(this.npmPath, " ") && this.npmPath[0] !== `"`) { this.npmPath = `"${this.npmPath}"`; } if (this.log.isEnabled()) { diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index c41ed798b1d..e3bf9deac89 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -195,7 +195,7 @@ namespace ts.Completions.PathCompletions { const normalizedPrefixDirectory = getDirectoryPath(normalizedPrefix); const normalizedPrefixBase = getBaseFileName(normalizedPrefix); - const fragmentHasPath = fragment.indexOf(directorySeparator) !== -1; + const fragmentHasPath = stringContains(fragment, directorySeparator); // Try and expand the prefix to include any path from the fragment so that we can limit the readDirectory call const expandedPrefixDirectory = fragmentHasPath ? combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + getDirectoryPath(fragment)) : normalizedPrefixDirectory; @@ -235,7 +235,7 @@ namespace ts.Completions.PathCompletions { function enumeratePotentialNonRelativeModules(fragment: string, scriptPath: string, options: CompilerOptions, typeChecker: TypeChecker, host: LanguageServiceHost): string[] { // Check If this is a nested module - const isNestedModule = fragment.indexOf(directorySeparator) !== -1; + const isNestedModule = stringContains(fragment, directorySeparator); const moduleNameFragment = isNestedModule ? fragment.substr(0, fragment.lastIndexOf(directorySeparator)) : undefined; // Get modules that the type checker picked up diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index c16a290a30f..124a1f720bd 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -660,7 +660,7 @@ namespace ts.refactor.extractSymbol { function getUniqueName(baseName: string, fileText: string): string { let nameText = baseName; - for (let i = 1; fileText.indexOf(nameText) !== -1; i++) { + for (let i = 1; stringContains(fileText, nameText); i++) { nameText = `${baseName}_${i}`; } return nameText; diff --git a/src/services/services.ts b/src/services/services.ts index bc733a4e2fe..6bdc96d8b4d 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1952,7 +1952,7 @@ namespace ts { function isNodeModulesFile(path: string): boolean { const node_modulesFolderName = "/node_modules/"; - return path.indexOf(node_modulesFolderName) !== -1; + return stringContains(path, node_modulesFolderName); } } From 52d7c7278d7b6d3995777980e73466d630b53837 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 10 Oct 2017 17:14:32 -0700 Subject: [PATCH 072/312] Add comment about swallowing exception --- src/server/server.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/server/server.ts b/src/server/server.ts index 7917f6fb544..f24251ee6ac 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -753,11 +753,13 @@ namespace ts.server { const sys = ts.sys; // use watchGuard process on Windows when node version is 4 or later const useWatchGuard = process.platform === "win32" && getNodeMajorVersion() >= 4; - const originalWatchDirectory = sys.watchDirectory; + const originalWatchDirectory: ServerHost["watchDirectory"] = sys.watchDirectory.bind(sys); const noopWatcher: FileWatcher = { close: noop }; + // This is the function that catches the exceptions when watching directory, and yet lets project service continue to function + // Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point function watchDirectorySwallowingException(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher { try { - return originalWatchDirectory.call(sys, path, callback, recursive); + return originalWatchDirectory(path, callback, recursive); } catch (e) { logger.info(`Exception when creating directory watcher: ${e.message}`); From 856961b84ceb96098fba52ddac76c9d3ed0b0032 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 10 Oct 2017 17:20:10 -0700 Subject: [PATCH 073/312] Add regression test for #18668 (#19085) --- .../castFunctionExpressionShouldBeParenthesized.js | 5 +++++ ...astFunctionExpressionShouldBeParenthesized.symbols | 4 ++++ .../castFunctionExpressionShouldBeParenthesized.types | 11 +++++++++++ .../castFunctionExpressionShouldBeParenthesized.ts | 1 + 4 files changed, 21 insertions(+) create mode 100644 tests/baselines/reference/castFunctionExpressionShouldBeParenthesized.js create mode 100644 tests/baselines/reference/castFunctionExpressionShouldBeParenthesized.symbols create mode 100644 tests/baselines/reference/castFunctionExpressionShouldBeParenthesized.types create mode 100644 tests/cases/compiler/castFunctionExpressionShouldBeParenthesized.ts diff --git a/tests/baselines/reference/castFunctionExpressionShouldBeParenthesized.js b/tests/baselines/reference/castFunctionExpressionShouldBeParenthesized.js new file mode 100644 index 00000000000..e96b93bae85 --- /dev/null +++ b/tests/baselines/reference/castFunctionExpressionShouldBeParenthesized.js @@ -0,0 +1,5 @@ +//// [castFunctionExpressionShouldBeParenthesized.ts] +(function a() { } as any)().foo() + +//// [castFunctionExpressionShouldBeParenthesized.js] +(function a() { }().foo()); diff --git a/tests/baselines/reference/castFunctionExpressionShouldBeParenthesized.symbols b/tests/baselines/reference/castFunctionExpressionShouldBeParenthesized.symbols new file mode 100644 index 00000000000..975a9480c3c --- /dev/null +++ b/tests/baselines/reference/castFunctionExpressionShouldBeParenthesized.symbols @@ -0,0 +1,4 @@ +=== tests/cases/compiler/castFunctionExpressionShouldBeParenthesized.ts === +(function a() { } as any)().foo() +>a : Symbol(a, Decl(castFunctionExpressionShouldBeParenthesized.ts, 0, 1)) + diff --git a/tests/baselines/reference/castFunctionExpressionShouldBeParenthesized.types b/tests/baselines/reference/castFunctionExpressionShouldBeParenthesized.types new file mode 100644 index 00000000000..337c5163ff2 --- /dev/null +++ b/tests/baselines/reference/castFunctionExpressionShouldBeParenthesized.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/castFunctionExpressionShouldBeParenthesized.ts === +(function a() { } as any)().foo() +>(function a() { } as any)().foo() : any +>(function a() { } as any)().foo : any +>(function a() { } as any)() : any +>(function a() { } as any) : any +>function a() { } as any : any +>function a() { } : () => void +>a : () => void +>foo : any + diff --git a/tests/cases/compiler/castFunctionExpressionShouldBeParenthesized.ts b/tests/cases/compiler/castFunctionExpressionShouldBeParenthesized.ts new file mode 100644 index 00000000000..3fb1aaf7079 --- /dev/null +++ b/tests/cases/compiler/castFunctionExpressionShouldBeParenthesized.ts @@ -0,0 +1 @@ +(function a() { } as any)().foo() \ No newline at end of file From 5a1d846e76d01069d8fc6af9e3edf16c66990829 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 10 Oct 2017 17:34:16 -0700 Subject: [PATCH 074/312] Properly account for possibly referenced type parameters --- src/compiler/checker.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 58ac3bc52c0..ed131c8936c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8258,11 +8258,11 @@ namespace ts { // The first time an anonymous type is instantiated we compute and store a list of the type // parameters that are in scope (and therefore potentially referenced). For type literals that // aren't the right hand side of a generic type alias declaration we optimize by reducing the - // set of type parameters to those that are actually referenced somewhere in the literal. + // set of type parameters to those that are possibly referenced in the literal. const declaration = symbol.declarations[0]; const outerTypeParameters = getOuterTypeParameters(declaration, /*includeThisTypes*/ true) || emptyArray; typeParameters = symbol.flags & SymbolFlags.TypeLiteral && !target.aliasTypeArguments ? - filter(outerTypeParameters, tp => isTypeParameterReferencedWithin(tp, declaration)) : + filter(outerTypeParameters, tp => isTypeParameterPossiblyReferenced(tp, declaration)) : outerTypeParameters; links.typeParameters = typeParameters; if (typeParameters.length) { @@ -8288,8 +8288,17 @@ namespace ts { return type; } - function isTypeParameterReferencedWithin(tp: TypeParameter, node: Node) { - return tp.isThisType ? forEachChild(node, checkThis) : forEachChild(node, checkIdentifier); + function isTypeParameterPossiblyReferenced(tp: TypeParameter, node: Node) { + // If the type parameter doesn't have exactly one declaration, if there are invening statement blocks + // between the node and the type parameter declaration, or if the node contains actual references to the + // type parameter, we consider the type parameter possibly referenced. + if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) { + const container = tp.symbol.declarations[0].parent; + if (findAncestor(node, n => n.kind === SyntaxKind.Block ? "quit" : n === container)) { + return tp.isThisType ? forEachChild(node, checkThis) : forEachChild(node, checkIdentifier); + } + } + return true; function checkThis(node: Node): boolean { return node.kind === SyntaxKind.ThisType || forEachChild(node, checkThis); } From 83020dbbd6c43ecdbebe7bf6a65b573eb6038aa3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 10 Oct 2017 17:34:32 -0700 Subject: [PATCH 075/312] Add regression test --- .../indirectTypeParameterReferences.ts | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tests/cases/compiler/indirectTypeParameterReferences.ts diff --git a/tests/cases/compiler/indirectTypeParameterReferences.ts b/tests/cases/compiler/indirectTypeParameterReferences.ts new file mode 100644 index 00000000000..210a599354d --- /dev/null +++ b/tests/cases/compiler/indirectTypeParameterReferences.ts @@ -0,0 +1,24 @@ +// Repro from #19043 + +type B = {b: string} + +const flowtypes = (b: B) => { + type Combined = A & B + + const combined = (fn: (combined: Combined) => void) => null + const literal = (fn: (aPlusB: A & B) => void) => null + + return {combined, literal} +} + +const {combined, literal} = flowtypes<{a: string}>({b: 'b-value'}) + +literal(aPlusB => { + aPlusB.b + aPlusB.a +}) + +combined(comb => { + comb.b + comb.a +}) From d815ba13f8b67847935c386102288e754f3894de Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 10 Oct 2017 17:34:44 -0700 Subject: [PATCH 076/312] Accept new baselines --- .../indirectTypeParameterReferences.js | 43 +++++++++ .../indirectTypeParameterReferences.symbols | 75 ++++++++++++++++ .../indirectTypeParameterReferences.types | 88 +++++++++++++++++++ 3 files changed, 206 insertions(+) create mode 100644 tests/baselines/reference/indirectTypeParameterReferences.js create mode 100644 tests/baselines/reference/indirectTypeParameterReferences.symbols create mode 100644 tests/baselines/reference/indirectTypeParameterReferences.types diff --git a/tests/baselines/reference/indirectTypeParameterReferences.js b/tests/baselines/reference/indirectTypeParameterReferences.js new file mode 100644 index 00000000000..e6e807a4720 --- /dev/null +++ b/tests/baselines/reference/indirectTypeParameterReferences.js @@ -0,0 +1,43 @@ +//// [indirectTypeParameterReferences.ts] +// Repro from #19043 + +type B = {b: string} + +const flowtypes = (b: B) => { + type Combined = A & B + + const combined = (fn: (combined: Combined) => void) => null + const literal = (fn: (aPlusB: A & B) => void) => null + + return {combined, literal} +} + +const {combined, literal} = flowtypes<{a: string}>({b: 'b-value'}) + +literal(aPlusB => { + aPlusB.b + aPlusB.a +}) + +combined(comb => { + comb.b + comb.a +}) + + +//// [indirectTypeParameterReferences.js] +// Repro from #19043 +var flowtypes = function (b) { + var combined = function (fn) { return null; }; + var literal = function (fn) { return null; }; + return { combined: combined, literal: literal }; +}; +var _a = flowtypes({ b: 'b-value' }), combined = _a.combined, literal = _a.literal; +literal(function (aPlusB) { + aPlusB.b; + aPlusB.a; +}); +combined(function (comb) { + comb.b; + comb.a; +}); diff --git a/tests/baselines/reference/indirectTypeParameterReferences.symbols b/tests/baselines/reference/indirectTypeParameterReferences.symbols new file mode 100644 index 00000000000..0cb091a8622 --- /dev/null +++ b/tests/baselines/reference/indirectTypeParameterReferences.symbols @@ -0,0 +1,75 @@ +=== tests/cases/compiler/indirectTypeParameterReferences.ts === +// Repro from #19043 + +type B = {b: string} +>B : Symbol(B, Decl(indirectTypeParameterReferences.ts, 0, 0)) +>b : Symbol(b, Decl(indirectTypeParameterReferences.ts, 2, 10)) + +const flowtypes = (b: B) => { +>flowtypes : Symbol(flowtypes, Decl(indirectTypeParameterReferences.ts, 4, 5)) +>A : Symbol(A, Decl(indirectTypeParameterReferences.ts, 4, 19)) +>b : Symbol(b, Decl(indirectTypeParameterReferences.ts, 4, 22)) +>B : Symbol(B, Decl(indirectTypeParameterReferences.ts, 0, 0)) + + type Combined = A & B +>Combined : Symbol(Combined, Decl(indirectTypeParameterReferences.ts, 4, 32)) +>A : Symbol(A, Decl(indirectTypeParameterReferences.ts, 4, 19)) +>B : Symbol(B, Decl(indirectTypeParameterReferences.ts, 0, 0)) + + const combined = (fn: (combined: Combined) => void) => null +>combined : Symbol(combined, Decl(indirectTypeParameterReferences.ts, 7, 7)) +>fn : Symbol(fn, Decl(indirectTypeParameterReferences.ts, 7, 20)) +>combined : Symbol(combined, Decl(indirectTypeParameterReferences.ts, 7, 25)) +>Combined : Symbol(Combined, Decl(indirectTypeParameterReferences.ts, 4, 32)) + + const literal = (fn: (aPlusB: A & B) => void) => null +>literal : Symbol(literal, Decl(indirectTypeParameterReferences.ts, 8, 7)) +>fn : Symbol(fn, Decl(indirectTypeParameterReferences.ts, 8, 19)) +>aPlusB : Symbol(aPlusB, Decl(indirectTypeParameterReferences.ts, 8, 24)) +>A : Symbol(A, Decl(indirectTypeParameterReferences.ts, 4, 19)) +>B : Symbol(B, Decl(indirectTypeParameterReferences.ts, 0, 0)) + + return {combined, literal} +>combined : Symbol(combined, Decl(indirectTypeParameterReferences.ts, 10, 10)) +>literal : Symbol(literal, Decl(indirectTypeParameterReferences.ts, 10, 19)) +} + +const {combined, literal} = flowtypes<{a: string}>({b: 'b-value'}) +>combined : Symbol(combined, Decl(indirectTypeParameterReferences.ts, 13, 7)) +>literal : Symbol(literal, Decl(indirectTypeParameterReferences.ts, 13, 16)) +>flowtypes : Symbol(flowtypes, Decl(indirectTypeParameterReferences.ts, 4, 5)) +>a : Symbol(a, Decl(indirectTypeParameterReferences.ts, 13, 39)) +>b : Symbol(b, Decl(indirectTypeParameterReferences.ts, 13, 52)) + +literal(aPlusB => { +>literal : Symbol(literal, Decl(indirectTypeParameterReferences.ts, 13, 16)) +>aPlusB : Symbol(aPlusB, Decl(indirectTypeParameterReferences.ts, 15, 8)) + + aPlusB.b +>aPlusB.b : Symbol(b, Decl(indirectTypeParameterReferences.ts, 2, 10)) +>aPlusB : Symbol(aPlusB, Decl(indirectTypeParameterReferences.ts, 15, 8)) +>b : Symbol(b, Decl(indirectTypeParameterReferences.ts, 2, 10)) + + aPlusB.a +>aPlusB.a : Symbol(a, Decl(indirectTypeParameterReferences.ts, 13, 39)) +>aPlusB : Symbol(aPlusB, Decl(indirectTypeParameterReferences.ts, 15, 8)) +>a : Symbol(a, Decl(indirectTypeParameterReferences.ts, 13, 39)) + +}) + +combined(comb => { +>combined : Symbol(combined, Decl(indirectTypeParameterReferences.ts, 13, 7)) +>comb : Symbol(comb, Decl(indirectTypeParameterReferences.ts, 20, 9)) + + comb.b +>comb.b : Symbol(b, Decl(indirectTypeParameterReferences.ts, 2, 10)) +>comb : Symbol(comb, Decl(indirectTypeParameterReferences.ts, 20, 9)) +>b : Symbol(b, Decl(indirectTypeParameterReferences.ts, 2, 10)) + + comb.a +>comb.a : Symbol(a, Decl(indirectTypeParameterReferences.ts, 13, 39)) +>comb : Symbol(comb, Decl(indirectTypeParameterReferences.ts, 20, 9)) +>a : Symbol(a, Decl(indirectTypeParameterReferences.ts, 13, 39)) + +}) + diff --git a/tests/baselines/reference/indirectTypeParameterReferences.types b/tests/baselines/reference/indirectTypeParameterReferences.types new file mode 100644 index 00000000000..2a8ac9a8b08 --- /dev/null +++ b/tests/baselines/reference/indirectTypeParameterReferences.types @@ -0,0 +1,88 @@ +=== tests/cases/compiler/indirectTypeParameterReferences.ts === +// Repro from #19043 + +type B = {b: string} +>B : B +>b : string + +const flowtypes = (b: B) => { +>flowtypes : (b: B) => { combined: (fn: (combined: A & B) => void) => any; literal: (fn: (aPlusB: A & B) => void) => any; } +>(b: B) => { type Combined = A & B const combined = (fn: (combined: Combined) => void) => null const literal = (fn: (aPlusB: A & B) => void) => null return {combined, literal}} : (b: B) => { combined: (fn: (combined: A & B) => void) => any; literal: (fn: (aPlusB: A & B) => void) => any; } +>A : A +>b : B +>B : B + + type Combined = A & B +>Combined : A & B +>A : A +>B : B + + const combined = (fn: (combined: Combined) => void) => null +>combined : (fn: (combined: A & B) => void) => any +>(fn: (combined: Combined) => void) => null : (fn: (combined: A & B) => void) => any +>fn : (combined: A & B) => void +>combined : A & B +>Combined : A & B +>null : null + + const literal = (fn: (aPlusB: A & B) => void) => null +>literal : (fn: (aPlusB: A & B) => void) => any +>(fn: (aPlusB: A & B) => void) => null : (fn: (aPlusB: A & B) => void) => any +>fn : (aPlusB: A & B) => void +>aPlusB : A & B +>A : A +>B : B +>null : null + + return {combined, literal} +>{combined, literal} : { combined: (fn: (combined: A & B) => void) => any; literal: (fn: (aPlusB: A & B) => void) => any; } +>combined : (fn: (combined: A & B) => void) => any +>literal : (fn: (aPlusB: A & B) => void) => any +} + +const {combined, literal} = flowtypes<{a: string}>({b: 'b-value'}) +>combined : (fn: (combined: { a: string; } & B) => void) => any +>literal : (fn: (aPlusB: { a: string; } & B) => void) => any +>flowtypes<{a: string}>({b: 'b-value'}) : { combined: (fn: (combined: { a: string; } & B) => void) => any; literal: (fn: (aPlusB: { a: string; } & B) => void) => any; } +>flowtypes : (b: B) => { combined: (fn: (combined: A & B) => void) => any; literal: (fn: (aPlusB: A & B) => void) => any; } +>a : string +>{b: 'b-value'} : { b: string; } +>b : string +>'b-value' : "b-value" + +literal(aPlusB => { +>literal(aPlusB => { aPlusB.b aPlusB.a}) : any +>literal : (fn: (aPlusB: { a: string; } & B) => void) => any +>aPlusB => { aPlusB.b aPlusB.a} : (aPlusB: { a: string; } & B) => void +>aPlusB : { a: string; } & B + + aPlusB.b +>aPlusB.b : string +>aPlusB : { a: string; } & B +>b : string + + aPlusB.a +>aPlusB.a : string +>aPlusB : { a: string; } & B +>a : string + +}) + +combined(comb => { +>combined(comb => { comb.b comb.a}) : any +>combined : (fn: (combined: { a: string; } & B) => void) => any +>comb => { comb.b comb.a} : (comb: { a: string; } & B) => void +>comb : { a: string; } & B + + comb.b +>comb.b : string +>comb : { a: string; } & B +>b : string + + comb.a +>comb.a : string +>comb : { a: string; } & B +>a : string + +}) + From c5b4f5e7e72516f2cb946a189e1b06fed17ef199 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 10 Oct 2017 16:28:44 -0700 Subject: [PATCH 077/312] Use filterMutate instead of removeWhere --- src/harness/unittests/telemetry.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/harness/unittests/telemetry.ts b/src/harness/unittests/telemetry.ts index d2a54fdc1bb..25120af45c1 100644 --- a/src/harness/unittests/telemetry.ts +++ b/src/harness/unittests/telemetry.ts @@ -257,11 +257,12 @@ namespace ts.projectSystem { getEventsWithName(eventName: T["eventName"]): ReadonlyArray { let events: T[]; - removeWhere(this.events, event => { + filterMutate(this.events, event => { if (event.eventName === eventName) { (events || (events = [])).push(event as T); - return true; + return false; } + return true; }); return events || emptyArray; } @@ -291,14 +292,15 @@ namespace ts.projectSystem { getEvent(eventName: T["eventName"]): T["data"] { let event: server.ProjectServiceEvent; - removeWhere(this.events, e => { + filterMutate(this.events, e => { if (e.eventName === eventName) { if (event) { assert(false, "more than one event found"); } event = e; - return true; + return false; } + return true; }); assert.equal(event.eventName, eventName); return event.data; From bb4abbd95ecb20ba3e7e4ca12dfe41b1c80533c5 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 10 Oct 2017 17:37:02 -0700 Subject: [PATCH 078/312] Do not generate config file diagnostics event when the file opened doesnot belong to the configured project --- src/harness/unittests/tsserverProjectSystem.ts | 11 ++--------- src/server/editorServices.ts | 10 ++++------ 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 3d244fd30f8..04b848e7cdf 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -3168,7 +3168,7 @@ namespace ts.projectSystem { serverEventManager.checkEventCountOfType("configFileDiag", 3); }); - it("are generated when the config file doesnot include file opened but has errors", () => { + it("are not generated when the config file doesnot include file opened and config file has errors", () => { const serverEventManager = new TestServerEventManager(); const file = { path: "/a/b/app.ts", @@ -3195,14 +3195,7 @@ namespace ts.projectSystem { eventHandler: serverEventManager.handler }); openFilesForSession([file2], session); - serverEventManager.checkEventCountOfType("configFileDiag", 1); - for (const event of serverEventManager.events) { - if (event.eventName === "configFileDiag") { - assert.equal(event.data.configFileName, configFile.path); - assert.equal(event.data.triggerFile, file2.path); - return; - } - } + serverEventManager.checkEventCountOfType("configFileDiag", 0); }); it("are not generated when the config file doesnot include file opened and doesnt contain any errors", () => { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index fd229747390..765a3188443 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1933,12 +1933,10 @@ namespace ts.server { // At this point if file is part of any any configured or external project, then it would be present in the containing projects // So if it still doesnt have any containing projects, it needs to be part of inferred project if (info.isOrphan()) { - // Since the file isnt part of configured project, - // report config file and its error only if config file found had errors (and hence may be didnt include the file) - if (sendConfigFileDiagEvent && !project.getAllProjectErrors().length) { - configFileName = undefined; - sendConfigFileDiagEvent = false; - } + // Since the file isnt part of configured project, do not send config file event + configFileName = undefined; + sendConfigFileDiagEvent = false; + this.assignOrphanScriptInfoToInferredProject(info, projectRootPath); } this.addToListOfOpenFiles(info); From d0168af142dfcaa0310a6825cfd67e5e0e51da1c Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 10 Oct 2017 17:59:43 -0700 Subject: [PATCH 079/312] Functioning parallel unittests (#18956) --- src/harness/parallel/host.ts | 50 ++++++++++++++++++++-------- src/harness/parallel/shared.ts | 4 +-- src/harness/parallel/worker.ts | 60 ++++++++++++++++++++++++---------- 3 files changed, 81 insertions(+), 33 deletions(-) diff --git a/src/harness/parallel/host.ts b/src/harness/parallel/host.ts index 2aaa4f78728..d7bba70408e 100644 --- a/src/harness/parallel/host.ts +++ b/src/harness/parallel/host.ts @@ -38,20 +38,45 @@ namespace Harness.Parallel.Host { return undefined; } - function hashName(runner: TestRunnerKind, test: string) { + function hashName(runner: TestRunnerKind | "unittest", test: string) { return `tsrunner-${runner}://${test}`; } + let tasks: { runner: TestRunnerKind | "unittest", file: string, size: number }[] = []; + const newTasks: { runner: TestRunnerKind | "unittest", file: string, size: number }[] = []; + let unknownValue: string | undefined; export function start() { - initializeProgressBarsDependencies(); - console.log("Discovering tests..."); - const discoverStart = +(new Date()); - const { statSync }: { statSync(path: string): { size: number }; } = require("fs"); - let tasks: { runner: TestRunnerKind, file: string, size: number }[] = []; - const newTasks: { runner: TestRunnerKind, file: string, size: number }[] = []; const perfData = readSavedPerfData(configOption); let totalCost = 0; - let unknownValue: string | undefined; + if (runUnitTests) { + (global as any).describe = (suiteName: string) => { + // Note, sub-suites are not indexed (we assume such granularity is not required) + let size = 0; + if (perfData) { + size = perfData[hashName("unittest", suiteName)]; + if (size === undefined) { + newTasks.push({ runner: "unittest", file: suiteName, size: 0 }); + unknownValue = suiteName; + return; + } + } + tasks.push({ runner: "unittest", file: suiteName, size }); + totalCost += size; + }; + } + else { + (global as any).describe = ts.noop; + } + + setTimeout(() => startDelayed(perfData, totalCost), 0); // Do real startup on next tick, so all unit tests have been collected + } + + function startDelayed(perfData: {[testHash: string]: number}, totalCost: number) { + initializeProgressBarsDependencies(); + console.log(`Discovered ${tasks.length} unittest suites` + (newTasks.length ? ` and ${newTasks.length} new suites.` : ".")); + console.log("Discovering runner-based tests..."); + const discoverStart = +(new Date()); + const { statSync }: { statSync(path: string): { size: number }; } = require("fs"); for (const runner of runners) { const files = runner.enumerateTestFiles(); for (const file of files) { @@ -87,8 +112,7 @@ namespace Harness.Parallel.Host { } tasks.sort((a, b) => a.size - b.size); tasks = tasks.concat(newTasks); - // 1 fewer batches than threads to account for unittests running on the final thread - const batchCount = runners.length === 1 ? workerCount : workerCount - 1; + const batchCount = workerCount; const packfraction = 0.9; const chunkSize = 1000; // ~1KB or 1s for sending batches near the end of a test const batchSize = (totalCost / workerCount) * packfraction; // Keep spare tests for unittest thread in reserve @@ -113,7 +137,7 @@ namespace Harness.Parallel.Host { let closedWorkers = 0; for (let i = 0; i < workerCount; i++) { // TODO: Just send the config over the IPC channel or in the command line arguments - const config: TestConfig = { light: Harness.lightMode, listenForWork: true, runUnitTests: runners.length === 1 ? false : i === workerCount - 1 }; + const config: TestConfig = { light: Harness.lightMode, listenForWork: true, runUnitTests: runners.length !== 1 }; const configPath = ts.combinePaths(taskConfigsFolder, `task-config${i}.json`); Harness.IO.writeFile(configPath, JSON.stringify(config)); const child = fork(__filename, [`--config="${configPath}"`]); @@ -187,7 +211,7 @@ namespace Harness.Parallel.Host { // It's only really worth doing an initial batching if there are a ton of files to go through if (totalFiles > 1000) { console.log("Batching initial test lists..."); - const batches: { runner: TestRunnerKind, file: string, size: number }[][] = new Array(batchCount); + const batches: { runner: TestRunnerKind | "unittest", file: string, size: number }[][] = new Array(batchCount); const doneBatching = new Array(batchCount); let scheduledTotal = 0; batcher: while (true) { @@ -230,7 +254,7 @@ namespace Harness.Parallel.Host { if (payload) { worker.send({ type: "batch", payload }); } - else { // Unittest thread - send off just one test + else { // Out of batches, send off just one test const payload = tasks.pop(); ts.Debug.assert(!!payload); // The reserve kept above should ensure there is always an initial task available, even in suboptimal scenarios worker.send({ type: "test", payload }); diff --git a/src/harness/parallel/shared.ts b/src/harness/parallel/shared.ts index 85d885c14a1..2eb7777f828 100644 --- a/src/harness/parallel/shared.ts +++ b/src/harness/parallel/shared.ts @@ -1,14 +1,14 @@ /// /// namespace Harness.Parallel { - export type ParallelTestMessage = { type: "test", payload: { runner: TestRunnerKind, file: string } } | never; + export type ParallelTestMessage = { type: "test", payload: { runner: TestRunnerKind | "unittest", file: string } } | never; export type ParallelBatchMessage = { type: "batch", payload: ParallelTestMessage["payload"][] } | never; export type ParallelCloseMessage = { type: "close" } | never; export type ParallelHostMessage = ParallelTestMessage | ParallelCloseMessage | ParallelBatchMessage; export type ParallelErrorMessage = { type: "error", payload: { error: string, stack: string, name?: string[] } } | never; export type ErrorInfo = ParallelErrorMessage["payload"] & { name: string[] }; - export type ParallelResultMessage = { type: "result", payload: { passing: number, errors: ErrorInfo[], duration: number, runner: TestRunnerKind, file: string } } | never; + export type ParallelResultMessage = { type: "result", payload: { passing: number, errors: ErrorInfo[], duration: number, runner: TestRunnerKind | "unittest", file: string } } | never; export type ParallelBatchProgressMessage = { type: "progress", payload: ParallelResultMessage["payload"] } | never; export type ParallelClientMessage = ParallelErrorMessage | ParallelResultMessage | ParallelBatchProgressMessage; } \ No newline at end of file diff --git a/src/harness/parallel/worker.ts b/src/harness/parallel/worker.ts index 7e95831535a..c32b9660a39 100644 --- a/src/harness/parallel/worker.ts +++ b/src/harness/parallel/worker.ts @@ -1,22 +1,13 @@ namespace Harness.Parallel.Worker { let errors: ErrorInfo[] = []; let passing = 0; - let reportedUnitTests = false; type Executor = {name: string, callback: Function, kind: "suite" | "test"} | never; function resetShimHarnessAndExecute(runner: RunnerBase) { - if (reportedUnitTests) { - errors = []; - passing = 0; - testList.length = 0; - } - reportedUnitTests = true; - if (testList.length) { - // Execute unit tests - testList.forEach(({ name, callback, kind }) => executeCallback(name, callback, kind)); - testList.length = 0; - } + errors = []; + passing = 0; + testList.length = 0; const start = +(new Date()); runner.initializeTests(); testList.forEach(({ name, callback, kind }) => executeCallback(name, callback, kind)); @@ -226,13 +217,46 @@ namespace Harness.Parallel.Worker { shimMochaHarness(); } - function handleTest(runner: TestRunnerKind, file: string) { - if (!runners.has(runner)) { - runners.set(runner, createRunner(runner)); + function handleTest(runner: TestRunnerKind | "unittest", file: string) { + collectUnitTestsIfNeeded(); + if (runner === unittest) { + return executeUnitTest(file); + } + else { + if (!runners.has(runner)) { + runners.set(runner, createRunner(runner)); + } + const instance = runners.get(runner); + instance.tests = [file]; + return { ...resetShimHarnessAndExecute(instance), runner, file }; } - const instance = runners.get(runner); - instance.tests = [file]; - return { ...resetShimHarnessAndExecute(instance), runner, file }; } } + + const unittest: "unittest" = "unittest"; + let unitTests: {[name: string]: Function}; + function collectUnitTestsIfNeeded() { + if (!unitTests && testList.length) { + unitTests = {}; + for (const test of testList) { + unitTests[test.name] = test.callback; + } + testList.length = 0; + } + } + + function executeUnitTest(name: string) { + if (!unitTests) { + throw new Error(`Asked to run unit test ${name}, but no unit tests were discovered!`); + } + if (unitTests[name]) { + errors = []; + passing = 0; + const start = +(new Date()); + executeSuiteCallback(name, unitTests[name]); + delete unitTests[name]; + return { file: name, runner: unittest, errors, passing, duration: +(new Date()) - start }; + } + throw new Error(`Unit test with name "${name}" was asked to be run, but such a test does not exist!`); + } } \ No newline at end of file From 0e2eb3a2b88628680ca3ef56703d3679a8439f80 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 10 Oct 2017 18:25:26 -0700 Subject: [PATCH 080/312] Combine the event manager testing --- src/harness/unittests/telemetry.ts | 98 ++--------- .../unittests/tsserverProjectSystem.ts | 154 ++++++++++-------- 2 files changed, 101 insertions(+), 151 deletions(-) diff --git a/src/harness/unittests/telemetry.ts b/src/harness/unittests/telemetry.ts index 25120af45c1..9bb2db73801 100644 --- a/src/harness/unittests/telemetry.ts +++ b/src/harness/unittests/telemetry.ts @@ -5,9 +5,9 @@ namespace ts.projectSystem { describe("project telemetry", () => { it("does nothing for inferred project", () => { const file = makeFile("/a.js"); - const et = new EventTracker([file]); + const et = new TestServerEventManager([file]); et.service.openClientFile(file.path); - assert.equal(et.getEventsWithName(ts.server.ProjectInfoTelemetryEvent).length, 0); + et.hasZeroEvent(ts.server.ProjectInfoTelemetryEvent); }); it("only sends an event once", () => { @@ -15,7 +15,7 @@ namespace ts.projectSystem { const file2 = makeFile("/b.ts"); const tsconfig = makeFile("/a/tsconfig.json", {}); - const et = new EventTracker([file, file2, tsconfig]); + const et = new TestServerEventManager([file, file2, tsconfig]); et.service.openClientFile(file.path); et.assertProjectInfoTelemetryEvent({}, tsconfig.path); @@ -25,12 +25,12 @@ namespace ts.projectSystem { et.service.openClientFile(file2.path); checkNumberOfProjects(et.service, { inferredProjects: 1 }); - assert.equal(et.getEventsWithName(ts.server.ProjectInfoTelemetryEvent).length, 0); + et.hasZeroEvent(ts.server.ProjectInfoTelemetryEvent); et.service.openClientFile(file.path); checkNumberOfProjects(et.service, { configuredProjects: 1, inferredProjects: 1 }); - assert.equal(et.getEventsWithName(ts.server.ProjectInfoTelemetryEvent).length, 0); + et.hasZeroEvent(ts.server.ProjectInfoTelemetryEvent); }); it("counts files by extension", () => { @@ -39,7 +39,7 @@ namespace ts.projectSystem { const compilerOptions: ts.CompilerOptions = { allowJs: true }; const tsconfig = makeFile("/tsconfig.json", { compilerOptions, include: ["src"] }); - const et = new EventTracker([...files, notIncludedFile, tsconfig]); + const et = new TestServerEventManager([...files, notIncludedFile, tsconfig]); et.service.openClientFile(files[0].path); et.assertProjectInfoTelemetryEvent({ fileStats: { ts: 2, tsx: 1, js: 1, jsx: 1, dts: 1 }, @@ -50,7 +50,7 @@ namespace ts.projectSystem { it("works with external project", () => { const file1 = makeFile("/a.ts"); - const et = new EventTracker([file1]); + const et = new TestServerEventManager([file1]); const compilerOptions: ts.server.protocol.CompilerOptions = { strict: true }; const projectFileName = "/hunter2/foo.csproj"; @@ -148,7 +148,7 @@ namespace ts.projectSystem { (compilerOptions as any).unknownCompilerOption = "hunter2"; // These are always ignored. const tsconfig = makeFile("/tsconfig.json", { compilerOptions, files: ["/a.ts"] }); - const et = new EventTracker([file, tsconfig]); + const et = new TestServerEventManager([file, tsconfig]); et.service.openClientFile(file.path); et.assertProjectInfoTelemetryEvent({ @@ -168,7 +168,7 @@ namespace ts.projectSystem { compileOnSave: true, }); - const et = new EventTracker([tsconfig, file]); + const et = new TestServerEventManager([tsconfig, file]); et.service.openClientFile(file.path); et.assertProjectInfoTelemetryEvent({ extends: true, @@ -198,7 +198,7 @@ namespace ts.projectSystem { exclude: [], }, }); - const et = new EventTracker([jsconfig, file]); + const et = new TestServerEventManager([jsconfig, file]); et.service.openClientFile(file.path); et.assertProjectInfoTelemetryEvent({ projectId: Harness.mockHash("/jsconfig.json"), @@ -216,7 +216,7 @@ namespace ts.projectSystem { it("detects whether language service was disabled", () => { const file = makeFile("/a.js"); const tsconfig = makeFile("/jsconfig.json", {}); - const et = new EventTracker([tsconfig, file]); + const et = new TestServerEventManager([tsconfig, file]); et.host.getFileSize = () => server.maxProgramSizeForNonTsFiles + 1; et.service.openClientFile(file.path); et.getEvent(server.ProjectLanguageServiceStateEvent); @@ -235,83 +235,7 @@ namespace ts.projectSystem { }); }); - class EventTracker { - private events: server.ProjectServiceEvent[] = []; - readonly service: TestProjectService; - readonly host: projectSystem.TestServerHost; - - constructor(files: projectSystem.FileOrFolder[]) { - this.host = createServerHost(files); - this.service = createProjectService(this.host, { - eventHandler: event => { - this.events.push(event); - }, - }); - } - - getEvents(): ReadonlyArray { - const events = this.events; - this.events = []; - return events; - } - - getEventsWithName(eventName: T["eventName"]): ReadonlyArray { - let events: T[]; - filterMutate(this.events, event => { - if (event.eventName === eventName) { - (events || (events = [])).push(event as T); - return false; - } - return true; - }); - return events || emptyArray; - } - - assertProjectInfoTelemetryEvent(partial: Partial, configFile?: string): void { - assert.deepEqual(this.getEvent(ts.server.ProjectInfoTelemetryEvent), { - projectId: Harness.mockHash(configFile || "/tsconfig.json"), - fileStats: fileStats({ ts: 1 }), - compilerOptions: {}, - extends: false, - files: false, - include: false, - exclude: false, - compileOnSave: false, - typeAcquisition: { - enable: false, - exclude: false, - include: false, - }, - configFileName: "tsconfig.json", - projectType: "configured", - languageServiceEnabled: true, - version: ts.version, - ...partial, - }); - } - - getEvent(eventName: T["eventName"]): T["data"] { - let event: server.ProjectServiceEvent; - filterMutate(this.events, e => { - if (e.eventName === eventName) { - if (event) { - assert(false, "more than one event found"); - } - event = e; - return false; - } - return true; - }); - assert.equal(event.eventName, eventName); - return event.data; - } - } - function makeFile(path: string, content: {} = ""): projectSystem.FileOrFolder { return { path, content: isString(content) ? "" : JSON.stringify(content) }; } - - function fileStats(nonZeroStats: Partial): server.FileStats { - return { ts: 0, tsx: 0, dts: 0, js: 0, jsx: 0, ...nonZeroStats }; - } } diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 04b848e7cdf..d5b9b9d62fc 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -132,16 +132,78 @@ namespace ts.projectSystem { return map(fileNames, toExternalFile); } - class TestServerEventManager { - public events: server.ProjectServiceEvent[] = []; + export function fileStats(nonZeroStats: Partial): server.FileStats { + return { ts: 0, tsx: 0, dts: 0, js: 0, jsx: 0, ...nonZeroStats }; + } - handler: server.ProjectServiceEventHandler = (event: server.ProjectServiceEvent) => { - this.events.push(event); + export class TestServerEventManager { + private events: server.ProjectServiceEvent[] = []; + readonly session: TestSession; + readonly service: server.ProjectService; + readonly host: projectSystem.TestServerHost; + constructor(files: projectSystem.FileOrFolder[]) { + this.host = createServerHost(files); + this.session = createSession(this.host, { + canUseEvents: true, + eventHandler: event => this.events.push(event), + }); + this.service = this.session.getProjectService(); } - checkEventCountOfType(eventType: "configFileDiag", expectedCount: number) { - const eventsOfType = filter(this.events, e => e.eventName === eventType); - assert.equal(eventsOfType.length, expectedCount, `The actual event counts of type ${eventType} is ${eventsOfType.length}, while expected ${expectedCount}`); + getEvents(): ReadonlyArray { + const events = this.events; + this.events = []; + return events; + } + + getEvent(eventName: T["eventName"]): T["data"] { + let eventData: T["data"]; + filterMutate(this.events, e => { + if (e.eventName === eventName) { + if (eventData !== undefined) { + assert(false, "more than one event found"); + } + eventData = e.data; + return false; + } + return true; + }); + assert.isDefined(eventData); + return eventData; + } + + hasZeroEvent(eventName: T["eventName"]) { + const eventCount = countWhere(this.events, event => event.eventName === eventName); + assert.equal(eventCount, 0); + } + + checkSingleConfigFileDiagEvent(configFileName: string, triggerFile: string) { + const eventData = this.getEvent(server.ConfigFileDiagEvent); + assert.equal(eventData.configFileName, configFileName); + assert.equal(eventData.triggerFile, triggerFile); + } + + assertProjectInfoTelemetryEvent(partial: Partial, configFile?: string): void { + assert.deepEqual(this.getEvent(ts.server.ProjectInfoTelemetryEvent), { + projectId: Harness.mockHash(configFile || "/tsconfig.json"), + fileStats: fileStats({ ts: 1 }), + compilerOptions: {}, + extends: false, + files: false, + include: false, + exclude: false, + compileOnSave: false, + typeAcquisition: { + enable: false, + exclude: false, + include: false, + }, + configFileName: "tsconfig.json", + projectType: "configured", + languageServiceEnabled: true, + version: ts.version, + ...partial, + }); } } @@ -3076,7 +3138,6 @@ namespace ts.projectSystem { describe("Configure file diagnostics events", () => { it("are generated when the config file has errors", () => { - const serverEventManager = new TestServerEventManager(); const file = { path: "/a/b/app.ts", content: "let x = 10" @@ -3090,26 +3151,12 @@ namespace ts.projectSystem { } }` }; - - const host = createServerHost([file, configFile]); - const session = createSession(host, { - canUseEvents: true, - eventHandler: serverEventManager.handler - }); - openFilesForSession([file], session); - serverEventManager.checkEventCountOfType("configFileDiag", 1); - - for (const event of serverEventManager.events) { - if (event.eventName === "configFileDiag") { - assert.equal(event.data.configFileName, configFile.path); - assert.equal(event.data.triggerFile, file.path); - return; - } - } + const serverEventManager = new TestServerEventManager([file, configFile]); + openFilesForSession([file], serverEventManager.session); + serverEventManager.checkSingleConfigFileDiagEvent(configFile.path, file.path); }); it("are generated when the config file doesn't have errors", () => { - const serverEventManager = new TestServerEventManager(); const file = { path: "/a/b/app.ts", content: "let x = 10" @@ -3120,18 +3167,12 @@ namespace ts.projectSystem { "compilerOptions": {} }` }; - - const host = createServerHost([file, configFile]); - const session = createSession(host, { - canUseEvents: true, - eventHandler: serverEventManager.handler - }); - openFilesForSession([file], session); - serverEventManager.checkEventCountOfType("configFileDiag", 1); + const serverEventManager = new TestServerEventManager([file, configFile]); + openFilesForSession([file], serverEventManager.session); + serverEventManager.checkSingleConfigFileDiagEvent(configFile.path, file.path); }); it("are generated when the config file changes", () => { - const serverEventManager = new TestServerEventManager(); const file = { path: "/a/b/app.ts", content: "let x = 10" @@ -3143,33 +3184,28 @@ namespace ts.projectSystem { }` }; - const host = createServerHost([file, configFile]); - const session = createSession(host, { - canUseEvents: true, - eventHandler: serverEventManager.handler - }); - openFilesForSession([file], session); - serverEventManager.checkEventCountOfType("configFileDiag", 1); + const serverEventManager = new TestServerEventManager([file, configFile]); + openFilesForSession([file], serverEventManager.session); + serverEventManager.checkSingleConfigFileDiagEvent(configFile.path, file.path); configFile.content = `{ "compilerOptions": { "haha": 123 } }`; - host.reloadFS([file, configFile]); - host.runQueuedTimeoutCallbacks(); - serverEventManager.checkEventCountOfType("configFileDiag", 2); + serverEventManager.host.reloadFS([file, configFile]); + serverEventManager.host.runQueuedTimeoutCallbacks(); + serverEventManager.checkSingleConfigFileDiagEvent(configFile.path, configFile.path); configFile.content = `{ "compilerOptions": {} }`; - host.reloadFS([file, configFile]); - host.runQueuedTimeoutCallbacks(); - serverEventManager.checkEventCountOfType("configFileDiag", 3); + serverEventManager.host.reloadFS([file, configFile]); + serverEventManager.host.runQueuedTimeoutCallbacks(); + serverEventManager.checkSingleConfigFileDiagEvent(configFile.path, configFile.path); }); it("are not generated when the config file doesnot include file opened and config file has errors", () => { - const serverEventManager = new TestServerEventManager(); const file = { path: "/a/b/app.ts", content: "let x = 10" @@ -3188,18 +3224,12 @@ namespace ts.projectSystem { "files": ["app.ts"] }` }; - - const host = createServerHost([file, file2, libFile, configFile]); - const session = createSession(host, { - canUseEvents: true, - eventHandler: serverEventManager.handler - }); - openFilesForSession([file2], session); - serverEventManager.checkEventCountOfType("configFileDiag", 0); + const serverEventManager = new TestServerEventManager([file, file2, libFile, configFile]); + openFilesForSession([file2], serverEventManager.session); + serverEventManager.hasZeroEvent("configFileDiag"); }); it("are not generated when the config file doesnot include file opened and doesnt contain any errors", () => { - const serverEventManager = new TestServerEventManager(); const file = { path: "/a/b/app.ts", content: "let x = 10" @@ -3215,13 +3245,9 @@ namespace ts.projectSystem { }` }; - const host = createServerHost([file, file2, libFile, configFile]); - const session = createSession(host, { - canUseEvents: true, - eventHandler: serverEventManager.handler - }); - openFilesForSession([file2], session); - serverEventManager.checkEventCountOfType("configFileDiag", 0); + const serverEventManager = new TestServerEventManager([file, file2, libFile, configFile]); + openFilesForSession([file2], serverEventManager.session); + serverEventManager.hasZeroEvent("configFileDiag"); }); }); From 9767d77143b89ea62b6a48bb8163ba68ab27213f Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 10 Oct 2017 18:41:45 -0700 Subject: [PATCH 081/312] Update comment on emit handler functions --- src/compiler/builder.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 03eb5b7e8ae..093c6ec4d03 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -73,12 +73,17 @@ namespace ts { */ onRemoveSourceFile(path: Path): void; /** - * Called when sourceFile is changed + * For all source files, either "onUpdateSourceFile" or "onUpdateSourceFileWithSameVersion" will be called. + * If the builder is sure that the source file needs an update, "onUpdateSourceFile" will be called; + * otherwise "onUpdateSourceFileWithSameVersion" will be called. + * This should return whether the source file should be marked as changed (meaning that something associated with file has changed, e.g. module resolution) */ onUpdateSourceFile(program: Program, sourceFile: SourceFile): void; /** - * Called when source file has not changed - * If returned true, builder will mark the file as changed (noting that something associated with file has changed eg. module resolution) + * For all source files, either "onUpdateSourceFile" or "onUpdateSourceFileWithSameVersion" will be called. + * If the builder is sure that the source file needs an update, "onUpdateSourceFile" will be called; + * otherwise "onUpdateSourceFileWithSameVersion" will be called. + * This should return whether the source file should be marked as changed (meaning that something associated with file has changed, e.g. module resolution) */ onUpdateSourceFileWithSameVersion(program: Program, sourceFile: SourceFile): boolean; /** From 993890f06c422ab7fc016e07604f2ef0e00311c5 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 10 Oct 2017 20:19:46 -0700 Subject: [PATCH 082/312] Verify errors more correctly in tsc-watch mode --- src/harness/unittests/tscWatchMode.ts | 353 ++++++++++++---------- src/harness/virtualFileSystemWithWatch.ts | 8 +- 2 files changed, 193 insertions(+), 168 deletions(-) diff --git a/src/harness/unittests/tscWatchMode.ts b/src/harness/unittests/tscWatchMode.ts index 31d79df21c1..b25a7b1eb53 100644 --- a/src/harness/unittests/tscWatchMode.ts +++ b/src/harness/unittests/tscWatchMode.ts @@ -80,6 +80,92 @@ namespace ts.tscWatch { checkOutputDoesNotContain(host, expectedNonAffectedFiles); } + function checkOutputErrors(host: WatchedSystem, errors?: ReadonlyArray, isInitial?: true, skipWaiting?: true) { + const outputs = host.getOutput(); + const expectedOutputCount = (isInitial ? 0 : 1) + (errors ? errors.length : 0) + (skipWaiting ? 0 : 1); + assert.equal(outputs.length, expectedOutputCount, "Outputs = " + outputs.toString()); + let index = 0; + if (!isInitial) { + assertWatchDiagnosticAt(host, index, Diagnostics.File_change_detected_Starting_incremental_compilation); + index++; + } + forEach(errors, error => { + assertDiagnosticAt(host, index, error); + index++; + }); + if (!skipWaiting) { + assertWatchDiagnosticAt(host, index, Diagnostics.Compilation_complete_Watching_for_file_changes); + } + host.clearOutput(); + } + + function assertDiagnosticAt(host: WatchedSystem, outputAt: number, diagnostic: Diagnostic) { + const output = host.getOutput()[outputAt]; + assert.equal(output, formatDiagnostic(diagnostic, host), "outputs[" + outputAt + "] is " + output); + } + + function assertWatchDiagnosticAt(host: WatchedSystem, outputAt: number, diagnosticMessage: DiagnosticMessage) { + const output = host.getOutput()[outputAt]; + assert.isTrue(endsWith(output, getWatchDiagnosticWithoutDate(host, diagnosticMessage)), "outputs[" + outputAt + "] is " + output); + } + + function getWatchDiagnosticWithoutDate(host: WatchedSystem, diagnosticMessage: DiagnosticMessage) { + return ` - ${flattenDiagnosticMessageText(getLocaleSpecificMessage(diagnosticMessage), host.newLine)}${host.newLine + host.newLine + host.newLine}`; + } + + function getDiagnosticOfFileFrom(file: SourceFile, text: string, start: number, length: number, message: DiagnosticMessage): Diagnostic { + return { + file, + start, + length, + + messageText: text, + category: message.category, + code: message.code, + }; + } + + function getDiagnosticWithoutFile(message: DiagnosticMessage, ..._args: (string | number)[]): Diagnostic { + let text = getLocaleSpecificMessage(message); + + if (arguments.length > 1) { + text = formatStringFromArgs(text, arguments, 1); + } + + return getDiagnosticOfFileFrom(/*file*/ undefined, text, /*start*/ undefined, /*length*/ undefined, message); + } + + function getDiagnosticOfFile(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ..._args: (string | number)[]): Diagnostic { + let text = getLocaleSpecificMessage(message); + + if (arguments.length > 4) { + text = formatStringFromArgs(text, arguments, 4); + } + + return getDiagnosticOfFileFrom(file, text, start, length, message); + } + + function getUnknownCompilerOption(program: Program, configFile: FileOrFolder, option: string) { + const quotedOption = `"${option}"`; + return getDiagnosticOfFile(program.getCompilerOptions().configFile, configFile.content.indexOf(quotedOption), quotedOption.length, Diagnostics.Unknown_compiler_option_0, option); + } + + function getDiagnosticOfFileFromProgram(program: Program, filePath: string, start: number, length: number, message: DiagnosticMessage, ..._args: (string | number)[]): Diagnostic { + let text = getLocaleSpecificMessage(message); + + if (arguments.length > 5) { + text = formatStringFromArgs(text, arguments, 5); + } + + return getDiagnosticOfFileFrom(program.getSourceFileByPath(toPath(filePath, program.getCurrentDirectory(), s => s.toLowerCase())), + text, start, length, message); + } + + function getDiagnosticModuleNotFoundOfFile(program: Program, file: FileOrFolder, moduleName: string) { + const quotedModuleName = `"${moduleName}"`; + return getDiagnosticOfFileFromProgram(program, file.path, file.content.indexOf(quotedModuleName), quotedModuleName.length, Diagnostics.Cannot_find_module_0, moduleName); + } + describe("tsc-watch program updates", () => { const commonFile1: FileOrFolder = { path: "/a/b/commonFile1.ts", @@ -233,9 +319,10 @@ namespace ts.tscWatch { }); it("handles the missing files - that were added to program because they were added with /// { + const commonFile2Name = "commonFile2.ts"; const file1: FileOrFolder = { path: "/a/b/commonFile1.ts", - content: `/// + content: `/// let x = y` }; const host = createWatchedSystem([file1, libFile]); @@ -243,18 +330,16 @@ namespace ts.tscWatch { checkProgramRootFiles(watch(), [file1.path]); checkProgramActualFiles(watch(), [file1.path, libFile.path]); - const errors = [ - `a/b/commonFile1.ts(1,22): error TS6053: File '${commonFile2.path}' not found.${host.newLine}`, - `a/b/commonFile1.ts(2,29): error TS2304: Cannot find name 'y'.${host.newLine}` - ]; - checkOutputContains(host, errors); - host.clearOutput(); + checkOutputErrors(host, [ + getDiagnosticOfFileFromProgram(watch(), file1.path, file1.content.indexOf(commonFile2Name), commonFile2Name.length, Diagnostics.File_0_not_found, commonFile2.path), + getDiagnosticOfFileFromProgram(watch(), file1.path, file1.content.indexOf("y"), 1, Diagnostics.Cannot_find_name_0, "y") + ], /*isInitial*/ true); host.reloadFS([file1, commonFile2, libFile]); host.runQueuedTimeoutCallbacks(); checkProgramRootFiles(watch(), [file1.path]); checkProgramActualFiles(watch(), [file1.path, libFile.path, commonFile2.path]); - checkOutputDoesNotContain(host, errors); + checkOutputErrors(host); }); it("should reflect change in config file", () => { @@ -578,17 +663,19 @@ namespace ts.tscWatch { path: "/a/b/tsconfig.json", content: JSON.stringify({ compilerOptions: {} }) }; - const host = createWatchedSystem([file1, file2, config]); + const host = createWatchedSystem([file1, file2, libFile, config]); const watch = createWatchModeWithConfigFile(config.path, host); - checkProgramActualFiles(watch(), [file1.path, file2.path]); + checkProgramActualFiles(watch(), [file1.path, file2.path, libFile.path]); + checkOutputErrors(host, emptyArray, /*isInitial*/ true); - host.clearOutput(); - host.reloadFS([file1, file2]); + host.reloadFS([file1, file2, libFile]); host.checkTimeoutQueueLengthAndRun(1); assert.equal(host.exitCode, ExitStatus.DiagnosticsPresent_OutputsSkipped); - checkOutputContains(host, [`error TS6053: File '${config.path}' not found.${host.newLine}`]); + checkOutputErrors(host, [ + getDiagnosticWithoutFile(Diagnostics.File_0_not_found, config.path) + ], /*isInitial*/ undefined, /*skipWaiting*/ true); }); it("Proper errors: document is not contained in project", () => { @@ -687,25 +774,25 @@ namespace ts.tscWatch { }; const file1 = { path: "/a/b/file1.ts", - content: "import * as T from './moduleFile'; T.bar();" + content: 'import * as T from "./moduleFile"; T.bar();' }; const host = createWatchedSystem([moduleFile, file1, libFile]); - createWatchModeWithoutConfigFile([file1.path], host); - const error = "a/b/file1.ts(1,20): error TS2307: Cannot find module \'./moduleFile\'.\n"; - checkOutputDoesNotContain(host, [error]); + const watch = createWatchModeWithoutConfigFile([file1.path], host); + checkOutputErrors(host, emptyArray, /*isInitial*/ true); const moduleFileOldPath = moduleFile.path; const moduleFileNewPath = "/a/b/moduleFile1.ts"; moduleFile.path = moduleFileNewPath; host.reloadFS([moduleFile, file1, libFile]); host.runQueuedTimeoutCallbacks(); - checkOutputContains(host, [error]); + checkOutputErrors(host, [ + getDiagnosticModuleNotFoundOfFile(watch(), file1, "./moduleFile") + ]); - host.clearOutput(); moduleFile.path = moduleFileOldPath; host.reloadFS([moduleFile, file1, libFile]); host.runQueuedTimeoutCallbacks(); - checkOutputDoesNotContain(host, [error]); + checkOutputErrors(host); }); it("rename a module file and rename back should restore the states for configured projects", () => { @@ -715,31 +802,29 @@ namespace ts.tscWatch { }; const file1 = { path: "/a/b/file1.ts", - content: "import * as T from './moduleFile'; T.bar();" + content: 'import * as T from "./moduleFile"; T.bar();' }; const configFile = { path: "/a/b/tsconfig.json", content: `{}` }; const host = createWatchedSystem([moduleFile, file1, configFile, libFile]); - createWatchModeWithConfigFile(configFile.path, host); - - const error = "a/b/file1.ts(1,20): error TS2307: Cannot find module \'./moduleFile\'.\n"; - checkOutputDoesNotContain(host, [error]); + const watch = createWatchModeWithConfigFile(configFile.path, host); + checkOutputErrors(host, emptyArray, /*isInitial*/ true); const moduleFileOldPath = moduleFile.path; const moduleFileNewPath = "/a/b/moduleFile1.ts"; moduleFile.path = moduleFileNewPath; - host.clearOutput(); host.reloadFS([moduleFile, file1, configFile, libFile]); host.runQueuedTimeoutCallbacks(); - checkOutputContains(host, [error]); + checkOutputErrors(host, [ + getDiagnosticModuleNotFoundOfFile(watch(), file1, "./moduleFile") + ]); - host.clearOutput(); moduleFile.path = moduleFileOldPath; host.reloadFS([moduleFile, file1, configFile, libFile]); host.runQueuedTimeoutCallbacks(); - checkOutputDoesNotContain(host, [error]); + checkOutputErrors(host); }); it("types should load from config file path if config exists", () => { @@ -771,18 +856,18 @@ namespace ts.tscWatch { }; const file1 = { path: "/a/b/file1.ts", - content: "import * as T from './moduleFile'; T.bar();" + content: 'import * as T from "./moduleFile"; T.bar();' }; const host = createWatchedSystem([file1, libFile]); - createWatchModeWithoutConfigFile([file1.path], host); + const watch = createWatchModeWithoutConfigFile([file1.path], host); - const error = `a/b/file1.ts(1,20): error TS2307: Cannot find module \'./moduleFile\'.${host.newLine}`; - checkOutputContains(host, [error]); - host.clearOutput(); + checkOutputErrors(host, [ + getDiagnosticModuleNotFoundOfFile(watch(), file1, "./moduleFile") + ], /*isInitial*/ true); host.reloadFS([file1, moduleFile, libFile]); host.runQueuedTimeoutCallbacks(); - checkOutputDoesNotContain(host, [error]); + checkOutputErrors(host); }); it("Configure file diagnostics events are generated when the config file has errors", () => { @@ -801,14 +886,14 @@ namespace ts.tscWatch { }; const host = createWatchedSystem([file, configFile, libFile]); - createWatchModeWithConfigFile(configFile.path, host); - checkOutputContains(host, [ - `a/b/tsconfig.json(3,29): error TS5023: Unknown compiler option \'foo\'.${host.newLine}`, - `a/b/tsconfig.json(4,29): error TS5023: Unknown compiler option \'allowJS\'.${host.newLine}` - ]); + const watch = createWatchModeWithConfigFile(configFile.path, host); + checkOutputErrors(host, [ + getUnknownCompilerOption(watch(), configFile, "foo"), + getUnknownCompilerOption(watch(), configFile, "allowJS") + ], /*isInitial*/ true); }); - it("Configure file diagnostics events are generated when the config file doesn't have errors", () => { + it("If config file doesnt have errors, they are not reported", () => { const file = { path: "/a/b/app.ts", content: "let x = 10" @@ -822,13 +907,10 @@ namespace ts.tscWatch { const host = createWatchedSystem([file, configFile, libFile]); createWatchModeWithConfigFile(configFile.path, host); - checkOutputDoesNotContain(host, [ - `a/b/tsconfig.json(3,29): error TS5023: Unknown compiler option \'foo\'.${host.newLine}`, - `a/b/tsconfig.json(4,29): error TS5023: Unknown compiler option \'allowJS\'.${host.newLine}` - ]); + checkOutputErrors(host, emptyArray, /*isInitial*/ true); }); - it("Configure file diagnostics events are generated when the config file changes", () => { + it("Reports errors when the config file changes", () => { const file = { path: "/a/b/app.ts", content: "let x = 10" @@ -841,9 +923,8 @@ namespace ts.tscWatch { }; const host = createWatchedSystem([file, configFile, libFile]); - createWatchModeWithConfigFile(configFile.path, host); - const error = `a/b/tsconfig.json(3,25): error TS5023: Unknown compiler option 'haha'.${host.newLine}`; - checkOutputDoesNotContain(host, [error]); + const watch = createWatchModeWithConfigFile(configFile.path, host); + checkOutputErrors(host, emptyArray, /*isInitial*/ true); configFile.content = `{ "compilerOptions": { @@ -852,15 +933,16 @@ namespace ts.tscWatch { }`; host.reloadFS([file, configFile, libFile]); host.runQueuedTimeoutCallbacks(); - checkOutputContains(host, [error]); + checkOutputErrors(host, [ + getUnknownCompilerOption(watch(), configFile, "haha") + ]); - host.clearOutput(); configFile.content = `{ "compilerOptions": {} }`; host.reloadFS([file, configFile, libFile]); host.runQueuedTimeoutCallbacks(); - checkOutputDoesNotContain(host, [error]); + checkOutputErrors(host); }); it("non-existing directories listed in config file input array should be tolerated without crashing the server", () => { @@ -935,29 +1017,28 @@ namespace ts.tscWatch { }`; const configFileContentWithComment = configFileContentBeforeComment + configFileContentComment + configFileContentAfterComment; const configFileContentWithoutCommentLine = configFileContentBeforeComment + configFileContentAfterComment; - - const line = 5; - const errors = (line: number) => [ - `a/b/tsconfig.json(${line},25): error TS5053: Option \'allowJs\' cannot be specified with option \'declaration\'.\n`, - `a/b/tsconfig.json(${line + 1},25): error TS5053: Option \'allowJs\' cannot be specified with option \'declaration\'.\n` - ]; - const configFile = { path: "/a/b/tsconfig.json", content: configFileContentWithComment }; - const host = createWatchedSystem([file, libFile, configFile]); - createWatchModeWithConfigFile(configFile.path, host); - checkOutputContains(host, errors(line)); - checkOutputDoesNotContain(host, errors(line - 2)); - host.clearOutput(); + const files = [file, libFile, configFile]; + const host = createWatchedSystem(files); + const watch = createWatchModeWithConfigFile(configFile.path, host); + const errors = () => [ + getDiagnosticOfFile(watch().getCompilerOptions().configFile, configFile.content.indexOf('"allowJs"'), '"allowJs"'.length, Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration"), + getDiagnosticOfFile(watch().getCompilerOptions().configFile, configFile.content.indexOf('"declaration"'), '"declaration"'.length, Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration") + ]; + const intialErrors = errors(); + checkOutputErrors(host, intialErrors, /*isInitial*/ true); configFile.content = configFileContentWithoutCommentLine; - host.reloadFS([file, configFile]); + host.reloadFS(files); host.runQueuedTimeoutCallbacks(); - checkOutputContains(host, errors(line - 2)); - checkOutputDoesNotContain(host, errors(line)); + const nowErrors = errors(); + checkOutputErrors(host, nowErrors); + assert.equal(nowErrors[0].start, intialErrors[0].start - configFileContentComment.length); + assert.equal(nowErrors[1].start, intialErrors[1].start - configFileContentComment.length); }); }); @@ -1485,23 +1566,20 @@ namespace ts.tscWatch { path: "/a/d/f0.ts", content: `import {x} from "f1"` }; - const imported = { path: "/a/f1.ts", content: `foo()` }; - const f1IsNotModule = `a/d/f0.ts(1,17): error TS2306: File '${imported.path}' is not a module.\n`; - const cannotFindFoo = `a/f1.ts(1,1): error TS2304: Cannot find name 'foo'.\n`; - const cannotAssignValue = "a/d/f0.ts(2,21): error TS2322: Type '1' is not assignable to type 'string'.\n"; - const files = [root, imported, libFile]; const host = createWatchedSystem(files); - createWatchModeWithoutConfigFile([root.path], host, { module: ModuleKind.AMD }); + const watch = createWatchModeWithoutConfigFile([root.path], host, { module: ModuleKind.AMD }); + + const f1IsNotModule = getDiagnosticOfFileFromProgram(watch(), root.path, root.content.indexOf('"f1"'), '"f1"'.length, Diagnostics.File_0_is_not_a_module, imported.path); + const cannotFindFoo = getDiagnosticOfFileFromProgram(watch(), imported.path, imported.content.indexOf("foo"), "foo".length, Diagnostics.Cannot_find_name_0, "foo"); // ensure that imported file was found - checkOutputContains(host, [f1IsNotModule, cannotFindFoo]); - host.clearOutput(); + checkOutputErrors(host, [f1IsNotModule, cannotFindFoo], /*isInitial*/ true); const originalFileExists = host.fileExists; { @@ -1517,8 +1595,11 @@ namespace ts.tscWatch { host.runQueuedTimeoutCallbacks(); // ensure file has correct number of errors after edit - checkOutputContains(host, [f1IsNotModule, cannotAssignValue]); - host.clearOutput(); + checkOutputErrors(host, [ + f1IsNotModule, + getDiagnosticOfFileFromProgram(watch(), root.path, newContent.indexOf("var x") + "var ".length, "x".length, Diagnostics.Type_0_is_not_assignable_to_type_1, 1, "string"), + cannotFindFoo + ]); } { let fileExistsIsCalled = false; @@ -1534,13 +1615,13 @@ namespace ts.tscWatch { root.content = `import {x} from "f2"`; host.reloadFS(files); - // trigger synchronization to make sure that LSHost will try to find 'f2' module on disk - host.runQueuedTimeoutCallbacks(); + // trigger synchronization to make sure that LSHost will try to find 'f2' module on disk + host.runQueuedTimeoutCallbacks(); - // ensure file has correct number of errors after edit - const cannotFindModuleF2 = `a/d/f0.ts(1,17): error TS2307: Cannot find module 'f2'.\n`; - checkOutputContains(host, [cannotFindModuleF2]); - host.clearOutput(); + // ensure file has correct number of errors after edit + checkOutputErrors(host, [ + getDiagnosticModuleNotFoundOfFile(watch(), root, "f2") + ]); assert.isTrue(fileExistsIsCalled); } @@ -1561,7 +1642,7 @@ namespace ts.tscWatch { host.reloadFS(files); host.runQueuedTimeoutCallbacks(); - checkOutputContains(host, [f1IsNotModule, cannotFindFoo]); + checkOutputErrors(host, [f1IsNotModule, cannotFindFoo]); assert.isTrue(fileExistsCalled); } }); @@ -1593,12 +1674,12 @@ namespace ts.tscWatch { return originalFileExists.call(host, fileName); }; - createWatchModeWithoutConfigFile([root.path], host, { module: ModuleKind.AMD }); + const watch = createWatchModeWithoutConfigFile([root.path], host, { module: ModuleKind.AMD }); - const barNotFound = `a/foo.ts(1,17): error TS2307: Cannot find module 'bar'.\n`; assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called"); - checkOutputContains(host, [barNotFound]); - host.clearOutput(); + checkOutputErrors(host, [ + getDiagnosticModuleNotFoundOfFile(watch(), root, "bar") + ], /*isInitial*/ true); fileExistsCalledForBar = false; root.content = `import {y} from "bar"`; @@ -1606,7 +1687,7 @@ namespace ts.tscWatch { host.runQueuedTimeoutCallbacks(); assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called."); - checkOutputDoesNotContain(host, [barNotFound]); + checkOutputErrors(host); }); it("should compile correctly when resolved module goes missing and then comes back (module is not part of the root)", () => { @@ -1617,7 +1698,7 @@ namespace ts.tscWatch { const imported = { path: `/a/bar.d.ts`, - content: `export const y = 1;` + content: `export const y = 1;export const x = 10;` }; const files = [root, libFile]; @@ -1635,25 +1716,24 @@ namespace ts.tscWatch { return originalFileExists.call(host, fileName); }; - createWatchModeWithoutConfigFile([root.path], host, { module: ModuleKind.AMD }); + const watch = createWatchModeWithoutConfigFile([root.path], host, { module: ModuleKind.AMD }); - const barNotFound = `a/foo.ts(1,17): error TS2307: Cannot find module 'bar'.\n`; assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called"); - checkOutputDoesNotContain(host, [barNotFound]); - host.clearOutput(); + checkOutputErrors(host, emptyArray, /*isInitial*/ true); fileExistsCalledForBar = false; host.reloadFS(files); host.runQueuedTimeoutCallbacks(); assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called."); - checkOutputContains(host, [barNotFound]); - host.clearOutput(); + checkOutputErrors(host, [ + getDiagnosticModuleNotFoundOfFile(watch(), root, "bar") + ]); fileExistsCalledForBar = false; host.reloadFS(filesWithImported); host.checkTimeoutQueueLengthAndRun(1); assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called."); - checkOutputDoesNotContain(host, [barNotFound]); + checkOutputErrors(host); }); it("works when module resolution changes to ambient module", () => { @@ -1677,30 +1757,6 @@ namespace ts.tscWatch { declare module "fs" { export interface Stats { isFile(): boolean; - isDirectory(): boolean; - isBlockDevice(): boolean; - isCharacterDevice(): boolean; - isSymbolicLink(): boolean; - isFIFO(): boolean; - isSocket(): boolean; - dev: number; - ino: number; - mode: number; - nlink: number; - uid: number; - gid: number; - rdev: number; - size: number; - blksize: number; - blocks: number; - atimeMs: number; - mtimeMs: number; - ctimeMs: number; - birthtimeMs: number; - atime: Date; - mtime: Date; - ctime: Date; - birthtime: Date; } }` }; @@ -1709,15 +1765,15 @@ declare module "fs" { const filesWithNodeType = files.concat(packageJson, nodeType); const host = createWatchedSystem(files, { currentDirectory: "/a/b" }); - createWatchModeWithoutConfigFile([root.path], host, { }); + const watch = createWatchModeWithoutConfigFile([root.path], host, { }); - const fsNotFound = `foo.ts(1,21): error TS2307: Cannot find module 'fs'.\n`; - checkOutputContains(host, [fsNotFound]); - host.clearOutput(); + checkOutputErrors(host, [ + getDiagnosticModuleNotFoundOfFile(watch(), root, "fs") + ], /*isInitial*/ true); host.reloadFS(filesWithNodeType); host.runQueuedTimeoutCallbacks(); - checkOutputDoesNotContain(host, [fsNotFound]); + checkOutputErrors(host); }); it("works when included file with ambient module changes", () => { @@ -1735,17 +1791,6 @@ import * as u from "url"; declare module "url" { export interface Url { href?: string; - protocol?: string; - auth?: string; - hostname?: string; - port?: string; - host?: string; - pathname?: string; - search?: string; - query?: string | any; - slashes?: boolean; - hash?: string; - path?: string; } } ` @@ -1755,30 +1800,6 @@ declare module "url" { declare module "fs" { export interface Stats { isFile(): boolean; - isDirectory(): boolean; - isBlockDevice(): boolean; - isCharacterDevice(): boolean; - isSymbolicLink(): boolean; - isFIFO(): boolean; - isSocket(): boolean; - dev: number; - ino: number; - mode: number; - nlink: number; - uid: number; - gid: number; - rdev: number; - size: number; - blksize: number; - blocks: number; - atimeMs: number; - mtimeMs: number; - ctimeMs: number; - birthtimeMs: number; - atime: Date; - mtime: Date; - ctime: Date; - birthtime: Date; } } `; @@ -1786,16 +1807,16 @@ declare module "fs" { const files = [root, file, libFile]; const host = createWatchedSystem(files, { currentDirectory: "/a/b" }); - createWatchModeWithoutConfigFile([root.path, file.path], host, {}); + const watch = createWatchModeWithoutConfigFile([root.path, file.path], host, {}); - const fsNotFound = `foo.ts(2,21): error TS2307: Cannot find module 'fs'.\n`; - checkOutputContains(host, [fsNotFound]); - host.clearOutput(); + checkOutputErrors(host, [ + getDiagnosticModuleNotFoundOfFile(watch(), root, "fs") + ], /*isInitial*/ true); file.content += fileContentWithFS; host.reloadFS(files); host.runQueuedTimeoutCallbacks(); - checkOutputDoesNotContain(host, [fsNotFound]); + checkOutputErrors(host); }); }); } diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index c16f57235e4..cef70910678 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -212,13 +212,13 @@ namespace ts.TestFSWithWatch { directoryName: string; } - export class TestServerHost implements server.ServerHost { + export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost { args: string[] = []; private readonly output: string[] = []; private fs: Map = createMap(); - private getCanonicalFileName: (s: string) => string; + getCanonicalFileName: (s: string) => string; private toPath: (f: string) => Path; private timeoutCallbacks = new Callbacks(); private immediateCallbacks = new Callbacks(); @@ -234,6 +234,10 @@ namespace ts.TestFSWithWatch { this.reloadFS(fileOrFolderList); } + getNewLine() { + return this.newLine; + } + toNormalizedAbsolutePath(s: string) { return getNormalizedAbsolutePath(s, this.currentDirectory); } From cf9b83accc62833a109e48f03463bb1c02a5f767 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 10 Oct 2017 21:15:20 -0700 Subject: [PATCH 083/312] Instead of counting events with name, verify each event to not equal event name --- src/harness/unittests/tsserverProjectSystem.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index d5b9b9d62fc..af85e21260a 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -173,8 +173,7 @@ namespace ts.projectSystem { } hasZeroEvent(eventName: T["eventName"]) { - const eventCount = countWhere(this.events, event => event.eventName === eventName); - assert.equal(eventCount, 0); + this.events.forEach(event => assert.notEqual(event.eventName, eventName)); } checkSingleConfigFileDiagEvent(configFileName: string, triggerFile: string) { From de68f067d5bf1b60aaae6c0162e482480807944e Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 11 Oct 2017 08:17:40 -0700 Subject: [PATCH 084/312] Set flags on fresh object types from getSpreadType Previously, getSpreadType didn't set any flags and relied on its callers to do so. This was error-prone because getSpreadType often returns non-fresh types. --- src/compiler/checker.ts | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a61ded007f4..7c62dd4468c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7846,7 +7846,7 @@ namespace ts { * this function should be called in a left folding style, with left = previous result of getSpreadType * and right = the new element to be spread. */ - function getSpreadType(left: Type, right: Type): Type { + function getSpreadType(left: Type, right: Type, symbol: Symbol, propagatedFlags: TypeFlags): Type { if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) { return anyType; } @@ -7857,10 +7857,10 @@ namespace ts { return left; } if (left.flags & TypeFlags.Union) { - return mapType(left, t => getSpreadType(t, right)); + return mapType(left, t => getSpreadType(t, right, symbol, propagatedFlags)); } if (right.flags & TypeFlags.Union) { - return mapType(right, t => getSpreadType(left, t)); + return mapType(right, t => getSpreadType(left, t, symbol, propagatedFlags)); } if (right.flags & TypeFlags.NonPrimitive) { return nonPrimitiveType; @@ -7918,7 +7918,13 @@ namespace ts { members.set(leftProp.escapedName, getNonReadonlySymbol(leftProp)); } } - return createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo); + + const spread = createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo); + spread.flags |= propagatedFlags; + spread.flags |= TypeFlags.FreshLiteral; + (spread as ObjectType).objectFlags |= ObjectFlags.ObjectLiteral; + spread.symbol = symbol; + return spread; } function getNonReadonlySymbol(prop: Symbol) { @@ -13858,7 +13864,7 @@ namespace ts { checkExternalEmitHelpers(memberDecl, ExternalEmitHelpers.Assign); } if (propertiesArray.length > 0) { - spread = getSpreadType(spread, createObjectLiteralType()); + spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags); propertiesArray = []; propertiesTable = createSymbolTable(); hasComputedStringProperty = false; @@ -13870,7 +13876,7 @@ namespace ts { error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types); return unknownType; } - spread = getSpreadType(spread, type); + spread = getSpreadType(spread, type, node.symbol, propagatedFlags); offset = i + 1; continue; } @@ -13915,17 +13921,8 @@ namespace ts { if (spread !== emptyObjectType) { if (propertiesArray.length > 0) { - spread = getSpreadType(spread, createObjectLiteralType()); + spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags); } - // only set the symbol and flags if this is a (fresh) object type - forEachType(spread, t => { - if (t.flags & TypeFlags.Object) { - t.flags |= propagatedFlags; - t.flags |= TypeFlags.FreshLiteral; - (t as ObjectType).objectFlags |= ObjectFlags.ObjectLiteral; - t.symbol = node.symbol; - } - }); return spread; } @@ -14045,7 +14042,7 @@ namespace ts { else { Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute); if (attributesArray.length > 0) { - spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable)); + spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable), openingLikeElement.symbol, /*propagatedFlags*/ 0); attributesArray = []; attributesTable = createSymbolTable(); } @@ -14054,7 +14051,7 @@ namespace ts { hasSpreadAnyType = true; } if (isValidSpreadType(exprType)) { - spread = getSpreadType(spread, exprType); + spread = getSpreadType(spread, exprType, openingLikeElement.symbol, /*propagatedFlags*/ 0); } else { typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType; @@ -14065,7 +14062,7 @@ namespace ts { if (!hasSpreadAnyType) { if (spread !== emptyObjectType) { if (attributesArray.length > 0) { - spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable)); + spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable), openingLikeElement.symbol, /*propagatedFlags*/ 0); } attributesArray = getPropertiesOfType(spread); } From 576bd8c25f8970adf6952787af9546bb387f8240 Mon Sep 17 00:00:00 2001 From: Charles Pierce Date: Wed, 11 Oct 2017 09:04:51 -0700 Subject: [PATCH 085/312] Ensure Async Modifier is maintained through ES6 Class Conversion (#19092) --- .../refactors/convertFunctionToEs6Class.ts | 14 +++++----- .../convertFunctionToEs6Class_asyncMethods.ts | 27 +++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 tests/cases/fourslash/convertFunctionToEs6Class_asyncMethods.ts diff --git a/src/services/refactors/convertFunctionToEs6Class.ts b/src/services/refactors/convertFunctionToEs6Class.ts index 110f64d1220..1b02b11678b 100644 --- a/src/services/refactors/convertFunctionToEs6Class.ts +++ b/src/services/refactors/convertFunctionToEs6Class.ts @@ -172,7 +172,8 @@ namespace ts.refactor.convertFunctionToES6Class { switch (assignmentBinaryExpression.right.kind) { case SyntaxKind.FunctionExpression: { const functionExpression = assignmentBinaryExpression.right as FunctionExpression; - const method = createMethod(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, + const fullModifiers = concatenate(modifiers, getModifierKindFromSource(functionExpression, SyntaxKind.AsyncKeyword)); + const method = createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, /*typeParameters*/ undefined, functionExpression.parameters, /*type*/ undefined, functionExpression.body); copyComments(assignmentBinaryExpression, method); return method; @@ -192,7 +193,8 @@ namespace ts.refactor.convertFunctionToES6Class { const expression = arrowFunctionBody as Expression; bodyBlock = createBlock([createReturn(expression)]); } - const method = createMethod(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, + const fullModifiers = concatenate(modifiers, getModifierKindFromSource(arrowFunction, SyntaxKind.AsyncKeyword)); + const method = createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, /*typeParameters*/ undefined, arrowFunction.parameters, /*type*/ undefined, bodyBlock); copyComments(assignmentBinaryExpression, method); return method; @@ -243,7 +245,7 @@ namespace ts.refactor.convertFunctionToES6Class { memberElements.unshift(createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, initializer.parameters, initializer.body)); } - const modifiers = getExportModifierFromSource(precedingNode); + const modifiers = getModifierKindFromSource(precedingNode, SyntaxKind.ExportKeyword); const cls = createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements); // Don't call copyComments here because we'll already leave them in place @@ -256,15 +258,15 @@ namespace ts.refactor.convertFunctionToES6Class { memberElements.unshift(createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, node.parameters, node.body)); } - const modifiers = getExportModifierFromSource(node); + const modifiers = getModifierKindFromSource(node, SyntaxKind.ExportKeyword); const cls = createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements); // Don't call copyComments here because we'll already leave them in place return cls; } - function getExportModifierFromSource(source: Node) { - return filter(source.modifiers, modifier => modifier.kind === SyntaxKind.ExportKeyword); + function getModifierKindFromSource(source: Node, kind: SyntaxKind) { + return filter(source.modifiers, modifier => modifier.kind === kind); } } } \ No newline at end of file diff --git a/tests/cases/fourslash/convertFunctionToEs6Class_asyncMethods.ts b/tests/cases/fourslash/convertFunctionToEs6Class_asyncMethods.ts new file mode 100644 index 00000000000..ed230d50435 --- /dev/null +++ b/tests/cases/fourslash/convertFunctionToEs6Class_asyncMethods.ts @@ -0,0 +1,27 @@ +/// + +// @allowNonTsExtensions: true +// @Filename: test123.js +////export function /**/MyClass() { +////} +////MyClass.prototype.foo = async function() { +//// await 2; +////} +////MyClass.bar = async function() { +//// await 3; +////} + +verify.applicableRefactorAvailableAtMarker(""); +verify.fileAfterApplyingRefactorAtMarker("", +`export class MyClass { + constructor() { + } + async foo() { + await 2; + } + static async bar() { + await 3; + } +} +`, +'Convert to ES2015 class', 'convert'); From 0c4fe37a92c6aa16fa9746eb828a2c158f5ea3fe Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 11 Oct 2017 10:03:29 -0700 Subject: [PATCH 086/312] In issue template, recommend to use `typescript@next` (#19098) --- issue_template.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/issue_template.md b/issue_template.md index e812fe7b74c..ddc1d070bc9 100644 --- a/issue_template.md +++ b/issue_template.md @@ -2,7 +2,8 @@ -**TypeScript Version:** 2.4.0 / nightly (2.5.0-dev.201xxxxx) + +**TypeScript Version:** 2.6.0-dev.201xxxxx **Code** From e85c6330bad3255189785e676addbfaf26a65aa3 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 11 Oct 2017 10:03:53 -0700 Subject: [PATCH 087/312] Add package-lock.json to repository (#19099) --- .gitignore | 1 - package-lock.json | 5302 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 5302 insertions(+), 1 deletion(-) create mode 100644 package-lock.json diff --git a/.gitignore b/.gitignore index 9b93436e7f7..90b078fc94f 100644 --- a/.gitignore +++ b/.gitignore @@ -58,5 +58,4 @@ internal/ !tests/baselines/reference/project/nodeModules*/**/* .idea yarn.lock -package-lock.json .parallelperf.* diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000000..cde6c1ff733 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,5302 @@ +{ + "name": "typescript", + "version": "2.6.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@gulp-sourcemaps/identity-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.1.tgz", + "integrity": "sha1-z6I7xYQPkQTOMqZedNt+epdLvuE=", + "dev": true, + "requires": { + "acorn": "5.1.2", + "css": "2.2.1", + "normalize-path": "2.1.1", + "source-map": "0.5.7", + "through2": "2.0.3" + }, + "dependencies": { + "acorn": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", + "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==", + "dev": true + } + } + }, + "@gulp-sourcemaps/map-sources": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", + "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", + "dev": true, + "requires": { + "normalize-path": "2.1.1", + "through2": "2.0.3" + } + }, + "@types/browserify": { + "version": "12.0.33", + "resolved": "https://registry.npmjs.org/@types/browserify/-/browserify-12.0.33.tgz", + "integrity": "sha512-mY6dYfq1Ns3Xqz/JFUcyoWaXtm0XDoNhkU1vCwM/ULM5zqNL+SbtacJhce/JCgPeCdbqdVqq77tJ4HwdtypSxg==", + "dev": true, + "requires": { + "@types/insert-module-globals": "7.0.0", + "@types/node": "8.0.34" + } + }, + "@types/chai": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.4.tgz", + "integrity": "sha512-cvU0HomQ7/aGDQJZsbtJXqBQ7w4J4TqLB0Z/h8mKrpRjfeZEvTbygkfJEb7fWdmwpIeDeFmIVwAEqS0OYuUv3Q==", + "dev": true + }, + "@types/colors": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/colors/-/colors-1.1.3.tgz", + "integrity": "sha1-VBOwp6GxbdGL4OP9V9L+7Mgcx3Y=", + "dev": true + }, + "@types/convert-source-map": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@types/convert-source-map/-/convert-source-map-1.5.0.tgz", + "integrity": "sha512-4OHKJEw70U59CN24TLRxU3W+B/9GPp0P6g+eNIsObZLAIqw6NTEBorkjIpei4xsvUCx+YzFwUtt4MBZbfSLvbQ==", + "dev": true + }, + "@types/del": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/del/-/del-3.0.0.tgz", + "integrity": "sha512-18mSs54BvzV8+TTQxt0ancig6tsuPZySnhp3cQkWFFDmDMavU4pmWwR+bHHqRBWODYqpzIzVkqKLuk/fP6yypQ==", + "dev": true, + "requires": { + "@types/glob": "5.0.33" + } + }, + "@types/glob": { + "version": "5.0.33", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.33.tgz", + "integrity": "sha512-BcD4yyWz+qmCggaYMSFF0Xn7GkO6tgwm3Fh9Gxk/kQmEU3Z7flQTnVlMyKBUNvXXNTCCyjqK4XT4/2hLd1gQ2A==", + "dev": true, + "requires": { + "@types/minimatch": "3.0.1", + "@types/node": "8.0.34" + } + }, + "@types/gulp": { + "version": "3.8.33", + "resolved": "https://registry.npmjs.org/@types/gulp/-/gulp-3.8.33.tgz", + "integrity": "sha512-3UpA2pkKO40cNPe/8bxMQFWSASR9Jx67JfN9Z2Cf6ogfDMwXgEHm2XjKmuLYEtrp1IHYApOWlYMLYNgtTJgSAw==", + "dev": true, + "requires": { + "@types/node": "8.0.34", + "@types/orchestrator": "0.3.0", + "@types/vinyl": "2.0.1" + } + }, + "@types/gulp-concat": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/@types/gulp-concat/-/gulp-concat-0.0.31.tgz", + "integrity": "sha512-F14zRcKn15HC59RXRlHpcxj79WoLjkJBJBPfN0NBZOgkRCfDZYVu8rs0Y/CH4CJGUbbc/nHczD2LmepDS+ARaA==", + "dev": true, + "requires": { + "@types/node": "8.0.34" + } + }, + "@types/gulp-help": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/gulp-help/-/gulp-help-0.0.33.tgz", + "integrity": "sha1-ZejGUSQQkiVTf6OQA8S6UfT9GsU=", + "dev": true, + "requires": { + "@types/gulp": "3.8.33", + "@types/node": "8.0.34", + "@types/orchestrator": "0.3.0" + } + }, + "@types/gulp-newer": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/gulp-newer/-/gulp-newer-0.0.30.tgz", + "integrity": "sha1-bqn7oVsFdr5CTpl31IlCAEZKFR4=", + "dev": true, + "requires": { + "@types/node": "8.0.34" + } + }, + "@types/gulp-sourcemaps": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/@types/gulp-sourcemaps/-/gulp-sourcemaps-0.0.31.tgz", + "integrity": "sha512-kJD1byVNx+sdQlaBzZpSGeFH/4l99TXTY4XSGW+aRk27eOnVyk6VknXJpsb1Jk5E4ThKxZ8GYy6ais7MtprK1w==", + "dev": true, + "requires": { + "@types/node": "8.0.34" + } + }, + "@types/insert-module-globals": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/insert-module-globals/-/insert-module-globals-7.0.0.tgz", + "integrity": "sha512-zudCJPwluh1VUDB6Gl/OQdRp+fYy3+47huJB/JMQubMS2p+sH18MCVK4WUz3FqaWLB12yh5ELxVR/+tqwlm/qA==", + "dev": true, + "requires": { + "@types/node": "8.0.34" + } + }, + "@types/merge2": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/merge2/-/merge2-1.1.2.tgz", + "integrity": "sha512-Xy54xPmFQ8oAx0S3ku46i/zXE4dvfxl5M8n4p2M62IwxPau8IpobiRtL4jkrUzX6Kgeyb34BHOh0i70SDjKHeA==", + "dev": true, + "requires": { + "@types/node": "8.0.34" + } + }, + "@types/minimatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.1.tgz", + "integrity": "sha512-rUO/jz10KRSyA9SHoCWQ8WX9BICyj5jZYu1/ucKEJKb4KzLZCKMURdYbadP157Q6Zl1x0vHsrU+Z/O0XlhYQDw==", + "dev": true + }, + "@types/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", + "dev": true + }, + "@types/mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha512-XA4vNO6GCBz8Smq0hqSRo4yRWMqr4FPQrWjhJt6nKskzly4/p87SfuJMFYGRyYb6jo2WNIQU2FDBsY5r1BibUA==", + "dev": true, + "requires": { + "@types/node": "8.0.34" + } + }, + "@types/mocha": { + "version": "2.2.43", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.43.tgz", + "integrity": "sha512-xNlAmH+lRJdUMXClMTI9Y0pRqIojdxfm7DHsIxoB2iTzu3fnPmSMEN8SsSx0cdwV36d02PWCWaDUoZPDSln+xw==", + "dev": true + }, + "@types/node": { + "version": "8.0.34", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.34.tgz", + "integrity": "sha512-Jnmm57+nHqvJUPwUzt1CLoLzFtF2B2vgG7cWFut+a4nqTp9/L6pL0N+o0Jt3V7AQnCKMsPEqQpLFZYleBCdq3w==", + "dev": true + }, + "@types/orchestrator": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@types/orchestrator/-/orchestrator-0.3.0.tgz", + "integrity": "sha1-v4ShaZyTMNT+ic2BJj6PwJ+zKXg=", + "dev": true, + "requires": { + "@types/node": "8.0.34", + "@types/q": "0.0.37" + }, + "dependencies": { + "@types/q": { + "version": "0.0.37", + "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.37.tgz", + "integrity": "sha512-vjFGX1zMTMz/kUp3xgfJcxMVLkMWVMrdlyc0RwVyve1y9jxwqNaT8wTcv6M51ylq2a/zn5lm8g7qPSoIS4uvZQ==", + "dev": true + } + } + }, + "@types/q": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.0.5.tgz", + "integrity": "sha512-sudQPADzmQjXYS1fS2TxbWA/N/vbbfaO4Y7luPaAEyRWZVXC8jHwKV8KgNDbT7IHQaONNZWy9BYsodxY7IyDXQ==", + "dev": true + }, + "@types/run-sequence": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/run-sequence/-/run-sequence-0.0.29.tgz", + "integrity": "sha1-atD3ODE24TklMi5p/EHbd7MLIHU=", + "dev": true, + "requires": { + "@types/gulp": "3.8.33", + "@types/node": "8.0.34" + } + }, + "@types/through2": { + "version": "2.0.33", + "resolved": "https://registry.npmjs.org/@types/through2/-/through2-2.0.33.tgz", + "integrity": "sha1-H/LoihAN+1sUDnu5h5HxGUQA0TE=", + "dev": true, + "requires": { + "@types/node": "8.0.34" + } + }, + "@types/vinyl": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.1.tgz", + "integrity": "sha512-Joudabfn2ZofU2usW04y8OLmN75u7ZQkW0MCT3AnoBf5oUBp5iQ3Pgfz9+y1RdWkzhCPZo9/wBJ7FMWW2JrY0g==", + "dev": true, + "requires": { + "@types/node": "8.0.34" + } + }, + "@types/xml2js": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.0.tgz", + "integrity": "sha512-3gw0UqFMq7PsfMDwsawD0/L48soXfzOEh0NSAWVO99IZXnhx9LD3nOldHIpGYzZBsrS9NV2vaRFvEdWe+UweXQ==", + "dev": true, + "requires": { + "@types/node": "8.0.34" + } + }, + "JSONStream": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz", + "integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=", + "dev": true, + "requires": { + "jsonparse": "1.3.1", + "through": "2.3.8" + } + }, + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "dev": true + }, + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "dev": true + }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true + }, + "array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", + "dev": true + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", + "dev": true + }, + "array-slice": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.0.0.tgz", + "integrity": "sha1-5zA08A3MH0CHYAj9IP6ud71LfC8=", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1.js": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz", + "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + } + }, + "assertion-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", + "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", + "dev": true + }, + "astw": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/astw/-/astw-2.2.0.tgz", + "integrity": "sha1-e9QXhNMkk5h66yOba04cV6hzuRc=", + "dev": true, + "requires": { + "acorn": "4.0.13" + } + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "atob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz", + "integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", + "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==", + "dev": true + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-pack": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.0.2.tgz", + "integrity": "sha1-+GzWzvT1MAyOY+B6TVEvZfv/RTE=", + "dev": true, + "requires": { + "JSONStream": "1.3.1", + "combine-source-map": "0.7.2", + "defined": "1.0.0", + "through2": "2.0.3", + "umd": "3.0.1" + } + }, + "browser-resolve": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", + "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", + "dev": true, + "requires": { + "resolve": "1.1.7" + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "browserify": { + "version": "14.4.0", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-14.4.0.tgz", + "integrity": "sha1-CJo0Y69Y0OSNjNQHCz90ZU1avKk=", + "dev": true, + "requires": { + "JSONStream": "1.3.1", + "assert": "1.4.1", + "browser-pack": "6.0.2", + "browser-resolve": "1.11.2", + "browserify-zlib": "0.1.4", + "buffer": "5.0.8", + "cached-path-relative": "1.0.1", + "concat-stream": "1.5.2", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.11.1", + "defined": "1.0.0", + "deps-sort": "2.0.0", + "domain-browser": "1.1.7", + "duplexer2": "0.1.4", + "events": "1.1.1", + "glob": "7.1.2", + "has": "1.0.1", + "htmlescape": "1.1.1", + "https-browserify": "1.0.0", + "inherits": "2.0.3", + "insert-module-globals": "7.0.1", + "labeled-stream-splicer": "2.0.0", + "module-deps": "4.1.1", + "os-browserify": "0.1.2", + "parents": "1.0.1", + "path-browserify": "0.0.0", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "read-only-stream": "2.0.0", + "readable-stream": "2.3.3", + "resolve": "1.1.7", + "shasum": "1.0.2", + "shell-quote": "1.6.1", + "stream-browserify": "2.0.1", + "stream-http": "2.7.2", + "string_decoder": "1.0.3", + "subarg": "1.0.0", + "syntax-error": "1.3.0", + "through2": "2.0.3", + "timers-browserify": "1.4.2", + "tty-browserify": "0.0.0", + "url": "0.11.0", + "util": "0.10.3", + "vm-browserify": "0.0.4", + "xtend": "4.0.1" + } + }, + "browserify-aes": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.8.tgz", + "integrity": "sha512-WYCMOT/PtGTlpOKFht0YJFYcPy6pLCR98CtWfzK13zoynLlBMvAdEMSRGmgnJCw2M2j/5qxBkinZQFobieM8dQ==", + "dev": true, + "requires": { + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "browserify-cipher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", + "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "dev": true, + "requires": { + "browserify-aes": "1.0.8", + "browserify-des": "1.0.0", + "evp_bytestokey": "1.0.3" + } + }, + "browserify-des": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", + "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "des.js": "1.0.0", + "inherits": "2.0.3" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "randombytes": "2.0.5" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.0" + } + }, + "browserify-zlib": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "dev": true, + "requires": { + "pako": "0.2.9" + } + }, + "buffer": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.0.8.tgz", + "integrity": "sha512-xXvjQhVNz50v2nPeoOsNqWCLGfiv4ji/gXZM28jnVwdLJxH4mFyqgqCKfaK9zf1KUbG6zTkjLOy7ou+jSMarGA==", + "dev": true, + "requires": { + "base64-js": "1.2.1", + "ieee754": "1.1.8" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "cached-path-relative": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz", + "integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc=", + "dev": true + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + } + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "optional": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, + "chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "dev": true, + "requires": { + "assertion-error": "1.0.2", + "check-error": "1.0.2", + "deep-eql": "3.0.1", + "get-func-name": "2.0.0", + "pathval": "1.1.0", + "type-detect": "4.0.3" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "optional": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true, + "optional": true + } + } + }, + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "dev": true + }, + "clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "dev": true + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + }, + "cloneable-readable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.0.0.tgz", + "integrity": "sha1-pikNQT8hemEjL5XkWP84QYz7ARc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "process-nextick-args": "1.0.7", + "through2": "2.0.3" + } + }, + "color-convert": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", + "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "combine-source-map": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", + "integrity": "sha1-CHAxKFazB6h8xKxIbzqaYq7MwJ4=", + "dev": true, + "requires": { + "convert-source-map": "1.1.3", + "inline-source-map": "0.6.2", + "lodash.memoize": "3.0.4", + "source-map": "0.5.7" + }, + "dependencies": { + "convert-source-map": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + } + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", + "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.0.6", + "typedarray": "0.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "concat-with-sourcemaps": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.0.4.tgz", + "integrity": "sha1-9Vs74q60dgGxCi1SWcz7cP0vHdY=", + "dev": true, + "requires": { + "source-map": "0.5.7" + } + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "0.1.4" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "convert-source-map": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", + "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", + "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "elliptic": "6.4.0" + } + }, + "create-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "sha.js": "2.4.9" + } + }, + "create-hmac": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", + "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "create-hash": "1.1.3", + "inherits": "2.0.3", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.9" + } + }, + "crypto-browserify": { + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.1.tgz", + "integrity": "sha512-Na7ZlwCOqoaW5RwUK1WpXws2kv8mNhWdTlzob0UXulk6G9BDbyiJaGTYBIX61Ozn9l1EPPJpICZb4DaOpT9NlQ==", + "dev": true, + "requires": { + "browserify-cipher": "1.0.0", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.0", + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "diffie-hellman": "5.0.2", + "inherits": "2.0.3", + "pbkdf2": "3.0.14", + "public-encrypt": "4.0.0", + "randombytes": "2.0.5" + } + }, + "css": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.1.tgz", + "integrity": "sha1-c6TIHehdtmTU7mdPfUcIXjstVdw=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "source-map": "0.1.43", + "source-map-resolve": "0.3.1", + "urix": "0.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "1.0.2" + } + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "0.10.31" + } + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "dateformat": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", + "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "debug-fabulous": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-0.2.1.tgz", + "integrity": "sha512-u0TV6HcfLsZ03xLBhdhSViQMldaiQ2o+8/nSILaXkuNSWvxkx66vYJUAam0Eu7gAilJRX/69J4kKdqajQPaPyw==", + "dev": true, + "requires": { + "debug": "3.1.0", + "memoizee": "0.4.11", + "object-assign": "4.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "4.0.3" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "1.0.2" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "del": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", + "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", + "dev": true, + "requires": { + "globby": "6.1.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "p-map": "1.2.0", + "pify": "3.0.0", + "rimraf": "2.6.2" + } + }, + "deprecated": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", + "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=", + "dev": true + }, + "deps-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "dev": true, + "requires": { + "JSONStream": "1.3.1", + "shasum": "1.0.2", + "subarg": "1.0.0", + "through2": "2.0.3" + } + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "detect-file": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", + "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", + "dev": true, + "requires": { + "fs-exists-sync": "0.1.0" + } + }, + "detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", + "dev": true + }, + "detective": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-4.5.0.tgz", + "integrity": "sha1-blqMaybmx6JUsca210kNmOyR7dE=", + "dev": true, + "requires": { + "acorn": "4.0.13", + "defined": "1.0.0" + } + }, + "diff": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", + "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "miller-rabin": "4.0.1", + "randombytes": "2.0.5" + } + }, + "domain-browser": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", + "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=", + "dev": true + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "2.3.3" + } + }, + "duplexify": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz", + "integrity": "sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ==", + "dev": true, + "requires": { + "end-of-stream": "1.4.0", + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "stream-shift": "1.0.0" + }, + "dependencies": { + "end-of-stream": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", + "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", + "dev": true, + "requires": { + "once": "1.4.0" + } + } + } + }, + "elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "end-of-stream": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", + "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", + "dev": true, + "requires": { + "once": "1.3.3" + }, + "dependencies": { + "once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + } + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es5-ext": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.31.tgz", + "integrity": "sha1-e7k4yVp/G59ygJLcCcQe3MOY7v4=", + "dev": true, + "requires": { + "es6-iterator": "2.0.1", + "es6-symbol": "3.1.1" + } + }, + "es6-iterator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", + "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.31", + "es6-symbol": "3.1.1" + } + }, + "es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=", + "dev": true + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.31" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.31", + "es6-iterator": "2.0.1", + "es6-symbol": "3.1.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "requires": { + "esprima": "2.7.3", + "estraverse": "1.9.3", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.2.0" + }, + "dependencies": { + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.31" + } + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "1.3.4", + "safe-buffer": "5.1.1" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "2.2.3" + } + }, + "expand-tilde": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", + "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + } + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "fancy-log": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", + "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "time-stamp": "1.1.0" + } + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "filelist": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-0.0.6.tgz", + "integrity": "sha1-WKZBrR9XV0on/oekQO8xiDS1Vxk=", + "dev": true, + "requires": { + "minimatch": "3.0.4", + "utilities": "0.0.37" + }, + "dependencies": { + "utilities": { + "version": "0.0.37", + "resolved": "https://registry.npmjs.org/utilities/-/utilities-0.0.37.tgz", + "integrity": "sha1-o0cNCn9ogULZ6KV87hEo8S4Z4ZY=", + "dev": true + } + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "find-index": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", + "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", + "dev": true + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "findup-sync": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz", + "integrity": "sha1-QAQ5Kee8YK3wt/SCfExudaDeyhI=", + "dev": true, + "requires": { + "detect-file": "0.1.0", + "is-glob": "2.0.1", + "micromatch": "2.3.11", + "resolve-dir": "0.1.1" + } + }, + "fined": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz", + "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=", + "dev": true, + "requires": { + "expand-tilde": "2.0.2", + "is-plain-object": "2.0.4", + "object.defaults": "1.1.0", + "object.pick": "1.3.0", + "parse-filepath": "1.0.1" + }, + "dependencies": { + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "1.0.1" + } + } + } + }, + "first-chunk-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", + "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=", + "dev": true + }, + "flagged-respawn": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz", + "integrity": "sha1-/xke3c1wiKZ1smEP/8l2vpuAdLU=", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + }, + "fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gaze": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", + "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", + "dev": true, + "requires": { + "globule": "0.1.0" + } + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "glob-stream": { + "version": "3.1.18", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", + "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", + "dev": true, + "requires": { + "glob": "4.5.3", + "glob2base": "0.0.12", + "minimatch": "2.0.10", + "ordered-read-streams": "0.1.0", + "through2": "0.6.5", + "unique-stream": "1.0.0" + }, + "dependencies": { + "glob": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", + "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "2.0.10", + "once": "1.4.0" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + } + } + }, + "glob-watcher": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", + "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", + "dev": true, + "requires": { + "gaze": "0.5.2" + } + }, + "glob2base": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", + "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", + "dev": true, + "requires": { + "find-index": "0.1.1" + } + }, + "global-modules": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", + "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", + "dev": true, + "requires": { + "global-prefix": "0.1.5", + "is-windows": "0.2.0" + } + }, + "global-prefix": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", + "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", + "dev": true, + "requires": { + "homedir-polyfill": "1.0.1", + "ini": "1.3.4", + "is-windows": "0.2.0", + "which": "1.3.0" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "globule": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", + "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", + "dev": true, + "requires": { + "glob": "3.1.21", + "lodash": "1.0.2", + "minimatch": "0.2.14" + }, + "dependencies": { + "glob": { + "version": "3.1.21", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", + "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", + "dev": true, + "requires": { + "graceful-fs": "1.2.3", + "inherits": "1.0.2", + "minimatch": "0.2.14" + } + }, + "graceful-fs": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", + "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", + "dev": true + }, + "inherits": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", + "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", + "dev": true + }, + "minimatch": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", + "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", + "dev": true, + "requires": { + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + } + } + } + }, + "glogg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", + "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + } + }, + "graceful-fs": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", + "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", + "dev": true, + "requires": { + "natives": "1.1.0" + } + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true + }, + "gulp": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", + "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", + "dev": true, + "requires": { + "archy": "1.0.0", + "chalk": "1.1.3", + "deprecated": "0.0.1", + "gulp-util": "3.0.8", + "interpret": "1.0.4", + "liftoff": "2.3.0", + "minimist": "1.2.0", + "orchestrator": "0.3.8", + "pretty-hrtime": "1.0.3", + "semver": "4.3.6", + "tildify": "1.2.0", + "v8flags": "2.1.1", + "vinyl-fs": "0.3.14" + } + }, + "gulp-clone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulp-clone/-/gulp-clone-1.0.0.tgz", + "integrity": "sha1-mubGVr2cTzae6AXu9WV4a8gQBbA=", + "dev": true, + "requires": { + "gulp-util": "2.2.20", + "through2": "0.4.2" + }, + "dependencies": { + "ansi-regex": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", + "dev": true + }, + "ansi-styles": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", + "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", + "dev": true + }, + "chalk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", + "dev": true, + "requires": { + "ansi-styles": "1.1.0", + "escape-string-regexp": "1.0.5", + "has-ansi": "0.1.0", + "strip-ansi": "0.3.0", + "supports-color": "0.2.0" + } + }, + "dateformat": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", + "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", + "dev": true, + "requires": { + "get-stdin": "4.0.1", + "meow": "3.7.0" + } + }, + "gulp-util": { + "version": "2.2.20", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz", + "integrity": "sha1-1xRuVyiRC9jwR6awseVJvCLb1kw=", + "dev": true, + "requires": { + "chalk": "0.5.1", + "dateformat": "1.0.12", + "lodash._reinterpolate": "2.4.1", + "lodash.template": "2.4.1", + "minimist": "0.2.0", + "multipipe": "0.1.2", + "through2": "0.5.1", + "vinyl": "0.2.3" + }, + "dependencies": { + "through2": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", + "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "3.0.0" + } + } + } + }, + "has-ansi": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", + "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", + "dev": true, + "requires": { + "ansi-regex": "0.2.1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "lodash._reinterpolate": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz", + "integrity": "sha1-TxInqlqHEfxjL1sHofRgequLMiI=", + "dev": true + }, + "lodash.escape": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz", + "integrity": "sha1-LOEsXghNsKV92l5dHu659dF1o7Q=", + "dev": true, + "requires": { + "lodash._escapehtmlchar": "2.4.1", + "lodash._reunescapedhtml": "2.4.1", + "lodash.keys": "2.4.1" + } + }, + "lodash.keys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", + "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", + "dev": true, + "requires": { + "lodash._isnative": "2.4.1", + "lodash._shimkeys": "2.4.1", + "lodash.isobject": "2.4.1" + } + }, + "lodash.template": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz", + "integrity": "sha1-nmEQB+32KRKal0qzxIuBez4c8g0=", + "dev": true, + "requires": { + "lodash._escapestringchar": "2.4.1", + "lodash._reinterpolate": "2.4.1", + "lodash.defaults": "2.4.1", + "lodash.escape": "2.4.1", + "lodash.keys": "2.4.1", + "lodash.templatesettings": "2.4.1", + "lodash.values": "2.4.1" + } + }, + "lodash.templatesettings": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz", + "integrity": "sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=", + "dev": true, + "requires": { + "lodash._reinterpolate": "2.4.1", + "lodash.escape": "2.4.1" + } + }, + "minimist": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", + "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "strip-ansi": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", + "dev": true, + "requires": { + "ansi-regex": "0.2.1" + } + }, + "supports-color": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", + "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", + "dev": true + }, + "through2": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz", + "integrity": "sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "2.1.2" + }, + "dependencies": { + "xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "dev": true, + "requires": { + "object-keys": "0.4.0" + } + } + } + }, + "vinyl": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz", + "integrity": "sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI=", + "dev": true, + "requires": { + "clone-stats": "0.0.1" + } + }, + "xtend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", + "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", + "dev": true + } + } + }, + "gulp-concat": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz", + "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=", + "dev": true, + "requires": { + "concat-with-sourcemaps": "1.0.4", + "through2": "2.0.3", + "vinyl": "2.1.0" + }, + "dependencies": { + "clone": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", + "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "vinyl": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz", + "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=", + "dev": true, + "requires": { + "clone": "2.1.1", + "clone-buffer": "1.0.0", + "clone-stats": "1.0.0", + "cloneable-readable": "1.0.0", + "remove-trailing-separator": "1.1.0", + "replace-ext": "1.0.0" + } + } + } + }, + "gulp-help": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/gulp-help/-/gulp-help-1.6.1.tgz", + "integrity": "sha1-Jh2xhuGDl/7z9qLCLpwxW/qIrgw=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "object-assign": "3.0.0" + }, + "dependencies": { + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "dev": true + } + } + }, + "gulp-insert": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/gulp-insert/-/gulp-insert-0.5.0.tgz", + "integrity": "sha1-MjE/E+SiPPWsylzl8MCAkjx3hgI=", + "dev": true, + "requires": { + "readable-stream": "1.1.14", + "streamqueue": "0.0.6" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "gulp-newer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/gulp-newer/-/gulp-newer-1.3.0.tgz", + "integrity": "sha1-1Q7Ky7gi7aSStXMkpshaB/2aVcE=", + "dev": true, + "requires": { + "glob": "7.1.2", + "gulp-util": "3.0.8", + "kew": "0.7.0" + } + }, + "gulp-sourcemaps": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.1.tgz", + "integrity": "sha512-1qHCI3hdmsMdq/SUotxwUh/L8YzlI6J9zQ5ifNOtx4Y6KV5y5sGuORv1KZzWhuKtz/mXNh5xLESUtwC4EndCjA==", + "dev": true, + "requires": { + "@gulp-sourcemaps/identity-map": "1.0.1", + "@gulp-sourcemaps/map-sources": "1.0.0", + "acorn": "4.0.13", + "convert-source-map": "1.5.0", + "css": "2.2.1", + "debug-fabulous": "0.2.1", + "detect-newline": "2.1.0", + "graceful-fs": "4.1.11", + "source-map": "0.5.7", + "strip-bom-string": "1.0.0", + "through2": "2.0.3", + "vinyl": "1.2.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + } + } + }, + "gulp-typescript": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-3.2.2.tgz", + "integrity": "sha1-t+Xh08s193LlPmBAJmAYJuK+d/w=", + "dev": true, + "requires": { + "gulp-util": "3.0.8", + "source-map": "0.5.7", + "through2": "2.0.3", + "vinyl-fs": "2.4.4" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + } + }, + "glob-stream": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", + "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", + "dev": true, + "requires": { + "extend": "3.0.1", + "glob": "5.0.15", + "glob-parent": "3.1.0", + "micromatch": "2.3.11", + "ordered-read-streams": "0.3.0", + "through2": "0.6.5", + "to-absolute-glob": "0.1.1", + "unique-stream": "2.2.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + } + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "gulp-sourcemaps": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz", + "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=", + "dev": true, + "requires": { + "convert-source-map": "1.5.0", + "graceful-fs": "4.1.11", + "strip-bom": "2.0.0", + "through2": "2.0.3", + "vinyl": "1.2.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "ordered-read-streams": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", + "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", + "dev": true, + "requires": { + "is-stream": "1.1.0", + "readable-stream": "2.3.3" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "unique-stream": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", + "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", + "dev": true, + "requires": { + "json-stable-stringify": "1.0.1", + "through2-filter": "2.0.0" + } + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + }, + "vinyl-fs": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", + "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", + "dev": true, + "requires": { + "duplexify": "3.5.1", + "glob-stream": "5.3.5", + "graceful-fs": "4.1.11", + "gulp-sourcemaps": "1.6.0", + "is-valid-glob": "0.3.0", + "lazystream": "1.0.0", + "lodash.isequal": "4.5.0", + "merge-stream": "1.0.1", + "mkdirp": "0.5.1", + "object-assign": "4.1.1", + "readable-stream": "2.3.3", + "strip-bom": "2.0.0", + "strip-bom-stream": "1.0.0", + "through2": "2.0.3", + "through2-filter": "2.0.0", + "vali-date": "1.0.0", + "vinyl": "1.2.0" + } + } + } + }, + "gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "dev": true, + "requires": { + "array-differ": "1.0.0", + "array-uniq": "1.0.3", + "beeper": "1.1.1", + "chalk": "1.1.3", + "dateformat": "2.2.0", + "fancy-log": "1.3.0", + "gulplog": "1.0.0", + "has-gulplog": "0.1.0", + "lodash._reescape": "3.0.0", + "lodash._reevaluate": "3.0.0", + "lodash._reinterpolate": "3.0.0", + "lodash.template": "3.6.2", + "minimist": "1.2.0", + "multipipe": "0.1.2", + "object-assign": "3.0.0", + "replace-ext": "0.0.1", + "through2": "2.0.3", + "vinyl": "0.5.3" + }, + "dependencies": { + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "dev": true + } + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true, + "requires": { + "glogg": "1.0.0" + } + }, + "handlebars": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz", + "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=", + "dev": true, + "requires": { + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.29" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "requires": { + "function-bind": "1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-color": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", + "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", + "dev": true + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dev": true, + "requires": { + "sparkles": "1.0.0" + } + }, + "hash-base": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.0" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "1.1.3", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "dev": true, + "requires": { + "parse-passwd": "1.0.0" + } + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "dev": true + }, + "htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", + "dev": true + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "ieee754": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ini": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", + "dev": true + }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "requires": { + "source-map": "0.5.7" + } + }, + "insert-module-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.1.tgz", + "integrity": "sha1-wDv04BywhtW15azorQr+eInWOMM=", + "dev": true, + "requires": { + "JSONStream": "1.3.1", + "combine-source-map": "0.7.2", + "concat-stream": "1.5.2", + "is-buffer": "1.1.5", + "lexical-scope": "1.2.0", + "process": "0.11.10", + "through2": "2.0.3", + "xtend": "4.0.1" + } + }, + "interpret": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.4.tgz", + "integrity": "sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA=", + "dev": true + }, + "is-absolute": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", + "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", + "dev": true, + "requires": { + "is-relative": "0.2.1", + "is-windows": "0.2.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, + "requires": { + "is-path-inside": "1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "dev": true, + "requires": { + "path-is-inside": "1.0.2" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-relative": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", + "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", + "dev": true, + "requires": { + "is-unc-path": "0.1.2" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-unc-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", + "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", + "dev": true, + "requires": { + "unc-path-regex": "0.1.2" + } + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-valid-glob": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz", + "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=", + "dev": true + }, + "is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "istanbul": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", + "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", + "dev": true, + "requires": { + "abbrev": "1.0.9", + "async": "1.5.2", + "escodegen": "1.8.1", + "esprima": "2.7.3", + "glob": "5.0.15", + "handlebars": "4.0.10", + "js-yaml": "3.10.0", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "once": "1.4.0", + "resolve": "1.1.7", + "supports-color": "3.2.3", + "which": "1.3.0", + "wordwrap": "1.0.0" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "jake": { + "version": "8.0.15", + "resolved": "https://registry.npmjs.org/jake/-/jake-8.0.15.tgz", + "integrity": "sha1-8Np9WOeQrBqPhubuDxk+XZIw6rs=", + "dev": true, + "requires": { + "async": "0.9.2", + "chalk": "0.4.0", + "filelist": "0.0.6", + "minimatch": "3.0.4", + "utilities": "1.0.5" + }, + "dependencies": { + "ansi-styles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", + "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", + "dev": true + }, + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "dev": true + }, + "chalk": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", + "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", + "dev": true, + "requires": { + "ansi-styles": "1.0.0", + "has-color": "0.1.7", + "strip-ansi": "0.1.1" + } + }, + "strip-ansi": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", + "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", + "dev": true + } + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + } + } + }, + "json-stable-stringify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "kew": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", + "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + }, + "labeled-stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz", + "integrity": "sha1-pS4dE4AkwAuGscDJH2d5GLiuClk=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "isarray": "0.0.1", + "stream-splicer": "2.0.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true, + "optional": true + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "2.3.3" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, + "lexical-scope": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/lexical-scope/-/lexical-scope-1.2.0.tgz", + "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=", + "dev": true, + "requires": { + "astw": "2.2.0" + } + }, + "liftoff": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz", + "integrity": "sha1-qY8v9nGD2Lp8+soQVIvX/wVQs4U=", + "dev": true, + "requires": { + "extend": "3.0.1", + "findup-sync": "0.4.3", + "fined": "1.1.0", + "flagged-respawn": "0.3.2", + "lodash.isplainobject": "4.0.6", + "lodash.isstring": "4.0.1", + "lodash.mapvalues": "4.6.0", + "rechoir": "0.6.2", + "resolve": "1.1.7" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + } + } + }, + "lodash": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", + "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", + "dev": true + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", + "dev": true + }, + "lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", + "dev": true + }, + "lodash._escapehtmlchar": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz", + "integrity": "sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0=", + "dev": true, + "requires": { + "lodash._htmlescapes": "2.4.1" + } + }, + "lodash._escapestringchar": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz", + "integrity": "sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I=", + "dev": true + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash._htmlescapes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz", + "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash._isnative": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz", + "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=", + "dev": true + }, + "lodash._objecttypes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", + "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", + "dev": true + }, + "lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", + "dev": true + }, + "lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash._reunescapedhtml": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz", + "integrity": "sha1-dHxPxAED6zu4oJduVx96JlnpO6c=", + "dev": true, + "requires": { + "lodash._htmlescapes": "2.4.1", + "lodash.keys": "2.4.1" + }, + "dependencies": { + "lodash.keys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", + "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", + "dev": true, + "requires": { + "lodash._isnative": "2.4.1", + "lodash._shimkeys": "2.4.1", + "lodash.isobject": "2.4.1" + } + } + } + }, + "lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", + "dev": true + }, + "lodash._shimkeys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz", + "integrity": "sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM=", + "dev": true, + "requires": { + "lodash._objecttypes": "2.4.1" + } + }, + "lodash.defaults": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz", + "integrity": "sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ=", + "dev": true, + "requires": { + "lodash._objecttypes": "2.4.1", + "lodash.keys": "2.4.1" + }, + "dependencies": { + "lodash.keys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", + "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", + "dev": true, + "requires": { + "lodash._isnative": "2.4.1", + "lodash._shimkeys": "2.4.1", + "lodash.isobject": "2.4.1" + } + } + } + }, + "lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "dev": true, + "requires": { + "lodash._root": "3.0.1" + } + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "dev": true + }, + "lodash.isobject": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz", + "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=", + "dev": true, + "requires": { + "lodash._objecttypes": "2.4.1" + } + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "dev": true + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", + "dev": true + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" + } + }, + "lodash.mapvalues": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", + "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=", + "dev": true + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "dev": true + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", + "dev": true + }, + "lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "dev": true, + "requires": { + "lodash._basecopy": "3.0.1", + "lodash._basetostring": "3.0.1", + "lodash._basevalues": "3.0.0", + "lodash._isiterateecall": "3.0.9", + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0", + "lodash.keys": "3.1.2", + "lodash.restparam": "3.6.1", + "lodash.templatesettings": "3.1.1" + } + }, + "lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "dev": true, + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0" + } + }, + "lodash.values": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz", + "integrity": "sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ=", + "dev": true, + "requires": { + "lodash.keys": "2.4.1" + }, + "dependencies": { + "lodash.keys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", + "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", + "dev": true, + "requires": { + "lodash._isnative": "2.4.1", + "lodash._shimkeys": "2.4.1", + "lodash.isobject": "2.4.1" + } + } + } + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + } + }, + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", + "dev": true + }, + "lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", + "dev": true, + "requires": { + "es5-ext": "0.10.31" + } + }, + "make-error": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.0.tgz", + "integrity": "sha1-Uq06M5zPEM5itAQLcI/nByRLi5Y=", + "dev": true + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "dev": true, + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + }, + "dependencies": { + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + } + } + }, + "memoizee": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.11.tgz", + "integrity": "sha1-vemBdmPJ5A/bKk6hw2cpYIeujI8=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.31", + "es6-weak-map": "2.0.2", + "event-emitter": "0.3.5", + "is-promise": "2.1.0", + "lru-queue": "0.1.0", + "next-tick": "1.0.0", + "timers-ext": "0.1.2" + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.4.0", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + } + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "dev": true, + "requires": { + "readable-stream": "2.3.3" + } + }, + "merge2": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.0.tgz", + "integrity": "sha1-D4ghUdmIsfPQdYlFQE+nPuWSPT8=", + "dev": true + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0" + } + }, + "minimalistic-assert": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", + "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "mocha": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.0.1.tgz", + "integrity": "sha512-evDmhkoA+cBNiQQQdSKZa2b9+W2mpLoj50367lhy+Klnx9OV8XlCIhigUnn1gaTFLQCa0kdNhEGDr0hCXOQFDw==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } + } + }, + "mocha-fivemat-progress-reporter": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/mocha-fivemat-progress-reporter/-/mocha-fivemat-progress-reporter-0.1.0.tgz", + "integrity": "sha1-zK/w4ckc9Vf+d+B535lUuRt0d1Y=", + "dev": true + }, + "module-deps": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz", + "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", + "dev": true, + "requires": { + "JSONStream": "1.3.1", + "browser-resolve": "1.11.2", + "cached-path-relative": "1.0.1", + "concat-stream": "1.5.2", + "defined": "1.0.0", + "detective": "4.5.0", + "duplexer2": "0.1.4", + "inherits": "2.0.3", + "parents": "1.0.1", + "readable-stream": "2.3.3", + "resolve": "1.1.7", + "stream-combiner2": "1.1.1", + "subarg": "1.0.0", + "through2": "2.0.3", + "xtend": "4.0.1" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "dev": true, + "requires": { + "duplexer2": "0.0.2" + }, + "dependencies": { + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, + "requires": { + "readable-stream": "1.1.14" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "natives": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz", + "integrity": "sha1-6f+EFBimsux6SV6TmYT3jxY+bjE=", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1.0.9" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "4.3.6", + "validate-npm-package-license": "3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", + "dev": true + }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "requires": { + "array-each": "1.0.1", + "array-slice": "1.0.0", + "for-own": "1.0.0", + "isobject": "3.0.1" + }, + "dependencies": { + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "0.0.10", + "wordwrap": "0.0.3" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + } + }, + "orchestrator": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", + "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", + "dev": true, + "requires": { + "end-of-stream": "0.1.5", + "sequencify": "0.0.7", + "stream-consume": "0.1.0" + } + }, + "ordered-read-streams": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", + "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=", + "dev": true + }, + "os-browserify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.1.2.tgz", + "integrity": "sha1-ScoCk+CxlZCl9d4Qx/JlphfY/lQ=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "dev": true + }, + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", + "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "dev": true, + "requires": { + "asn1.js": "4.9.1", + "browserify-aes": "1.0.8", + "create-hash": "1.1.3", + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.14" + } + }, + "parse-filepath": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz", + "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=", + "dev": true, + "requires": { + "is-absolute": "0.2.6", + "map-cache": "0.2.2", + "path-root": "0.1.1" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "requires": { + "path-root-regex": "0.1.2" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", + "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", + "dev": true, + "requires": { + "create-hash": "1.1.3", + "create-hmac": "1.1.6", + "ripemd160": "2.0.1", + "safe-buffer": "5.1.1", + "sha.js": "2.4.9" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", + "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.1.3", + "parse-asn1": "5.1.0", + "randombytes": "2.0.5" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "q": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", + "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "randombytes": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz", + "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "read-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "dev": true, + "requires": { + "readable-stream": "2.3.3" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "1.1.7" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "1.0.2" + } + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "resolve-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", + "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", + "dev": true, + "requires": { + "expand-tilde": "1.2.2", + "global-modules": "0.2.3" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "optional": true, + "requires": { + "align-text": "0.1.4" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "ripemd160": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "dev": true, + "requires": { + "hash-base": "2.0.2", + "inherits": "2.0.3" + } + }, + "run-sequence": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/run-sequence/-/run-sequence-2.2.0.tgz", + "integrity": "sha512-xW5DmUwdvoyYQUMPKN8UW7TZSFs7AxtT59xo1m5y91jHbvwGlGgOmdV1Yw5P68fkjf3aHUZ4G1o1mZCtNe0qtw==", + "dev": true, + "requires": { + "chalk": "1.1.3", + "gulp-util": "3.0.8" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "sander": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", + "integrity": "sha1-dB4kXiMfB8r7b98PEzrfohalAq0=", + "dev": true, + "requires": { + "es6-promise": "3.3.1", + "graceful-fs": "4.1.11", + "mkdirp": "0.5.1", + "rimraf": "2.6.2" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + } + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "semver": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", + "dev": true + }, + "sequencify": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz", + "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=", + "dev": true + }, + "sha.js": { + "version": "2.4.9", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz", + "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + }, + "shasum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", + "dev": true, + "requires": { + "json-stable-stringify": "0.0.1", + "sha.js": "2.4.9" + } + }, + "shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "dev": true, + "requires": { + "array-filter": "0.0.1", + "array-map": "0.0.0", + "array-reduce": "0.0.0", + "jsonify": "0.0.0" + } + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "sorcery": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.10.0.tgz", + "integrity": "sha1-iukK19fLBfxZ8asMY3hF1cFaUrc=", + "dev": true, + "requires": { + "buffer-crc32": "0.2.13", + "minimist": "1.2.0", + "sander": "0.5.1", + "sourcemap-codec": "1.3.1" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz", + "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=", + "dev": true, + "requires": { + "atob": "1.1.3", + "resolve-url": "0.2.1", + "source-map-url": "0.3.0", + "urix": "0.1.0" + } + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "0.5.7" + } + }, + "source-map-url": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz", + "integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=", + "dev": true + }, + "sourcemap-codec": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.3.1.tgz", + "integrity": "sha1-mtb5vb1pGTEBbjCTnbyGhnMyMUY=", + "dev": true, + "requires": { + "vlq": "0.2.3" + } + }, + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "0.1.4", + "readable-stream": "2.3.3" + } + }, + "stream-consume": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", + "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=", + "dev": true + }, + "stream-http": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", + "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==", + "dev": true, + "requires": { + "builtin-status-codes": "3.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "to-arraybuffer": "1.0.1", + "xtend": "4.0.1" + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true + }, + "stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", + "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3" + } + }, + "streamqueue": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/streamqueue/-/streamqueue-0.0.6.tgz", + "integrity": "sha1-ZvX17JTpuK8knkrsLdH3Qb/pTeM=", + "dev": true, + "requires": { + "readable-stream": "1.1.14" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", + "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", + "dev": true, + "requires": { + "first-chunk-stream": "1.0.0", + "is-utf8": "0.2.1" + } + }, + "strip-bom-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", + "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", + "dev": true, + "requires": { + "first-chunk-stream": "1.0.0", + "strip-bom": "2.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + } + } + }, + "strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "4.0.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "subarg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", + "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", + "dev": true, + "requires": { + "minimist": "1.2.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "syntax-error": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.3.0.tgz", + "integrity": "sha1-HtkmbE1AvnXcVb+bsct3Biu5bKE=", + "dev": true, + "requires": { + "acorn": "4.0.13" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "2.3.3", + "xtend": "4.0.1" + } + }, + "through2-filter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", + "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", + "dev": true, + "requires": { + "through2": "2.0.3", + "xtend": "4.0.1" + } + }, + "tildify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", + "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + } + }, + "time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", + "dev": true + }, + "timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "dev": true, + "requires": { + "process": "0.11.10" + } + }, + "timers-ext": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.2.tgz", + "integrity": "sha1-YcxHp2wavTGV8UUn+XjViulMUgQ=", + "dev": true, + "requires": { + "es5-ext": "0.10.31", + "next-tick": "1.0.0" + } + }, + "to-absolute-glob": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz", + "integrity": "sha1-HN+kcqnvUMI57maZm2YsoOs5k38=", + "dev": true, + "requires": { + "extend-shallow": "2.0.1" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "travis-fold": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/travis-fold/-/travis-fold-0.1.2.tgz", + "integrity": "sha1-/sAF+dyqJZo/lFnOWmkGq6TFRdo=", + "dev": true + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "ts-node": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-3.3.0.tgz", + "integrity": "sha1-wTxqMCTjC+EYDdUwOPwgkonUv2k=", + "dev": true, + "requires": { + "arrify": "1.0.1", + "chalk": "2.1.0", + "diff": "3.3.1", + "make-error": "1.3.0", + "minimist": "1.2.0", + "mkdirp": "0.5.1", + "source-map-support": "0.4.18", + "tsconfig": "6.0.0", + "v8flags": "3.0.1", + "yn": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + }, + "v8flags": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.0.1.tgz", + "integrity": "sha1-3Oj8N5wX2fLJ6e142JzgAFKxt2s=", + "dev": true, + "requires": { + "homedir-polyfill": "1.0.1" + } + } + } + }, + "tsconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-6.0.0.tgz", + "integrity": "sha1-aw6DdgA9evGGT434+J3QBZ/80DI=", + "dev": true, + "requires": { + "strip-bom": "3.0.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "tslib": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.8.0.tgz", + "integrity": "sha512-ymKWWZJST0/CkgduC2qkzjMOWr4bouhuURNXCn/inEX0L57BnRG6FhX76o7FOnsjHazCjfU2LKeSrlS2sIKQJg==", + "dev": true + }, + "tslint": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.7.0.tgz", + "integrity": "sha1-wl4NDJL6EgHCvDDoROCOaCtPNVI=", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "colors": "1.1.2", + "commander": "2.11.0", + "diff": "3.3.1", + "glob": "7.1.2", + "minimatch": "3.0.4", + "resolve": "1.4.0", + "semver": "5.4.1", + "tslib": "1.8.0", + "tsutils": "2.12.1" + }, + "dependencies": { + "resolve": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", + "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + } + } + }, + "tsutils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.12.1.tgz", + "integrity": "sha1-9Nlc4zkciXHkblTEzw7bCiHdWyQ=", + "dev": true, + "requires": { + "tslib": "1.8.0" + } + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2" + } + }, + "type-detect": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.3.tgz", + "integrity": "sha1-Dj8mcLRAmbC0bChNE2p+9Jx0wuo=", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "2.6.0-dev.20171011", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.0-dev.20171011.tgz", + "integrity": "sha512-il66U8zNRbF875Gq6cP3K/CthG7Dp9PRpu5w5mVHaPcolzJhrdLa3K2WavqqJg/7h7sPOZvsU8nYdXO61sHagg==", + "dev": true + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "optional": true, + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "umd": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.1.tgz", + "integrity": "sha1-iuVW4RAR9jwllnCKiDclnwGz1g4=", + "dev": true + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, + "unique-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", + "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=", + "dev": true + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "user-home": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", + "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "utilities": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/utilities/-/utilities-1.0.5.tgz", + "integrity": "sha1-8rd6iPNRBzP8chW1xIalBKdaskU=", + "dev": true + }, + "v8flags": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", + "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", + "dev": true, + "requires": { + "user-home": "1.1.1" + } + }, + "vali-date": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", + "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "dev": true, + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + }, + "vinyl-fs": { + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz", + "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", + "dev": true, + "requires": { + "defaults": "1.0.3", + "glob-stream": "3.1.18", + "glob-watcher": "0.0.6", + "graceful-fs": "3.0.11", + "mkdirp": "0.5.1", + "strip-bom": "1.0.0", + "through2": "0.6.5", + "vinyl": "0.4.6" + }, + "dependencies": { + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "dev": true, + "requires": { + "clone": "0.2.0", + "clone-stats": "0.0.1" + } + } + } + }, + "vlq": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", + "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", + "dev": true + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true, + "optional": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dev": true, + "requires": { + "sax": "1.2.4", + "xmlbuilder": "9.0.4" + } + }, + "xmlbuilder": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.4.tgz", + "integrity": "sha1-UZy0ymhtAFqEINNJbz8MruzKWA8=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "optional": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + }, + "dependencies": { + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true, + "optional": true + } + } + }, + "yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", + "dev": true + } + } +} From 142a88a4aeab6d24a179cc0782d6914eb0904f30 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 11 Oct 2017 10:51:46 -0700 Subject: [PATCH 088/312] Update the comment on emit handler method --- src/compiler/builder.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 093c6ec4d03..192f1e43027 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -76,14 +76,13 @@ namespace ts { * For all source files, either "onUpdateSourceFile" or "onUpdateSourceFileWithSameVersion" will be called. * If the builder is sure that the source file needs an update, "onUpdateSourceFile" will be called; * otherwise "onUpdateSourceFileWithSameVersion" will be called. - * This should return whether the source file should be marked as changed (meaning that something associated with file has changed, e.g. module resolution) */ onUpdateSourceFile(program: Program, sourceFile: SourceFile): void; /** * For all source files, either "onUpdateSourceFile" or "onUpdateSourceFileWithSameVersion" will be called. * If the builder is sure that the source file needs an update, "onUpdateSourceFile" will be called; * otherwise "onUpdateSourceFileWithSameVersion" will be called. - * This should return whether the source file should be marked as changed (meaning that something associated with file has changed, e.g. module resolution) + * This function should return whether the source file should be marked as changed (meaning that something associated with file has changed, e.g. module resolution) */ onUpdateSourceFileWithSameVersion(program: Program, sourceFile: SourceFile): boolean; /** From 81fc2a14d19ae763286f75a6fba61e05e777edd3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 11 Oct 2017 12:01:26 -0700 Subject: [PATCH 089/312] Don't check for callbacks in recursive call that resulted from callbacks --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ce1769118a4..0cb7fe909dc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8579,16 +8579,16 @@ namespace ts { for (let i = 0; i < checkCount; i++) { const sourceType = i < sourceMax ? getTypeOfParameter(sourceParams[i]) : getRestTypeOfSignature(source); const targetType = i < targetMax ? getTypeOfParameter(targetParams[i]) : getRestTypeOfSignature(target); - const sourceSig = getSingleCallSignature(getNonNullableType(sourceType)); - const targetSig = getSingleCallSignature(getNonNullableType(targetType)); // In order to ensure that any generic type Foo is at least co-variant with respect to T no matter // how Foo uses T, we need to relate parameters bi-variantly (given that parameters are input positions, // they naturally relate only contra-variantly). However, if the source and target parameters both have - // function types with a single call signature, we known we are relating two callback parameters. In + // function types with a single call signature, we know we are relating two callback parameters. In // that case it is sufficient to only relate the parameters of the signatures co-variantly because, // similar to return values, callback parameters are output positions. This means that a Promise, // where T is used only in callback parameter positions, will be co-variant (as opposed to bi-variant) // with respect to T. + const sourceSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(sourceType)); + const targetSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(targetType)); const callbacks = sourceSig && targetSig && !sourceSig.typePredicate && !targetSig.typePredicate && (getFalsyFlags(sourceType) & TypeFlags.Nullable) === (getFalsyFlags(targetType) & TypeFlags.Nullable); const related = callbacks ? From 07e4819b8bb5db64c2d00c91b7ce184de1eb4723 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 11 Oct 2017 12:01:38 -0700 Subject: [PATCH 090/312] Add regression test --- tests/cases/compiler/mutuallyRecursiveCallbacks.ts | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tests/cases/compiler/mutuallyRecursiveCallbacks.ts diff --git a/tests/cases/compiler/mutuallyRecursiveCallbacks.ts b/tests/cases/compiler/mutuallyRecursiveCallbacks.ts new file mode 100644 index 00000000000..94f2d285786 --- /dev/null +++ b/tests/cases/compiler/mutuallyRecursiveCallbacks.ts @@ -0,0 +1,7 @@ +// Repro from #18277 + +interface Foo { (bar: Bar): void }; +type Bar = (foo: Foo) => Foo; +declare function foo(bar: Bar): void; +declare var bar: Bar<{}>; +bar = foo; From 38cec121902d505de3cf71711f7c4c847563e9d6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 11 Oct 2017 12:02:01 -0700 Subject: [PATCH 091/312] Accept new baselines --- .../mutuallyRecursiveCallbacks.errors.txt | 24 +++++++++++++ .../reference/mutuallyRecursiveCallbacks.js | 14 ++++++++ .../mutuallyRecursiveCallbacks.symbols | 34 ++++++++++++++++++ .../mutuallyRecursiveCallbacks.types | 35 +++++++++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 tests/baselines/reference/mutuallyRecursiveCallbacks.errors.txt create mode 100644 tests/baselines/reference/mutuallyRecursiveCallbacks.js create mode 100644 tests/baselines/reference/mutuallyRecursiveCallbacks.symbols create mode 100644 tests/baselines/reference/mutuallyRecursiveCallbacks.types diff --git a/tests/baselines/reference/mutuallyRecursiveCallbacks.errors.txt b/tests/baselines/reference/mutuallyRecursiveCallbacks.errors.txt new file mode 100644 index 00000000000..0682caad5b8 --- /dev/null +++ b/tests/baselines/reference/mutuallyRecursiveCallbacks.errors.txt @@ -0,0 +1,24 @@ +tests/cases/compiler/mutuallyRecursiveCallbacks.ts(7,1): error TS2322: Type '(bar: Bar) => void' is not assignable to type 'Bar<{}>'. + Types of parameters 'bar' and 'foo' are incompatible. + Types of parameters 'bar' and 'foo' are incompatible. + Type 'Foo<{}>' is not assignable to type 'Bar<{}>'. + Types of parameters 'bar' and 'foo' are incompatible. + Type 'void' is not assignable to type 'Foo<{}>'. + + +==== tests/cases/compiler/mutuallyRecursiveCallbacks.ts (1 errors) ==== + // Repro from #18277 + + interface Foo { (bar: Bar): void }; + type Bar = (foo: Foo) => Foo; + declare function foo(bar: Bar): void; + declare var bar: Bar<{}>; + bar = foo; + ~~~ +!!! error TS2322: Type '(bar: Bar) => void' is not assignable to type 'Bar<{}>'. +!!! error TS2322: Types of parameters 'bar' and 'foo' are incompatible. +!!! error TS2322: Types of parameters 'bar' and 'foo' are incompatible. +!!! error TS2322: Type 'Foo<{}>' is not assignable to type 'Bar<{}>'. +!!! error TS2322: Types of parameters 'bar' and 'foo' are incompatible. +!!! error TS2322: Type 'void' is not assignable to type 'Foo<{}>'. + \ No newline at end of file diff --git a/tests/baselines/reference/mutuallyRecursiveCallbacks.js b/tests/baselines/reference/mutuallyRecursiveCallbacks.js new file mode 100644 index 00000000000..df52508df7a --- /dev/null +++ b/tests/baselines/reference/mutuallyRecursiveCallbacks.js @@ -0,0 +1,14 @@ +//// [mutuallyRecursiveCallbacks.ts] +// Repro from #18277 + +interface Foo { (bar: Bar): void }; +type Bar = (foo: Foo) => Foo; +declare function foo(bar: Bar): void; +declare var bar: Bar<{}>; +bar = foo; + + +//// [mutuallyRecursiveCallbacks.js] +// Repro from #18277 +; +bar = foo; diff --git a/tests/baselines/reference/mutuallyRecursiveCallbacks.symbols b/tests/baselines/reference/mutuallyRecursiveCallbacks.symbols new file mode 100644 index 00000000000..50cb0c0dea0 --- /dev/null +++ b/tests/baselines/reference/mutuallyRecursiveCallbacks.symbols @@ -0,0 +1,34 @@ +=== tests/cases/compiler/mutuallyRecursiveCallbacks.ts === +// Repro from #18277 + +interface Foo { (bar: Bar): void }; +>Foo : Symbol(Foo, Decl(mutuallyRecursiveCallbacks.ts, 0, 0)) +>T : Symbol(T, Decl(mutuallyRecursiveCallbacks.ts, 2, 14)) +>bar : Symbol(bar, Decl(mutuallyRecursiveCallbacks.ts, 2, 20)) +>Bar : Symbol(Bar, Decl(mutuallyRecursiveCallbacks.ts, 2, 41)) +>T : Symbol(T, Decl(mutuallyRecursiveCallbacks.ts, 2, 14)) + +type Bar = (foo: Foo) => Foo; +>Bar : Symbol(Bar, Decl(mutuallyRecursiveCallbacks.ts, 2, 41)) +>T : Symbol(T, Decl(mutuallyRecursiveCallbacks.ts, 3, 9)) +>foo : Symbol(foo, Decl(mutuallyRecursiveCallbacks.ts, 3, 15)) +>Foo : Symbol(Foo, Decl(mutuallyRecursiveCallbacks.ts, 0, 0)) +>T : Symbol(T, Decl(mutuallyRecursiveCallbacks.ts, 3, 9)) +>Foo : Symbol(Foo, Decl(mutuallyRecursiveCallbacks.ts, 0, 0)) +>T : Symbol(T, Decl(mutuallyRecursiveCallbacks.ts, 3, 9)) + +declare function foo(bar: Bar): void; +>foo : Symbol(foo, Decl(mutuallyRecursiveCallbacks.ts, 3, 38)) +>T : Symbol(T, Decl(mutuallyRecursiveCallbacks.ts, 4, 21)) +>bar : Symbol(bar, Decl(mutuallyRecursiveCallbacks.ts, 4, 24)) +>Bar : Symbol(Bar, Decl(mutuallyRecursiveCallbacks.ts, 2, 41)) +>T : Symbol(T, Decl(mutuallyRecursiveCallbacks.ts, 4, 21)) + +declare var bar: Bar<{}>; +>bar : Symbol(bar, Decl(mutuallyRecursiveCallbacks.ts, 5, 11)) +>Bar : Symbol(Bar, Decl(mutuallyRecursiveCallbacks.ts, 2, 41)) + +bar = foo; +>bar : Symbol(bar, Decl(mutuallyRecursiveCallbacks.ts, 5, 11)) +>foo : Symbol(foo, Decl(mutuallyRecursiveCallbacks.ts, 3, 38)) + diff --git a/tests/baselines/reference/mutuallyRecursiveCallbacks.types b/tests/baselines/reference/mutuallyRecursiveCallbacks.types new file mode 100644 index 00000000000..4a7b4dd0493 --- /dev/null +++ b/tests/baselines/reference/mutuallyRecursiveCallbacks.types @@ -0,0 +1,35 @@ +=== tests/cases/compiler/mutuallyRecursiveCallbacks.ts === +// Repro from #18277 + +interface Foo { (bar: Bar): void }; +>Foo : Foo +>T : T +>bar : Bar +>Bar : Bar +>T : T + +type Bar = (foo: Foo) => Foo; +>Bar : Bar +>T : T +>foo : Foo +>Foo : Foo +>T : T +>Foo : Foo +>T : T + +declare function foo(bar: Bar): void; +>foo : (bar: Bar) => void +>T : T +>bar : Bar +>Bar : Bar +>T : T + +declare var bar: Bar<{}>; +>bar : Bar<{}> +>Bar : Bar + +bar = foo; +>bar = foo : (bar: Bar) => void +>bar : Bar<{}> +>foo : (bar: Bar) => void + From 26290a88ac8daa7bcc4e12f077d2184cd99e0cd3 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 11 Oct 2017 12:07:16 -0700 Subject: [PATCH 092/312] Updated error baseline --- tests/baselines/reference/genericDefaultsErrors.errors.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/genericDefaultsErrors.errors.txt b/tests/baselines/reference/genericDefaultsErrors.errors.txt index 762bb92535b..b1afd6f173b 100644 --- a/tests/baselines/reference/genericDefaultsErrors.errors.txt +++ b/tests/baselines/reference/genericDefaultsErrors.errors.txt @@ -21,7 +21,7 @@ tests/cases/compiler/genericDefaultsErrors.ts(33,15): error TS2707: Generic type tests/cases/compiler/genericDefaultsErrors.ts(36,15): error TS2707: Generic type 'i09' requires between 2 and 3 type arguments. tests/cases/compiler/genericDefaultsErrors.ts(38,20): error TS2304: Cannot find name 'T'. tests/cases/compiler/genericDefaultsErrors.ts(38,20): error TS4033: Property 'x' of exported interface has or is using private name 'T'. -tests/cases/compiler/genericDefaultsErrors.ts(42,29): error TS2715: Type parameter 'T' has a circular default. +tests/cases/compiler/genericDefaultsErrors.ts(42,29): error TS2716: Type parameter 'T' has a circular default. ==== tests/cases/compiler/genericDefaultsErrors.ts (22 errors) ==== @@ -112,4 +112,4 @@ tests/cases/compiler/genericDefaultsErrors.ts(42,29): error TS2715: Type paramet // https://github.com/Microsoft/TypeScript/issues/16221 interface SelfReference {} ~~~~~~~~~~~~~ -!!! error TS2715: Type parameter 'T' has a circular default. \ No newline at end of file +!!! error TS2716: Type parameter 'T' has a circular default. \ No newline at end of file From 4930cad653443ec228e2fba8b9e4ba5d0c9c4fdf Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 11 Oct 2017 13:33:31 -0700 Subject: [PATCH 093/312] Convert all JSDoc parameters and return types of functions --- src/compiler/diagnosticMessages.json | 2 +- .../refactors/annotateWithTypeFromJSDoc.ts | 113 +++++++++--------- .../refactors/convertFunctionToEs6Class.ts | 2 +- 3 files changed, 57 insertions(+), 60 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index ab90d47f2a4..99b45639cac 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3738,7 +3738,7 @@ "category": "Message", "code": 95007 }, - "Annotate with return type from JSDoc": { + "Annotate with types from JSDoc": { "category": "Message", "code": 95008 } diff --git a/src/services/refactors/annotateWithTypeFromJSDoc.ts b/src/services/refactors/annotateWithTypeFromJSDoc.ts index 3111c0d3ed9..529793b7cd1 100644 --- a/src/services/refactors/annotateWithTypeFromJSDoc.ts +++ b/src/services/refactors/annotateWithTypeFromJSDoc.ts @@ -5,13 +5,13 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { const annotateTypeFromJSDoc: Refactor = { name: "Annotate with type from JSDoc", description: Diagnostics.Annotate_with_type_from_JSDoc.message, - getEditsForAction, + getEditsForAction: getEditsForAnnotation, getAvailableActions }; - const annotateReturnTypeFromJSDoc: Refactor = { - name: "Annotate with return type from JSDoc", - description: Diagnostics.Annotate_with_return_type_from_JSDoc.message, - getEditsForAction, + const annotateFunctionFromJSDoc: Refactor = { + name: "Annotate with types from JSDoc", + description: Diagnostics.Annotate_with_types_from_JSDoc.message, + getEditsForAction: getEditsForFunctionAnnotation, getAvailableActions }; @@ -23,7 +23,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { | PropertyDeclaration; registerRefactor(annotateTypeFromJSDoc); - registerRefactor(annotateReturnTypeFromJSDoc); + registerRefactor(annotateFunctionFromJSDoc); function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { if (isInJavaScriptFile(context.file)) { @@ -33,8 +33,10 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { const node = getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false); const decl = findAncestor(node, isTypedNode); if (decl && !decl.type) { - const annotate = getJSDocType(decl) ? annotateTypeFromJSDoc : - getJSDocReturnType(decl) ? annotateReturnTypeFromJSDoc : + const type = getJSDocType(decl); + const returnType = getJSDocReturnType(decl); + const annotate = (returnType || type && decl.kind === SyntaxKind.Parameter) ? annotateFunctionFromJSDoc : + type ? annotateTypeFromJSDoc : undefined; if (annotate) { return [{ @@ -51,16 +53,14 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { } } - function getEditsForAction(context: RefactorContext, action: string): RefactorEditInfo | undefined { - // Somehow wrong action got invoked? + function getEditsForAnnotation(context: RefactorContext, action: string): RefactorEditInfo | undefined { if (actionName !== action) { Debug.fail(`actionName !== action: ${actionName} !== ${action}`); return undefined; } - const start = context.startPosition; const sourceFile = context.file; - const token = getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); + const token = getTokenAtPosition(sourceFile, context.startPosition, /*includeJsDocComment*/ false); const decl = findAncestor(token, isTypedNode); const jsdocType = getJSDocReturnType(decl) || getJSDocType(decl); if (!decl || !jsdocType || decl.type) { @@ -69,19 +69,25 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { } const changeTracker = textChanges.ChangeTracker.fromContext(context); - if (isParameterOfSimpleArrowFunction(decl)) { - // `x => x` becomes `(x: number) => x`, but in order to make the changeTracker generate the parentheses, - // we have to replace the entire function; it doesn't check that the node it's replacing might require - // other syntax changes - const arrow = decl.parent as ArrowFunction; - const param = decl as ParameterDeclaration; - const replacementParam = createParameter(param.decorators, param.modifiers, param.dotDotDotToken, param.name, param.questionToken, transformJSDocType(jsdocType) as TypeNode, param.initializer); - const replacement = createArrowFunction(arrow.modifiers, arrow.typeParameters, [replacementParam], arrow.type, arrow.equalsGreaterThanToken, arrow.body); - changeTracker.replaceRange(sourceFile, { pos: arrow.getStart(), end: arrow.end }, replacement); - } - else { - changeTracker.replaceRange(sourceFile, { pos: decl.getStart(), end: decl.end }, replaceType(decl, transformJSDocType(jsdocType) as TypeNode)); + changeTracker.replaceRange(sourceFile, { pos: decl.getStart(), end: decl.end }, addType(decl, transformJSDocType(jsdocType) as TypeNode)); + return { + edits: changeTracker.getChanges(), + renameFilename: undefined, + renameLocation: undefined + }; + } + + function getEditsForFunctionAnnotation(context: RefactorContext, action: string): RefactorEditInfo | undefined { + if (actionName !== action) { + Debug.fail(`actionName !== action: ${actionName} !== ${action}`); + return undefined; } + + const sourceFile = context.file; + const token = getTokenAtPosition(sourceFile, context.startPosition, /*includeJsDocComment*/ false); + const decl = findAncestor(token, isFunctionLikeDeclaration); + const changeTracker = textChanges.ChangeTracker.fromContext(context); + changeTracker.replaceRange(sourceFile, { pos: decl.getStart(), end: decl.end }, addTypesToFunctionLike(decl)); return { edits: changeTracker.getChanges(), renameFilename: undefined, @@ -97,53 +103,44 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { node.kind === SyntaxKind.PropertyDeclaration; } - function replaceType(decl: DeclarationWithType, jsdocType: TypeNode) { + function addTypesToFunctionLike(decl: FunctionLikeDeclaration) { + const returnType = decl.type || transformJSDocType(getJSDocReturnType(decl)) as TypeNode; + const parameters = decl.parameters.map( + p => createParameter(p.decorators, p.modifiers, p.dotDotDotToken, p.name, p.questionToken, p.type || transformJSDocType(getJSDocType(p)) as TypeNode, p.initializer)); + switch (decl.kind) { + case SyntaxKind.FunctionDeclaration: + return createFunctionDeclaration(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.typeParameters, parameters, returnType, decl.body); + case SyntaxKind.Constructor: + return createConstructor(decl.decorators, decl.modifiers, parameters, decl.body); + case SyntaxKind.FunctionExpression: + return createFunctionExpression(decl.modifiers, decl.asteriskToken, (decl as FunctionExpression).name, decl.typeParameters, parameters, returnType, decl.body); + case SyntaxKind.ArrowFunction: + return createArrowFunction(decl.modifiers, decl.typeParameters, parameters, returnType, decl.equalsGreaterThanToken, decl.body); + case SyntaxKind.MethodDeclaration: + return createMethod(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.questionToken, decl.typeParameters, parameters, returnType, decl.body); + case SyntaxKind.GetAccessor: + return createGetAccessor(decl.decorators, decl.modifiers, decl.name, parameters, returnType, decl.body); + case SyntaxKind.SetAccessor: + return createSetAccessor(decl.decorators, decl.modifiers, decl.name, parameters, decl.body); + default: + return Debug.fail(`Unexpected SyntaxKind: ${(decl as any).kind}`); + } + } + + function addType(decl: DeclarationWithType, jsdocType: TypeNode) { switch (decl.kind) { case SyntaxKind.VariableDeclaration: return createVariableDeclaration(decl.name, jsdocType, decl.initializer); - case SyntaxKind.Parameter: - return createParameter(decl.decorators, decl.modifiers, decl.dotDotDotToken, decl.name, decl.questionToken, jsdocType, decl.initializer); case SyntaxKind.PropertySignature: return createPropertySignature(decl.modifiers, decl.name, decl.questionToken, jsdocType, decl.initializer); case SyntaxKind.PropertyDeclaration: return createProperty(decl.decorators, decl.modifiers, decl.name, decl.questionToken, jsdocType, decl.initializer); - case SyntaxKind.FunctionDeclaration: - return createFunctionDeclaration(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.typeParameters, decl.parameters, jsdocType, decl.body); - case SyntaxKind.FunctionExpression: - return createFunctionExpression(decl.modifiers, decl.asteriskToken, decl.name, decl.typeParameters, decl.parameters, jsdocType, decl.body); - case SyntaxKind.ArrowFunction: - return createArrowFunction(decl.modifiers, decl.typeParameters, decl.parameters, jsdocType, decl.equalsGreaterThanToken, decl.body); - case SyntaxKind.MethodDeclaration: - return createMethod(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.questionToken, decl.typeParameters, decl.parameters, jsdocType, decl.body); - case SyntaxKind.GetAccessor: - return createGetAccessor(decl.decorators, decl.modifiers, decl.name, decl.parameters, jsdocType, decl.body); default: Debug.fail(`Unexpected SyntaxKind: ${decl.kind}`); return undefined; } } - function isParameterOfSimpleArrowFunction(decl: DeclarationWithType) { - return decl.kind === SyntaxKind.Parameter && decl.parent.kind === SyntaxKind.ArrowFunction && isSimpleArrowFunction(decl.parent); - } - - function isSimpleArrowFunction(parentNode: FunctionTypeNode | ArrowFunction | JSDocFunctionType) { - const parameter = singleOrUndefined(parentNode.parameters); - return parameter - && parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter - && !(isArrowFunction(parentNode) && parentNode.type) // arrow function may not have return type annotation - && !some(parentNode.decorators) // parent may not have decorators - && !some(parentNode.modifiers) // parent may not have modifiers - && !some(parentNode.typeParameters) // parent may not have type parameters - && !some(parameter.decorators) // parameter may not have decorators - && !some(parameter.modifiers) // parameter may not have modifiers - && !parameter.dotDotDotToken // parameter may not be rest - && !parameter.questionToken // parameter may not be optional - && !parameter.type // parameter may not have a type annotation - && !parameter.initializer // parameter may not have an initializer - && isIdentifier(parameter.name); // parameter name must be identifier - } - function transformJSDocType(node: Node): Node | undefined { if (node === undefined) { return undefined; diff --git a/src/services/refactors/convertFunctionToEs6Class.ts b/src/services/refactors/convertFunctionToEs6Class.ts index e4cd1a42083..6634dd6121a 100644 --- a/src/services/refactors/convertFunctionToEs6Class.ts +++ b/src/services/refactors/convertFunctionToEs6Class.ts @@ -261,4 +261,4 @@ namespace ts.refactor.convertFunctionToES6Class { return cls; } } -} \ No newline at end of file +} From 1a1c1f9e93a6383192aca0a94d10d6d5ce9334b3 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 11 Oct 2017 13:34:16 -0700 Subject: [PATCH 094/312] Add and update jsdoc annotation refactoring tests --- .../fourslash/annotateWithTypeFromJSDoc10.ts | 2 +- .../fourslash/annotateWithTypeFromJSDoc11.ts | 2 +- .../fourslash/annotateWithTypeFromJSDoc12.ts | 2 +- .../fourslash/annotateWithTypeFromJSDoc13.ts | 2 +- .../fourslash/annotateWithTypeFromJSDoc14.ts | 2 +- .../fourslash/annotateWithTypeFromJSDoc15.ts | 130 +----------------- .../fourslash/annotateWithTypeFromJSDoc16.ts | 4 +- .../fourslash/annotateWithTypeFromJSDoc17.ts | 18 +++ .../fourslash/annotateWithTypeFromJSDoc18.ts | 11 ++ .../fourslash/annotateWithTypeFromJSDoc3.ts | 34 +---- .../fourslash/annotateWithTypeFromJSDoc4.ts | 88 +----------- .../fourslash/annotateWithTypeFromJSDoc7.ts | 4 +- .../fourslash/annotateWithTypeFromJSDoc8.ts | 4 +- .../fourslash/annotateWithTypeFromJSDoc9.ts | 2 +- 14 files changed, 47 insertions(+), 258 deletions(-) create mode 100644 tests/cases/fourslash/annotateWithTypeFromJSDoc17.ts create mode 100644 tests/cases/fourslash/annotateWithTypeFromJSDoc18.ts diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc10.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc10.ts index 88b565fa932..0553a411c2e 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc10.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc10.ts @@ -12,4 +12,4 @@ verify.fileAfterApplyingRefactorAtMarker('1', * @param {?} x * @returns {number} */ -var f = (x): number => x`, 'Annotate with return type from JSDoc', 'annotate'); +var f = (x: any): number => x`, 'Annotate with types from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc11.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc11.ts index 63b2d85fbfe..aaa7aaefa5b 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc11.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc11.ts @@ -12,4 +12,4 @@ verify.fileAfterApplyingRefactorAtMarker('2', * @param {?} x * @returns {number} */ -var f = (x: any) => x`, 'Annotate with type from JSDoc', 'annotate'); +var f = (x: any): number => x`, 'Annotate with types from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc12.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc12.ts index 95fa0b55cd2..c3c1aad5a90 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc12.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc12.ts @@ -18,4 +18,4 @@ verify.fileAfterApplyingRefactorAtMarker('1', */ m(x): any[] { } -}`, 'Annotate with return type from JSDoc', 'annotate'); +}`, 'Annotate with types from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc13.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc13.ts index caa3315b87f..a47c090cd17 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc13.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc13.ts @@ -8,4 +8,4 @@ verify.fileAfterApplyingRefactorAtMarker('1', `class C { /** @return {number} */ get c(): number { return 12; } -}`, 'Annotate with return type from JSDoc', 'annotate'); +}`, 'Annotate with types from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc14.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc14.ts index 43ac95a1c4a..13b4591de47 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc14.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc14.ts @@ -8,4 +8,4 @@ verify.fileAfterApplyingRefactorAtMarker('1', `/** @return {number} */ function f(): number { return 12; -}`, 'Annotate with return type from JSDoc', 'annotate'); +}`, 'Annotate with types from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc15.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc15.ts index 487b456d561..c316430b718 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc15.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc15.ts @@ -13,134 +13,6 @@ //// */ ////function f(/*1*/x, /*2*/y, /*3*/z, /*4*/alpha, /*5*/beta, /*6*/gamma, /*7*/delta, /*8*/epsilon, /*9*/zeta) { ////} -verify.applicableRefactorAvailableAtMarker('1'); -verify.fileAfterApplyingRefactorAtMarker('1', -`/** - * @param {Boolean} x - * @param {String} y - * @param {Number} z - * @param {Object} alpha - * @param {date} beta - * @param {promise} gamma - * @param {array} delta - * @param {Array} epsilon - * @param {promise} zeta - */ -function f(x: boolean, y, z, alpha, beta, gamma, delta, epsilon, zeta) { -}`, 'Annotate with type from JSDoc', 'annotate'); - -verify.applicableRefactorAvailableAtMarker('2'); -verify.fileAfterApplyingRefactorAtMarker('2', -`/** - * @param {Boolean} x - * @param {String} y - * @param {Number} z - * @param {Object} alpha - * @param {date} beta - * @param {promise} gamma - * @param {array} delta - * @param {Array} epsilon - * @param {promise} zeta - */ -function f(x: boolean, y: string, z, alpha, beta, gamma, delta, epsilon, zeta) { -}`, 'Annotate with type from JSDoc', 'annotate'); - -verify.applicableRefactorAvailableAtMarker('3'); -verify.fileAfterApplyingRefactorAtMarker('3', -`/** - * @param {Boolean} x - * @param {String} y - * @param {Number} z - * @param {Object} alpha - * @param {date} beta - * @param {promise} gamma - * @param {array} delta - * @param {Array} epsilon - * @param {promise} zeta - */ -function f(x: boolean, y: string, z: number, alpha, beta, gamma, delta, epsilon, zeta) { -}`, 'Annotate with type from JSDoc', 'annotate'); - -verify.applicableRefactorAvailableAtMarker('4'); -verify.fileAfterApplyingRefactorAtMarker('4', -`/** - * @param {Boolean} x - * @param {String} y - * @param {Number} z - * @param {Object} alpha - * @param {date} beta - * @param {promise} gamma - * @param {array} delta - * @param {Array} epsilon - * @param {promise} zeta - */ -function f(x: boolean, y: string, z: number, alpha: object, beta, gamma, delta, epsilon, zeta) { -}`, 'Annotate with type from JSDoc', 'annotate'); - -verify.applicableRefactorAvailableAtMarker('5'); -verify.fileAfterApplyingRefactorAtMarker('5', -`/** - * @param {Boolean} x - * @param {String} y - * @param {Number} z - * @param {Object} alpha - * @param {date} beta - * @param {promise} gamma - * @param {array} delta - * @param {Array} epsilon - * @param {promise} zeta - */ -function f(x: boolean, y: string, z: number, alpha: object, beta: Date, gamma, delta, epsilon, zeta) { -}`, 'Annotate with type from JSDoc', 'annotate'); - -verify.applicableRefactorAvailableAtMarker('6'); -verify.fileAfterApplyingRefactorAtMarker('6', -`/** - * @param {Boolean} x - * @param {String} y - * @param {Number} z - * @param {Object} alpha - * @param {date} beta - * @param {promise} gamma - * @param {array} delta - * @param {Array} epsilon - * @param {promise} zeta - */ -function f(x: boolean, y: string, z: number, alpha: object, beta: Date, gamma: Promise, delta, epsilon, zeta) { -}`, 'Annotate with type from JSDoc', 'annotate'); - -verify.applicableRefactorAvailableAtMarker('7'); -verify.fileAfterApplyingRefactorAtMarker('7', -`/** - * @param {Boolean} x - * @param {String} y - * @param {Number} z - * @param {Object} alpha - * @param {date} beta - * @param {promise} gamma - * @param {array} delta - * @param {Array} epsilon - * @param {promise} zeta - */ -function f(x: boolean, y: string, z: number, alpha: object, beta: Date, gamma: Promise, delta: Array, epsilon, zeta) { -}`, 'Annotate with type from JSDoc', 'annotate'); - -verify.applicableRefactorAvailableAtMarker('8'); -verify.fileAfterApplyingRefactorAtMarker('8', -`/** - * @param {Boolean} x - * @param {String} y - * @param {Number} z - * @param {Object} alpha - * @param {date} beta - * @param {promise} gamma - * @param {array} delta - * @param {Array} epsilon - * @param {promise} zeta - */ -function f(x: boolean, y: string, z: number, alpha: object, beta: Date, gamma: Promise, delta: Array, epsilon: Array, zeta) { -}`, 'Annotate with type from JSDoc', 'annotate'); - verify.applicableRefactorAvailableAtMarker('9'); verify.fileAfterApplyingRefactorAtMarker('9', `/** @@ -155,4 +27,4 @@ verify.fileAfterApplyingRefactorAtMarker('9', * @param {promise} zeta */ function f(x: boolean, y: string, z: number, alpha: object, beta: Date, gamma: Promise, delta: Array, epsilon: Array, zeta: Promise) { -}`, 'Annotate with type from JSDoc', 'annotate'); +}`, 'Annotate with types from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc16.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc16.ts index 2f5ab2bcc72..a332a84d910 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc16.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc16.ts @@ -1,9 +1,9 @@ /// // @strict: true /////** @type {function(*, ...number, ...boolean): void} */ -////var /*1*/x; +////var /*1*/x = (x, ys, ...zs) => { }; verify.applicableRefactorAvailableAtMarker('1'); verify.fileAfterApplyingRefactorAtMarker('1', `/** @type {function(*, ...number, ...boolean): void} */ -var x: (arg0: any, arg1: number[], ...rest: boolean[]) => void;`, 'Annotate with type from JSDoc', 'annotate'); +var x: (arg0: any, arg1: number[], ...rest: boolean[]) => void = (x, ys, ...zs) => { };`, 'Annotate with type from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc17.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc17.ts new file mode 100644 index 00000000000..ed3180d3bd8 --- /dev/null +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc17.ts @@ -0,0 +1,18 @@ +/// +////class C { +//// /** +//// * @param {number} x - the first parameter +//// */ +//// constructor(/*1*/x) { +//// } +////} +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`class C { + /** + * @param {number} x - the first parameter + */ + constructor(x: number) { + } +}`, 'Annotate with types from JSDoc', 'annotate'); + diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc18.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc18.ts new file mode 100644 index 00000000000..9cfcb5c2471 --- /dev/null +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc18.ts @@ -0,0 +1,11 @@ +/// +////class C { +//// /** @param {number} value */ +//// set c(/*1*/value) { return 12 } +////} +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`class C { + /** @param {number} value */ + set c(value: number) { return 12; } +}`, 'Annotate with types from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc3.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc3.ts index 985b89ed709..ca5dbe312e3 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc3.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc3.ts @@ -9,37 +9,10 @@ ////function f(/*1*/x, /*2*/y, /*3*/z: string, /*4*/alpha, /*5*/beta) { ////} -verify.applicableRefactorAvailableAtMarker('1'); -verify.fileAfterApplyingRefactorAtMarker('1', -`/** - * @param {number} x - the first parameter - * @param {{ a: string, b: Date }} y - the most complex parameter - * @param z - the best parameter - * @param alpha - the other best parameter - * @param {*} beta - I have no idea how this got here - */ -function f(x: number, y, z: string, alpha, beta) { -}`, 'Annotate with type from JSDoc', 'annotate'); - -verify.applicableRefactorAvailableAtMarker('2'); -verify.fileAfterApplyingRefactorAtMarker('2', -`/** - * @param {number} x - the first parameter - * @param {{ a: string, b: Date }} y - the most complex parameter - * @param z - the best parameter - * @param alpha - the other best parameter - * @param {*} beta - I have no idea how this got here - */ -function f(x: number, y: { - a: string; - b: Date; -}, z: string, alpha, beta) { -}`, 'Annotate with type from JSDoc', 'annotate'); - verify.not.applicableRefactorAvailableAtMarker('3'); verify.not.applicableRefactorAvailableAtMarker('4'); -verify.applicableRefactorAvailableAtMarker('5'); -verify.fileAfterApplyingRefactorAtMarker('5', +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', `/** * @param {number} x - the first parameter * @param {{ a: string, b: Date }} y - the most complex parameter @@ -51,4 +24,5 @@ function f(x: number, y: { a: string; b: Date; }, z: string, alpha, beta: any) { -}`, 'Annotate with type from JSDoc', 'annotate'); +}`, 'Annotate with types from JSDoc', 'annotate'); + diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc4.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc4.ts index d4d5384b19c..2a2d7f943e2 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc4.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc4.ts @@ -12,94 +12,8 @@ ////function f(/*1*/x, /*2*/y, /*3*/z, /*4*/alpha, /*5*/beta, /*6*/gamma, /*7*/delta) { ////} -verify.applicableRefactorAvailableAtMarker('1'); -verify.fileAfterApplyingRefactorAtMarker('1', -`/** - * @param {*} x - * @param {?} y - * @param {number=} z - * @param {...number} alpha - * @param {function(this:{ a: string}, string, number): boolean} beta - * @param {number?} gamma - * @param {number!} delta - */ -function f(x: any, y, z, alpha, beta, gamma, delta) { -}`, 'Annotate with type from JSDoc', 'annotate'); - -verify.applicableRefactorAvailableAtMarker('2'); -verify.fileAfterApplyingRefactorAtMarker('2', -`/** - * @param {*} x - * @param {?} y - * @param {number=} z - * @param {...number} alpha - * @param {function(this:{ a: string}, string, number): boolean} beta - * @param {number?} gamma - * @param {number!} delta - */ -function f(x: any, y: any, z, alpha, beta, gamma, delta) { -}`, 'Annotate with type from JSDoc', 'annotate'); - -verify.applicableRefactorAvailableAtMarker('3'); -verify.fileAfterApplyingRefactorAtMarker('3', -`/** - * @param {*} x - * @param {?} y - * @param {number=} z - * @param {...number} alpha - * @param {function(this:{ a: string}, string, number): boolean} beta - * @param {number?} gamma - * @param {number!} delta - */ -function f(x: any, y: any, z: number | undefined, alpha, beta, gamma, delta) { -}`, 'Annotate with type from JSDoc', 'annotate'); -verify.applicableRefactorAvailableAtMarker('4'); -verify.fileAfterApplyingRefactorAtMarker('4', -`/** - * @param {*} x - * @param {?} y - * @param {number=} z - * @param {...number} alpha - * @param {function(this:{ a: string}, string, number): boolean} beta - * @param {number?} gamma - * @param {number!} delta - */ -function f(x: any, y: any, z: number | undefined, alpha: number[], beta, gamma, delta) { -}`, 'Annotate with type from JSDoc', 'annotate'); - verify.applicableRefactorAvailableAtMarker('5'); verify.fileAfterApplyingRefactorAtMarker('5', -`/** - * @param {*} x - * @param {?} y - * @param {number=} z - * @param {...number} alpha - * @param {function(this:{ a: string}, string, number): boolean} beta - * @param {number?} gamma - * @param {number!} delta - */ -function f(x: any, y: any, z: number | undefined, alpha: number[], beta: (this: { - a: string; -}, arg1: string, arg2: number) => boolean, gamma, delta) { -}`, 'Annotate with type from JSDoc', 'annotate'); -verify.applicableRefactorAvailableAtMarker('6'); -verify.fileAfterApplyingRefactorAtMarker('6', -`/** - * @param {*} x - * @param {?} y - * @param {number=} z - * @param {...number} alpha - * @param {function(this:{ a: string}, string, number): boolean} beta - * @param {number?} gamma - * @param {number!} delta - */ -function f(x: any, y: any, z: number | undefined, alpha: number[], beta: (this: { - a: string; -}, arg1: string, arg2: number) => boolean, gamma: number | null, delta) { -}`, 'Annotate with type from JSDoc', 'annotate'); - -verify.applicableRefactorAvailableAtMarker('7'); -verify.fileAfterApplyingRefactorAtMarker('7', `/** * @param {*} x * @param {?} y @@ -112,4 +26,4 @@ verify.fileAfterApplyingRefactorAtMarker('7', function f(x: any, y: any, z: number | undefined, alpha: number[], beta: (this: { a: string; }, arg1: string, arg2: number) => boolean, gamma: number | null, delta: number) { -}`, 'Annotate with type from JSDoc', 'annotate'); +}`, 'Annotate with types from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc7.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc7.ts index c78f8949b18..a99ea823389 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc7.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc7.ts @@ -13,5 +13,5 @@ verify.fileAfterApplyingRefactorAtMarker('1', * @param {number} x * @returns {number} */ -function f(x): number { -}`, 'Annotate with return type from JSDoc', 'annotate'); +function f(x: number): number { +}`, 'Annotate with types from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc8.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc8.ts index 502b945819c..72ddb36988e 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc8.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc8.ts @@ -13,5 +13,5 @@ verify.fileAfterApplyingRefactorAtMarker('1', * @param {number} x * @returns {number} */ -var f = function(x): number { -}`, 'Annotate with return type from JSDoc', 'annotate'); +var f = function(x: number): number { +}`, 'Annotate with types from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc9.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc9.ts index cf2581f5d8f..6b967e8e004 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc9.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc9.ts @@ -12,4 +12,4 @@ verify.fileAfterApplyingRefactorAtMarker('1', * @param {?} x * @returns {number} */ -var f = (x: any) => x`, 'Annotate with type from JSDoc', 'annotate'); +var f = (x: any): number => x`, 'Annotate with types from JSDoc', 'annotate'); From deed981715dcce5d10b3cbfa1701794672212be3 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 11 Oct 2017 12:27:21 -0700 Subject: [PATCH 095/312] Handle case sensitivity when looking up config file for Script info Fixes #17726 --- .../unittests/tsserverProjectSystem.ts | 46 +++++++++++++++++++ src/server/editorServices.ts | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 2d761ae33c2..f7d082128cd 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -2917,6 +2917,52 @@ namespace ts.projectSystem { function checkSnapLength(snap: IScriptSnapshot, expectedLength: number) { assert.equal(snap.getLength(), expectedLength, "Incorrect snapshot size"); } + + function verifyOpenFileWorks(useCaseSensitiveFileNames: boolean) { + const file1: FileOrFolder = { + path: "/a/b/src/app.ts", + content: "let x = 10;" + }; + const file2: FileOrFolder = { + path: "/a/B/lib/module2.ts", + content: "let z = 10;" + }; + const configFile: FileOrFolder = { + path: "/a/b/tsconfig.json", + content: "" + }; + const configFile2: FileOrFolder = { + path: "/a/tsconfig.json", + content: "" + }; + const host = createServerHost([file1, file2, configFile, configFile2], { + useCaseSensitiveFileNames + }); + const service = createProjectService(host); + + // Open file1 -> configFile + verifyConfigFileName(file1, "/a", configFile); + verifyConfigFileName(file1, "/a/b", configFile); + verifyConfigFileName(file1, "/a/B", useCaseSensitiveFileNames ? undefined : configFile); + + // Open file2 use root "/a/b" + verifyConfigFileName(file2, "/a", useCaseSensitiveFileNames ? configFile2 : configFile); + verifyConfigFileName(file2, "/a/b", useCaseSensitiveFileNames ? undefined : configFile); + verifyConfigFileName(file2, "/a/B", useCaseSensitiveFileNames ? undefined : configFile); + + function verifyConfigFileName(file: FileOrFolder, projectRoot: string, expectedConfigFile: FileOrFolder | undefined) { + const { configFileName } = service.openClientFile(file.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, projectRoot); + assert.equal(configFileName, expectedConfigFile && expectedConfigFile.path); + service.closeClientFile(file.path); + } + } + it("works when project root is used with case-sensitive system", () => { + verifyOpenFileWorks(/*useCaseSensitiveFileNames*/ true); + }); + + it("works when project root is used with case-insensitive system", () => { + verifyOpenFileWorks(/*useCaseSensitiveFileNames*/ false); + }); }); describe("Language service", () => { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 173fd86afe4..379a5fbfe7e 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1218,7 +1218,7 @@ namespace ts.server { projectRootPath?: NormalizedPath) { let searchPath = asNormalizedPath(getDirectoryPath(info.fileName)); - while (!projectRootPath || stringContains(searchPath, projectRootPath)) { + while (!projectRootPath || containsPath(projectRootPath, searchPath, this.currentDirectory, !this.host.useCaseSensitiveFileNames)) { const canonicalSearchPath = normalizedPathToPath(searchPath, this.currentDirectory, this.toCanonicalFileName); const tsconfigFileName = asNormalizedPath(combinePaths(searchPath, "tsconfig.json")); let result = action(tsconfigFileName, combinePaths(canonicalSearchPath, "tsconfig.json")); From 7e1dd66c19d01fea072ab32a16a8d7354cae247d Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 11 Oct 2017 13:44:07 -0700 Subject: [PATCH 096/312] Update to use `help wanted` instead of `Accepting PRs` (#19105) --- pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pull_request_template.md b/pull_request_template.md index 683e6acbf89..2c49c84641b 100644 --- a/pull_request_template.md +++ b/pull_request_template.md @@ -3,7 +3,7 @@ Thank you for submitting a pull request! Here's a checklist you might find useful. [ ] There is an associated issue that is labelled - 'Bug' or 'Accepting PRs' or is in the Community milestone + 'Bug' or 'help wanted' or is in the Community milestone [ ] Code is up-to-date with the `master` branch [ ] You've successfully run `jake runtests` locally [ ] You've signed the CLA From 3fef16008d2c29951476321144763b0ce9d5a777 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 11 Oct 2017 14:01:25 -0700 Subject: [PATCH 097/312] Fill missing type arguments during error reporting Previously, only the success path did this; it was missing in the error reporting path in resolveCall. This resulted in crashes for unsupplied type arguments when the supplied type arguments were incorrect. --- src/compiler/checker.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 36ee2a00eb9..56835e13dde 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16203,8 +16203,10 @@ namespace ts { checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, /*reportErrors*/ true); } else if (candidateForTypeArgumentError) { + const isJavascript = isInJavaScriptFile(candidateForTypeArgumentError.declaration); const typeArguments = (node).typeArguments; - checkTypeArguments(candidateForTypeArgumentError, typeArguments, map(typeArguments, getTypeFromTypeNode), /*reportErrors*/ true, fallbackError); + const typeArgumentTypes = fillMissingTypeArguments(map(typeArguments, getTypeFromTypeNode), candidateForTypeArgumentError.typeParameters, getMinTypeArgumentCount(candidateForTypeArgumentError.typeParameters), isJavascript); + checkTypeArguments(candidateForTypeArgumentError, typeArguments, typeArgumentTypes, /*reportErrors*/ true, fallbackError); } else if (typeArguments && every(signatures, sig => length(sig.typeParameters) !== typeArguments.length)) { let min = Number.POSITIVE_INFINITY; From 156e7e206969b63247944e420a0b6abda970c925 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 11 Oct 2017 14:02:20 -0700 Subject: [PATCH 098/312] Test:Incorrect number of type args during err reporting --- ...peArgumentsDuringErrorReporting.errors.txt | 28 ++++++++ ...mberOfTypeArgumentsDuringErrorReporting.js | 30 ++++++++ ...fTypeArgumentsDuringErrorReporting.symbols | 60 ++++++++++++++++ ...rOfTypeArgumentsDuringErrorReporting.types | 68 +++++++++++++++++++ ...mberOfTypeArgumentsDuringErrorReporting.ts | 21 ++++++ 5 files changed, 207 insertions(+) create mode 100644 tests/baselines/reference/incorrectNumberOfTypeArgumentsDuringErrorReporting.errors.txt create mode 100644 tests/baselines/reference/incorrectNumberOfTypeArgumentsDuringErrorReporting.js create mode 100644 tests/baselines/reference/incorrectNumberOfTypeArgumentsDuringErrorReporting.symbols create mode 100644 tests/baselines/reference/incorrectNumberOfTypeArgumentsDuringErrorReporting.types create mode 100644 tests/cases/compiler/incorrectNumberOfTypeArgumentsDuringErrorReporting.ts diff --git a/tests/baselines/reference/incorrectNumberOfTypeArgumentsDuringErrorReporting.errors.txt b/tests/baselines/reference/incorrectNumberOfTypeArgumentsDuringErrorReporting.errors.txt new file mode 100644 index 00000000000..41aadb4d465 --- /dev/null +++ b/tests/baselines/reference/incorrectNumberOfTypeArgumentsDuringErrorReporting.errors.txt @@ -0,0 +1,28 @@ +tests/cases/compiler/incorrectNumberOfTypeArgumentsDuringErrorReporting.ts(18,4): error TS2559: Type 'MyObjA' has no properties in common with type 'ObjA'. + + +==== tests/cases/compiler/incorrectNumberOfTypeArgumentsDuringErrorReporting.ts (1 errors) ==== + interface ObjA { + y?:string, + } + + interface ObjB {[key:string]:any} + + interface Opts {a:A, b:B} + + const fn = < + A extends ObjA, + B extends ObjB = ObjB + >(opts:Opts):string => 'Z' + + interface MyObjA { + x:string, + } + + fn({ + ~~~~~~ +!!! error TS2559: Type 'MyObjA' has no properties in common with type 'ObjA'. + a: {x: 'X', y: 'Y'}, + b: {}, + }) + \ No newline at end of file diff --git a/tests/baselines/reference/incorrectNumberOfTypeArgumentsDuringErrorReporting.js b/tests/baselines/reference/incorrectNumberOfTypeArgumentsDuringErrorReporting.js new file mode 100644 index 00000000000..d74360e8edc --- /dev/null +++ b/tests/baselines/reference/incorrectNumberOfTypeArgumentsDuringErrorReporting.js @@ -0,0 +1,30 @@ +//// [incorrectNumberOfTypeArgumentsDuringErrorReporting.ts] +interface ObjA { + y?:string, +} + +interface ObjB {[key:string]:any} + +interface Opts {a:A, b:B} + +const fn = < + A extends ObjA, + B extends ObjB = ObjB +>(opts:Opts):string => 'Z' + +interface MyObjA { + x:string, +} + +fn({ + a: {x: 'X', y: 'Y'}, + b: {}, +}) + + +//// [incorrectNumberOfTypeArgumentsDuringErrorReporting.js] +var fn = function (opts) { return 'Z'; }; +fn({ + a: { x: 'X', y: 'Y' }, + b: {} +}); diff --git a/tests/baselines/reference/incorrectNumberOfTypeArgumentsDuringErrorReporting.symbols b/tests/baselines/reference/incorrectNumberOfTypeArgumentsDuringErrorReporting.symbols new file mode 100644 index 00000000000..5f94ad312c0 --- /dev/null +++ b/tests/baselines/reference/incorrectNumberOfTypeArgumentsDuringErrorReporting.symbols @@ -0,0 +1,60 @@ +=== tests/cases/compiler/incorrectNumberOfTypeArgumentsDuringErrorReporting.ts === +interface ObjA { +>ObjA : Symbol(ObjA, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 0, 0)) + + y?:string, +>y : Symbol(ObjA.y, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 0, 16)) +} + +interface ObjB {[key:string]:any} +>ObjB : Symbol(ObjB, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 2, 1)) +>key : Symbol(key, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 4, 17)) + +interface Opts {a:A, b:B} +>Opts : Symbol(Opts, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 4, 33)) +>A : Symbol(A, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 6, 15)) +>B : Symbol(B, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 6, 17)) +>a : Symbol(Opts.a, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 6, 22)) +>A : Symbol(A, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 6, 15)) +>b : Symbol(Opts.b, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 6, 26)) +>B : Symbol(B, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 6, 17)) + +const fn = < +>fn : Symbol(fn, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 8, 5)) + + A extends ObjA, +>A : Symbol(A, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 8, 12)) +>ObjA : Symbol(ObjA, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 0, 0)) + + B extends ObjB = ObjB +>B : Symbol(B, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 9, 17)) +>ObjB : Symbol(ObjB, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 2, 1)) +>ObjB : Symbol(ObjB, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 2, 1)) + +>(opts:Opts):string => 'Z' +>opts : Symbol(opts, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 11, 2)) +>Opts : Symbol(Opts, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 4, 33)) +>A : Symbol(A, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 8, 12)) +>B : Symbol(B, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 9, 17)) + +interface MyObjA { +>MyObjA : Symbol(MyObjA, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 11, 32)) + + x:string, +>x : Symbol(MyObjA.x, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 13, 18)) +} + +fn({ +>fn : Symbol(fn, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 8, 5)) +>MyObjA : Symbol(MyObjA, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 11, 32)) + + a: {x: 'X', y: 'Y'}, +>a : Symbol(a, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 17, 12)) +>x : Symbol(x, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 18, 6)) +>y : Symbol(y, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 18, 13)) + + b: {}, +>b : Symbol(b, Decl(incorrectNumberOfTypeArgumentsDuringErrorReporting.ts, 18, 22)) + +}) + diff --git a/tests/baselines/reference/incorrectNumberOfTypeArgumentsDuringErrorReporting.types b/tests/baselines/reference/incorrectNumberOfTypeArgumentsDuringErrorReporting.types new file mode 100644 index 00000000000..681a05eba09 --- /dev/null +++ b/tests/baselines/reference/incorrectNumberOfTypeArgumentsDuringErrorReporting.types @@ -0,0 +1,68 @@ +=== tests/cases/compiler/incorrectNumberOfTypeArgumentsDuringErrorReporting.ts === +interface ObjA { +>ObjA : ObjA + + y?:string, +>y : string +} + +interface ObjB {[key:string]:any} +>ObjB : ObjB +>key : string + +interface Opts {a:A, b:B} +>Opts : Opts +>A : A +>B : B +>a : A +>A : A +>b : B +>B : B + +const fn = < +>fn : (opts: Opts) => string +>< A extends ObjA, B extends ObjB = ObjB>(opts:Opts):string => 'Z' : (opts: Opts) => string + + A extends ObjA, +>A : A +>ObjA : ObjA + + B extends ObjB = ObjB +>B : B +>ObjB : ObjB +>ObjB : ObjB + +>(opts:Opts):string => 'Z' +>opts : Opts +>Opts : Opts +>A : A +>B : B +>'Z' : "Z" + +interface MyObjA { +>MyObjA : MyObjA + + x:string, +>x : string +} + +fn({ +>fn({ a: {x: 'X', y: 'Y'}, b: {},}) : any +>fn : (opts: Opts) => string +>MyObjA : MyObjA +>{ a: {x: 'X', y: 'Y'}, b: {},} : { a: { x: string; y: string; }; b: {}; } + + a: {x: 'X', y: 'Y'}, +>a : { x: string; y: string; } +>{x: 'X', y: 'Y'} : { x: string; y: string; } +>x : string +>'X' : "X" +>y : string +>'Y' : "Y" + + b: {}, +>b : {} +>{} : {} + +}) + diff --git a/tests/cases/compiler/incorrectNumberOfTypeArgumentsDuringErrorReporting.ts b/tests/cases/compiler/incorrectNumberOfTypeArgumentsDuringErrorReporting.ts new file mode 100644 index 00000000000..2f6c8c71250 --- /dev/null +++ b/tests/cases/compiler/incorrectNumberOfTypeArgumentsDuringErrorReporting.ts @@ -0,0 +1,21 @@ +interface ObjA { + y?:string, +} + +interface ObjB {[key:string]:any} + +interface Opts {a:A, b:B} + +const fn = < + A extends ObjA, + B extends ObjB = ObjB +>(opts:Opts):string => 'Z' + +interface MyObjA { + x:string, +} + +fn({ + a: {x: 'X', y: 'Y'}, + b: {}, +}) From 917ae32937053026f2c5421a4c2fa6256d31c10f Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 11 Oct 2017 14:50:45 -0700 Subject: [PATCH 099/312] Always log output of execSync (#19110) * Always log output of execSync * Fix lint --- .../typingsInstaller/nodeTypingsInstaller.ts | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/src/server/typingsInstaller/nodeTypingsInstaller.ts b/src/server/typingsInstaller/nodeTypingsInstaller.ts index f5d9b866376..98478c2d5fc 100644 --- a/src/server/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/server/typingsInstaller/nodeTypingsInstaller.ts @@ -68,10 +68,14 @@ namespace ts.server.typingsInstaller { return combinePaths(normalizeSlashes(globalTypingsCacheLocation), `node_modules/${TypesRegistryPackageName}/index.json`); } - type ExecSync = (command: string, options: { cwd: string, stdio?: "ignore" }) => any; + interface ExecSyncOptions { + cwd: string; + encoding: "utf-8"; + } + type ExecSync = (command: string, options: ExecSyncOptions) => string; export class NodeTypingsInstaller extends TypingsInstaller { - private readonly execSync: ExecSync; + private readonly nodeExecSync: ExecSync; private readonly npmPath: string; readonly typesRegistry: Map; @@ -95,7 +99,7 @@ namespace ts.server.typingsInstaller { this.log.writeLine(`Process id: ${process.pid}`); this.log.writeLine(`NPM location: ${this.npmPath} (explicit '${Arguments.NpmLocation}' ${npmLocation === undefined ? "not " : ""} provided)`); } - ({ execSync: this.execSync } = require("child_process")); + ({ execSync: this.nodeExecSync } = require("child_process")); this.ensurePackageDirectoryExists(globalTypingsCacheLocation); @@ -103,7 +107,7 @@ namespace ts.server.typingsInstaller { if (this.log.isEnabled()) { this.log.writeLine(`Updating ${TypesRegistryPackageName} npm package...`); } - this.execSync(`${this.npmPath} install --ignore-scripts ${TypesRegistryPackageName}`, { cwd: globalTypingsCacheLocation, stdio: "ignore" }); + this.execSyncAndLog(`${this.npmPath} install --ignore-scripts ${TypesRegistryPackageName}`, { cwd: globalTypingsCacheLocation }); if (this.log.isEnabled()) { this.log.writeLine(`Updated ${TypesRegistryPackageName} npm package`); } @@ -155,22 +159,31 @@ namespace ts.server.typingsInstaller { } const command = `${this.npmPath} install --ignore-scripts ${args.join(" ")} --save-dev --user-agent="typesInstaller/${version}"`; const start = Date.now(); - let stdout: Buffer; - let stderr: Buffer; - let hasError = false; - try { - stdout = this.execSync(command, { cwd }); - } - catch (e) { - stdout = e.stdout; - stderr = e.stderr; - hasError = true; - } + const hasError = this.execSyncAndLog(command, { cwd }); if (this.log.isEnabled()) { - this.log.writeLine(`npm install #${requestId} took: ${Date.now() - start} ms${sys.newLine}stdout: ${stdout && stdout.toString()}${sys.newLine}stderr: ${stderr && stderr.toString()}`); + this.log.writeLine(`npm install #${requestId} took: ${Date.now() - start} ms`); } onRequestCompleted(!hasError); } + + /** Returns 'true' in case of error. */ + private execSyncAndLog(command: string, options: Pick): boolean { + if (this.log.isEnabled()) { + this.log.writeLine(`Exec: ${command}`); + } + try { + const stdout = this.nodeExecSync(command, { ...options, encoding: "utf-8" }); + if (this.log.isEnabled()) { + this.log.writeLine(` Succeeded. stdout:${indent(sys.newLine, stdout)}`); + } + return false; + } + catch (error) { + const { stdout, stderr } = error; + this.log.writeLine(` Failed. stdout:${indent(sys.newLine, stdout)}${sys.newLine} stderr:${indent(sys.newLine, stderr)}`); + return true; + } + } } const logFilePath = findArgument(server.Arguments.LogFile); @@ -193,4 +206,8 @@ namespace ts.server.typingsInstaller { }); const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, /*throttleLimit*/5, log); installer.listen(); + + function indent(newline: string, string: string): string { + return `${newline} ` + string.replace(/\r?\n/, `${newline} `); + } } From 9f4130b204024f33cdc6c8ecafebb70edd7fb4ac Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 11 Oct 2017 14:52:23 -0700 Subject: [PATCH 100/312] Fix incorrect cast target (#19093) Found while updating #18285 to latest master. Not sure what this fixes, but it was definitely incorrect - `node` must be a `Block` at this point, so this cast must have been intended for `node.parent`, which was checked against `TryStatement` right before it. --- src/services/refactors/extractSymbol.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 124a1f720bd..ba5a6d9d1b5 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -375,7 +375,7 @@ namespace ts.refactor.extractSymbol { permittedJumps = PermittedJumps.None; break; case SyntaxKind.Block: - if (node.parent && node.parent.kind === SyntaxKind.TryStatement && (node).finallyBlock === node) { + if (node.parent && node.parent.kind === SyntaxKind.TryStatement && (node.parent).finallyBlock === node) { // allow unconditional returns from finally blocks permittedJumps = PermittedJumps.Return; } From b94924533690661c9b5e6b2ef60b136e624adb83 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 11 Oct 2017 15:13:33 -0700 Subject: [PATCH 101/312] Add ValueModule as a valid object literal type, as they are immutable (#19090) * Add ValueModule as a valid object literal type, as they are immutable * Rename method based on usage --- src/compiler/checker.ts | 10 +++---- .../inferredIndexerOnNamespaceImport.js | 28 +++++++++++++++++++ .../inferredIndexerOnNamespaceImport.symbols | 23 +++++++++++++++ .../inferredIndexerOnNamespaceImport.types | 26 +++++++++++++++++ .../inferredIndexerOnNamespaceImport.ts | 12 ++++++++ 5 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/inferredIndexerOnNamespaceImport.js create mode 100644 tests/baselines/reference/inferredIndexerOnNamespaceImport.symbols create mode 100644 tests/baselines/reference/inferredIndexerOnNamespaceImport.types create mode 100644 tests/cases/compiler/inferredIndexerOnNamespaceImport.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 36ee2a00eb9..a756faae036 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6274,7 +6274,7 @@ namespace ts { } function getImplicitIndexTypeOfType(type: Type, kind: IndexKind): Type { - if (isObjectLiteralType(type)) { + if (isObjectTypeWithInferableIndex(type)) { const propTypes: Type[] = []; for (const prop of getPropertiesOfType(type)) { if (kind === IndexKind.String || isNumericLiteralName(prop.escapedName)) { @@ -9831,7 +9831,7 @@ namespace ts { // if T is related to U. return kind === IndexKind.String && isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, reportErrors); } - if (isObjectLiteralType(source)) { + if (isObjectTypeWithInferableIndex(source)) { let related = Ternary.True; if (kind === IndexKind.String) { const sourceNumberInfo = getIndexInfoOfType(source, IndexKind.Number); @@ -10344,11 +10344,11 @@ namespace ts { } /** - * Return true if type was inferred from an object literal or written as an object type literal + * Return true if type was inferred from an object literal, written as an object type literal, or is the shape of a module * with no call or construct signatures. */ - function isObjectLiteralType(type: Type) { - return type.symbol && (type.symbol.flags & (SymbolFlags.ObjectLiteral | SymbolFlags.TypeLiteral)) !== 0 && + function isObjectTypeWithInferableIndex(type: Type) { + return type.symbol && (type.symbol.flags & (SymbolFlags.ObjectLiteral | SymbolFlags.TypeLiteral | SymbolFlags.ValueModule)) !== 0 && getSignaturesOfType(type, SignatureKind.Call).length === 0 && getSignaturesOfType(type, SignatureKind.Construct).length === 0; } diff --git a/tests/baselines/reference/inferredIndexerOnNamespaceImport.js b/tests/baselines/reference/inferredIndexerOnNamespaceImport.js new file mode 100644 index 00000000000..10fbc0890b7 --- /dev/null +++ b/tests/baselines/reference/inferredIndexerOnNamespaceImport.js @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/inferredIndexerOnNamespaceImport.ts] //// + +//// [foo.ts] +export const x = 3; +export const y = 5; + +//// [bar.ts] +import * as foo from "./foo"; + +function f(map: { [k: string]: number }) { + // ... +} + +f(foo); + +//// [foo.js] +"use strict"; +exports.__esModule = true; +exports.x = 3; +exports.y = 5; +//// [bar.js] +"use strict"; +exports.__esModule = true; +var foo = require("./foo"); +function f(map) { + // ... +} +f(foo); diff --git a/tests/baselines/reference/inferredIndexerOnNamespaceImport.symbols b/tests/baselines/reference/inferredIndexerOnNamespaceImport.symbols new file mode 100644 index 00000000000..ea0337ee9c2 --- /dev/null +++ b/tests/baselines/reference/inferredIndexerOnNamespaceImport.symbols @@ -0,0 +1,23 @@ +=== tests/cases/compiler/foo.ts === +export const x = 3; +>x : Symbol(x, Decl(foo.ts, 0, 12)) + +export const y = 5; +>y : Symbol(y, Decl(foo.ts, 1, 12)) + +=== tests/cases/compiler/bar.ts === +import * as foo from "./foo"; +>foo : Symbol(foo, Decl(bar.ts, 0, 6)) + +function f(map: { [k: string]: number }) { +>f : Symbol(f, Decl(bar.ts, 0, 29)) +>map : Symbol(map, Decl(bar.ts, 2, 11)) +>k : Symbol(k, Decl(bar.ts, 2, 19)) + + // ... +} + +f(foo); +>f : Symbol(f, Decl(bar.ts, 0, 29)) +>foo : Symbol(foo, Decl(bar.ts, 0, 6)) + diff --git a/tests/baselines/reference/inferredIndexerOnNamespaceImport.types b/tests/baselines/reference/inferredIndexerOnNamespaceImport.types new file mode 100644 index 00000000000..4a88b2330a0 --- /dev/null +++ b/tests/baselines/reference/inferredIndexerOnNamespaceImport.types @@ -0,0 +1,26 @@ +=== tests/cases/compiler/foo.ts === +export const x = 3; +>x : 3 +>3 : 3 + +export const y = 5; +>y : 5 +>5 : 5 + +=== tests/cases/compiler/bar.ts === +import * as foo from "./foo"; +>foo : typeof foo + +function f(map: { [k: string]: number }) { +>f : (map: { [k: string]: number; }) => void +>map : { [k: string]: number; } +>k : string + + // ... +} + +f(foo); +>f(foo) : void +>f : (map: { [k: string]: number; }) => void +>foo : typeof foo + diff --git a/tests/cases/compiler/inferredIndexerOnNamespaceImport.ts b/tests/cases/compiler/inferredIndexerOnNamespaceImport.ts new file mode 100644 index 00000000000..dd231361d27 --- /dev/null +++ b/tests/cases/compiler/inferredIndexerOnNamespaceImport.ts @@ -0,0 +1,12 @@ +// @filename: foo.ts +export const x = 3; +export const y = 5; + +// @filename: bar.ts +import * as foo from "./foo"; + +function f(map: { [k: string]: number }) { + // ... +} + +f(foo); \ No newline at end of file From 4d7c112ef7f5cd18f5563fff8158cc9e6eef6a98 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 11 Oct 2017 14:21:09 -0700 Subject: [PATCH 102/312] Make sure project root paths of inferred projects are canonical when comparing --- .../unittests/tsserverProjectSystem.ts | 111 +++++++++++++++++- src/server/editorServices.ts | 15 +-- src/server/project.ts | 6 +- .../reference/api/tsserverlibrary.d.ts | 3 +- 4 files changed, 124 insertions(+), 11 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index f7d082128cd..b52a6968774 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -220,11 +220,11 @@ namespace ts.projectSystem { checkNumberOfProjects(this, count); } } - export function createProjectService(host: server.ServerHost, parameters: CreateProjectServiceParameters = {}) { + export function createProjectService(host: server.ServerHost, parameters: CreateProjectServiceParameters = {}, options?: Partial) { const cancellationToken = parameters.cancellationToken || server.nullCancellationToken; const logger = parameters.logger || nullLogger; const useSingleInferredProject = parameters.useSingleInferredProject !== undefined ? parameters.useSingleInferredProject : false; - return new TestProjectService(host, logger, cancellationToken, useSingleInferredProject, parameters.typingsInstaller, parameters.eventHandler); + return new TestProjectService(host, logger, cancellationToken, useSingleInferredProject, parameters.typingsInstaller, parameters.eventHandler, options); } export function checkNumberOfConfiguredProjects(projectService: server.ProjectService, expected: number) { @@ -3703,6 +3703,113 @@ namespace ts.projectSystem { assert.equal(projectService.inferredProjects[1].getCompilationSettings().target, ScriptTarget.ESNext); assert.equal(projectService.inferredProjects[2].getCompilationSettings().target, ScriptTarget.ES2015); }); + + function checkInferredProject(inferredProject: server.InferredProject, actualFiles: FileOrFolder[], target: ScriptTarget) { + checkProjectActualFiles(inferredProject, actualFiles.map(f => f.path)); + assert.equal(inferredProject.getCompilationSettings().target, target); + } + + function verifyProjectRootWithCaseSensitivity(useCaseSensitiveFileNames: boolean) { + const files: [FileOrFolder, FileOrFolder, FileOrFolder, FileOrFolder] = [ + { path: "/a/file1.ts", content: "let x = 1;" }, + { path: "/A/file2.ts", content: "let y = 2;" }, + { path: "/b/file2.ts", content: "let x = 3;" }, + { path: "/c/file3.ts", content: "let z = 4;" } + ]; + const host = createServerHost(files, { useCaseSensitiveFileNames }); + const projectService = createProjectService(host, { useSingleInferredProject: true, }, { useInferredProjectPerProjectRoot: true }); + projectService.setCompilerOptionsForInferredProjects({ + allowJs: true, + target: ScriptTarget.ESNext + }); + projectService.setCompilerOptionsForInferredProjects({ + allowJs: true, + target: ScriptTarget.ES2015 + }, "/a"); + + openClientFiles(["/a", "/a", "/b", undefined]); + verifyInferredProjectsState([ + [[files[3]], ScriptTarget.ESNext], + [[files[0], files[1]], ScriptTarget.ES2015], + [[files[2]], ScriptTarget.ESNext] + ]); + closeClientFiles(); + + openClientFiles(["/a", "/A", "/b", undefined]); + if (useCaseSensitiveFileNames) { + verifyInferredProjectsState([ + [[files[3]], ScriptTarget.ESNext], + [[files[0]], ScriptTarget.ES2015], + [[files[1]], ScriptTarget.ESNext], + [[files[2]], ScriptTarget.ESNext] + ]); + } + else { + verifyInferredProjectsState([ + [[files[3]], ScriptTarget.ESNext], + [[files[0], files[1]], ScriptTarget.ES2015], + [[files[2]], ScriptTarget.ESNext] + ]); + } + closeClientFiles(); + + projectService.setCompilerOptionsForInferredProjects({ + allowJs: true, + target: ScriptTarget.ES2017 + }, "/A"); + + openClientFiles(["/a", "/a", "/b", undefined]); + verifyInferredProjectsState([ + [[files[3]], ScriptTarget.ESNext], + [[files[0], files[1]], useCaseSensitiveFileNames ? ScriptTarget.ES2015 : ScriptTarget.ES2017], + [[files[2]], ScriptTarget.ESNext] + ]); + closeClientFiles(); + + openClientFiles(["/a", "/A", "/b", undefined]); + if (useCaseSensitiveFileNames) { + verifyInferredProjectsState([ + [[files[3]], ScriptTarget.ESNext], + [[files[0]], ScriptTarget.ES2015], + [[files[1]], ScriptTarget.ES2017], + [[files[2]], ScriptTarget.ESNext] + ]); + } + else { + verifyInferredProjectsState([ + [[files[3]], ScriptTarget.ESNext], + [[files[0], files[1]], ScriptTarget.ES2017], + [[files[2]], ScriptTarget.ESNext] + ]); + } + closeClientFiles(); + + function openClientFiles(projectRoots: [string | undefined, string | undefined, string | undefined, string | undefined]) { + files.forEach((file, index) => { + projectService.openClientFile(file.path, file.content, ScriptKind.JS, projectRoots[index]); + }); + } + + function closeClientFiles() { + files.forEach(file => projectService.closeClientFile(file.path)); + } + + function verifyInferredProjectsState(expected: [FileOrFolder[], ScriptTarget][]) { + checkNumberOfProjects(projectService, { inferredProjects: expected.length }); + projectService.inferredProjects.forEach((p, index) => { + const [actualFiles, target] = expected[index]; + checkInferredProject(p, actualFiles, target); + }); + } + } + + it("inferred projects per project root with case sensitive system", () => { + verifyProjectRootWithCaseSensitivity(/*useCaseSensitiveFileNames*/ true); + }); + + it("inferred projects per project root with case insensitive system", () => { + verifyProjectRootWithCaseSensitivity(/*useCaseSensitiveFileNames*/ false); + }); }); describe("No overwrite emit error", () => { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 379a5fbfe7e..98112b3f24e 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -590,9 +590,9 @@ namespace ts.server { // always set 'allowNonTsExtensions' for inferred projects since user cannot configure it from the outside // previously we did not expose a way for user to change these settings and this option was enabled by default compilerOptions.allowNonTsExtensions = true; - - if (projectRootPath) { - this.compilerOptionsForInferredProjectsPerProjectRoot.set(projectRootPath, compilerOptions); + const canonicalProjectRootPath = projectRootPath && this.toCanonicalFileName(projectRootPath); + if (canonicalProjectRootPath) { + this.compilerOptionsForInferredProjectsPerProjectRoot.set(canonicalProjectRootPath, compilerOptions); } else { this.compilerOptionsForInferredProjects = compilerOptions; @@ -608,9 +608,9 @@ namespace ts.server { // root path // - Inferred projects with a projectRootPath, if the new options apply to that // project root path. - if (projectRootPath ? - project.projectRootPath === projectRootPath : - !project.projectRootPath || !this.compilerOptionsForInferredProjectsPerProjectRoot.has(project.projectRootPath)) { + if (canonicalProjectRootPath ? + project.projectRootPath === canonicalProjectRootPath : + !project.projectRootPath || !this.compilerOptionsForInferredProjectsPerProjectRoot.has(project.projectRootPath)) { project.setCompilerOptions(compilerOptions); project.compileOnSaveEnabled = compilerOptions.compileOnSave; project.markAsDirty(); @@ -1596,9 +1596,10 @@ namespace ts.server { } if (projectRootPath) { + const canonicalProjectRootPath = this.toCanonicalFileName(projectRootPath); // if we have an explicit project root path, find (or create) the matching inferred project. for (const project of this.inferredProjects) { - if (project.projectRootPath === projectRootPath) { + if (project.projectRootPath === canonicalProjectRootPath) { return project; } } diff --git a/src/server/project.ts b/src/server/project.ts index 9c66f8b4a6c..bf060b66a27 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1047,12 +1047,15 @@ namespace ts.server { super.setCompilerOptions(newOptions); } + /** this is canonical project root path */ + readonly projectRootPath: string | undefined; + /*@internal*/ constructor( projectService: ProjectService, documentRegistry: DocumentRegistry, compilerOptions: CompilerOptions, - readonly projectRootPath: string | undefined, + projectRootPath: string | undefined, currentDirectory: string | undefined) { super(InferredProject.newName(), ProjectKind.Inferred, @@ -1064,6 +1067,7 @@ namespace ts.server { /*compileOnSaveEnabled*/ false, projectService.host, currentDirectory); + this.projectRootPath = projectRootPath && projectService.toCanonicalFileName(projectRootPath); } addRoot(info: ScriptInfo) { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index d862513c293..61320be7eb7 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7186,11 +7186,12 @@ declare namespace ts.server { * the file and its imports/references are put into an InferredProject. */ class InferredProject extends Project { - readonly projectRootPath: string | undefined; private static readonly newName; private _isJsInferredProject; toggleJsInferredProject(isJsInferredProject: boolean): void; setCompilerOptions(options?: CompilerOptions): void; + /** this is canonical project root path*/ + readonly projectRootPath: string | undefined; addRoot(info: ScriptInfo): void; removeRoot(info: ScriptInfo): void; isProjectWithSingleRoot(): boolean; From eb4f067ecbdd3b43b9df8ea9c4826b766f38f8b7 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 11 Oct 2017 13:53:52 -0700 Subject: [PATCH 103/312] Don't clobber the position of cloned nodes --- src/services/utilities.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 5affb8a8887..a8dea4ddd0e 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1349,15 +1349,16 @@ namespace ts { const visited = visitEachChild(node, getSynthesizedDeepClone, nullTransformationContext); if (visited === node) { // This only happens for leaf nodes - internal nodes always see their children change. - return getSynthesizedClone(node); + const clone = getSynthesizedClone(node); + clone.pos = node.pos; + clone.end = node.end; + return clone; } // PERF: As an optimization, rather than calling getSynthesizedClone, we'll update // the new node created by visitEachChild with the extra changes getSynthesizedClone // would have made. - visited.pos = -1; - visited.end = -1; visited.parent = undefined; return visited; From d00ab417c6a4e5e084c3bbeab9b31ccd9fbc5854 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 11 Oct 2017 15:58:54 -0700 Subject: [PATCH 104/312] checkTypeParameters now always calls fillMissingTypeArguments And refactor checkTypeParameters to be easier to use and to read. --- src/compiler/checker.ts | 61 +++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 56835e13dde..ff78ccaa135 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15643,34 +15643,35 @@ namespace ts { return getInferredTypes(context); } - function checkTypeArguments(signature: Signature, typeArgumentNodes: ReadonlyArray, typeArgumentTypes: Type[], reportErrors: boolean, headMessage?: DiagnosticMessage): boolean { + function checkTypeArguments(signature: Signature, typeArguments: ReadonlyArray, reportErrors: boolean, headMessage?: DiagnosticMessage): Type[] | false { + const isJavascript = isInJavaScriptFile(signature.declaration); const typeParameters = signature.typeParameters; - let typeArgumentsAreAssignable = true; + const typeArgumentTypes = fillMissingTypeArguments(map(typeArguments, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isJavascript); let mapper: TypeMapper; - for (let i = 0; i < typeArgumentNodes.length; i++) { - if (typeArgumentsAreAssignable /* so far */) { - const constraint = getConstraintOfTypeParameter(typeParameters[i]); - if (constraint) { - let errorInfo: DiagnosticMessageChain; - let typeArgumentHeadMessage = Diagnostics.Type_0_does_not_satisfy_the_constraint_1; - if (reportErrors && headMessage) { - errorInfo = chainDiagnosticMessages(errorInfo, typeArgumentHeadMessage); - typeArgumentHeadMessage = headMessage; - } - if (!mapper) { - mapper = createTypeMapper(typeParameters, typeArgumentTypes); - } - const typeArgument = typeArgumentTypes[i]; - typeArgumentsAreAssignable = checkTypeAssignableTo( - typeArgument, - getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument), - reportErrors ? typeArgumentNodes[i] : undefined, - typeArgumentHeadMessage, - errorInfo); + for (let i = 0; i < typeArguments.length; i++) { + const constraint = getConstraintOfTypeParameter(typeParameters[i]); + if (constraint) { + let errorInfo: DiagnosticMessageChain; + let typeArgumentHeadMessage = Diagnostics.Type_0_does_not_satisfy_the_constraint_1; + if (reportErrors && headMessage) { + errorInfo = chainDiagnosticMessages(errorInfo, typeArgumentHeadMessage); + typeArgumentHeadMessage = headMessage; + } + if (!mapper) { + mapper = createTypeMapper(typeParameters, typeArgumentTypes); + } + const typeArgument = typeArgumentTypes[i]; + if (!checkTypeAssignableTo( + typeArgument, + getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument), + reportErrors ? typeArguments[i] : undefined, + typeArgumentHeadMessage, + errorInfo)) { + return false; } } } - return typeArgumentsAreAssignable; + return typeArgumentTypes; } /** @@ -16203,10 +16204,7 @@ namespace ts { checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, /*reportErrors*/ true); } else if (candidateForTypeArgumentError) { - const isJavascript = isInJavaScriptFile(candidateForTypeArgumentError.declaration); - const typeArguments = (node).typeArguments; - const typeArgumentTypes = fillMissingTypeArguments(map(typeArguments, getTypeFromTypeNode), candidateForTypeArgumentError.typeParameters, getMinTypeArgumentCount(candidateForTypeArgumentError.typeParameters), isJavascript); - checkTypeArguments(candidateForTypeArgumentError, typeArguments, typeArgumentTypes, /*reportErrors*/ true, fallbackError); + checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression).typeArguments, /*reportErrors*/ true, fallbackError); } else if (typeArguments && every(signatures, sig => length(sig.typeParameters) !== typeArguments.length)) { let min = Number.POSITIVE_INFINITY; @@ -16305,10 +16303,12 @@ namespace ts { candidate = originalCandidate; if (candidate.typeParameters) { let typeArgumentTypes: Type[]; - const isJavascript = isInJavaScriptFile(candidate.declaration); if (typeArguments) { - typeArgumentTypes = fillMissingTypeArguments(map(typeArguments, getTypeFromTypeNode), candidate.typeParameters, getMinTypeArgumentCount(candidate.typeParameters), isJavascript); - if (!checkTypeArguments(candidate, typeArguments, typeArgumentTypes, /*reportErrors*/ false)) { + const typeArgumentResult = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false); + if (typeArgumentResult) { + typeArgumentTypes = typeArgumentResult; + } + else { candidateForTypeArgumentError = originalCandidate; break; } @@ -16316,6 +16316,7 @@ namespace ts { else { typeArgumentTypes = inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext); } + const isJavascript = isInJavaScriptFile(candidate.declaration); candidate = getSignatureInstantiation(candidate, typeArgumentTypes, isJavascript); } if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) { From 9ef417b846694bb609e6d2a36b90b87b4e58cc34 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 11 Oct 2017 16:02:58 -0700 Subject: [PATCH 105/312] Account for type queries in type literals --- src/compiler/checker.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ed131c8936c..9224b6afd7c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8290,20 +8290,25 @@ namespace ts { function isTypeParameterPossiblyReferenced(tp: TypeParameter, node: Node) { // If the type parameter doesn't have exactly one declaration, if there are invening statement blocks - // between the node and the type parameter declaration, or if the node contains actual references to the - // type parameter, we consider the type parameter possibly referenced. + // between the node and the type parameter declaration, if the node contains actual references to the + // type parameter, or if the node contains type queries, we consider the type parameter possibly referenced. if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) { const container = tp.symbol.declarations[0].parent; if (findAncestor(node, n => n.kind === SyntaxKind.Block ? "quit" : n === container)) { - return tp.isThisType ? forEachChild(node, checkThis) : forEachChild(node, checkIdentifier); + return forEachChild(node, containsReference); } } return true; - function checkThis(node: Node): boolean { - return node.kind === SyntaxKind.ThisType || forEachChild(node, checkThis); - } - function checkIdentifier(node: Node): boolean { - return node.kind === SyntaxKind.Identifier && isPartOfTypeNode(node) && getTypeFromTypeNode(node) === tp || forEachChild(node, checkIdentifier); + function containsReference(node: Node): boolean { + switch (node.kind) { + case SyntaxKind.ThisType: + return tp.isThisType; + case SyntaxKind.Identifier: + return !tp.isThisType && isPartOfTypeNode(node) && getTypeFromTypeNode(node) === tp; + case SyntaxKind.TypeQuery: + return true; + } + return forEachChild(node, containsReference); } } From 19f70f6d3dac5ec210e1184631f2bee055e0fb4b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 11 Oct 2017 16:03:15 -0700 Subject: [PATCH 106/312] Add additional test --- tests/cases/compiler/indirectTypeParameterReferences.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/cases/compiler/indirectTypeParameterReferences.ts b/tests/cases/compiler/indirectTypeParameterReferences.ts index 210a599354d..c8cb56ad5e7 100644 --- a/tests/cases/compiler/indirectTypeParameterReferences.ts +++ b/tests/cases/compiler/indirectTypeParameterReferences.ts @@ -22,3 +22,8 @@ combined(comb => { comb.b comb.a }) + +// Repro from #19091 + +declare function f(a: T): { a: typeof a }; +let n: number = f(2).a; From 7ee96293ca23b3e8b6b2d64762b9366b2df59b71 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 11 Oct 2017 16:03:23 -0700 Subject: [PATCH 107/312] Accept new baselines --- .../indirectTypeParameterReferences.js | 6 ++++++ .../indirectTypeParameterReferences.symbols | 16 ++++++++++++++++ .../indirectTypeParameterReferences.types | 18 ++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/tests/baselines/reference/indirectTypeParameterReferences.js b/tests/baselines/reference/indirectTypeParameterReferences.js index e6e807a4720..f947b8f7c1f 100644 --- a/tests/baselines/reference/indirectTypeParameterReferences.js +++ b/tests/baselines/reference/indirectTypeParameterReferences.js @@ -23,6 +23,11 @@ combined(comb => { comb.b comb.a }) + +// Repro from #19091 + +declare function f(a: T): { a: typeof a }; +let n: number = f(2).a; //// [indirectTypeParameterReferences.js] @@ -41,3 +46,4 @@ combined(function (comb) { comb.b; comb.a; }); +var n = f(2).a; diff --git a/tests/baselines/reference/indirectTypeParameterReferences.symbols b/tests/baselines/reference/indirectTypeParameterReferences.symbols index 0cb091a8622..cf0f3e7bbc9 100644 --- a/tests/baselines/reference/indirectTypeParameterReferences.symbols +++ b/tests/baselines/reference/indirectTypeParameterReferences.symbols @@ -73,3 +73,19 @@ combined(comb => { }) +// Repro from #19091 + +declare function f(a: T): { a: typeof a }; +>f : Symbol(f, Decl(indirectTypeParameterReferences.ts, 23, 2)) +>T : Symbol(T, Decl(indirectTypeParameterReferences.ts, 27, 19)) +>a : Symbol(a, Decl(indirectTypeParameterReferences.ts, 27, 22)) +>T : Symbol(T, Decl(indirectTypeParameterReferences.ts, 27, 19)) +>a : Symbol(a, Decl(indirectTypeParameterReferences.ts, 27, 30)) +>a : Symbol(a, Decl(indirectTypeParameterReferences.ts, 27, 22)) + +let n: number = f(2).a; +>n : Symbol(n, Decl(indirectTypeParameterReferences.ts, 28, 3)) +>f(2).a : Symbol(a, Decl(indirectTypeParameterReferences.ts, 27, 30)) +>f : Symbol(f, Decl(indirectTypeParameterReferences.ts, 23, 2)) +>a : Symbol(a, Decl(indirectTypeParameterReferences.ts, 27, 30)) + diff --git a/tests/baselines/reference/indirectTypeParameterReferences.types b/tests/baselines/reference/indirectTypeParameterReferences.types index 2a8ac9a8b08..e38f5dd2577 100644 --- a/tests/baselines/reference/indirectTypeParameterReferences.types +++ b/tests/baselines/reference/indirectTypeParameterReferences.types @@ -86,3 +86,21 @@ combined(comb => { }) +// Repro from #19091 + +declare function f(a: T): { a: typeof a }; +>f : (a: T) => { a: T; } +>T : T +>a : T +>T : T +>a : T +>a : T + +let n: number = f(2).a; +>n : number +>f(2).a : number +>f(2) : { a: number; } +>f : (a: T) => { a: T; } +>2 : 2 +>a : number + From 568c8a3298fa10f1192a5fd3721414d27b0221b5 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 4 Oct 2017 14:09:32 -0700 Subject: [PATCH 108/312] Allow extraction of variable decls used outside the extracted range If there are only declarations, use the new function as the initializer for a destructuring declaration. If there are declarations and writes, changes all of the `const` declarations to `let` and add `| undefined` onto any explicit types. Use destructuring assignment to accomplish both "initialization" and writes. I don't believe there is a case where there are both declarations and a return (since the declarations wouldn't be available after the return). UNDONE: this could probably be generalized to handle binding patterns but, for now, only identifiers are supported. Fixes #18242 Fixes #18855 --- src/harness/unittests/extractFunctions.ts | 136 ++++++++++ src/services/refactors/extractSymbol.ts | 251 ++++++++++++++---- .../extractFunction/extractFunction11.ts | 6 +- .../extractFunction/extractFunction12.ts | 2 +- .../extractFunction/extractFunction6.ts | 6 +- .../extractFunction/extractFunction7.ts | 6 +- ...nction_VariableDeclaration_Const_NoType.js | 14 + ...nction_VariableDeclaration_Const_NoType.ts | 14 + ...Function_VariableDeclaration_Const_Type.ts | 14 + ...ction_VariableDeclaration_ConsumedTwice.ts | 14 + ...ction_VariableDeclaration_DeclaredTwice.js | 16 ++ ...ction_VariableDeclaration_DeclaredTwice.ts | 16 ++ ...Function_VariableDeclaration_Let_NoType.js | 14 + ...Function_VariableDeclaration_Let_NoType.ts | 14 + ...ctFunction_VariableDeclaration_Let_Type.ts | 14 + ...tFunction_VariableDeclaration_Multiple1.ts | 14 + ...tFunction_VariableDeclaration_Multiple2.js | 16 ++ ...tFunction_VariableDeclaration_Multiple2.ts | 16 ++ ...tFunction_VariableDeclaration_Multiple3.ts | 16 ++ ...n_VariableDeclaration_ShorthandProperty.js | 27 ++ ...n_VariableDeclaration_ShorthandProperty.ts | 27 ++ ...extractFunction_VariableDeclaration_Var.js | 14 + ...extractFunction_VariableDeclaration_Var.ts | 14 + ...VariableDeclaration_Writes_Const_NoType.js | 34 +++ ...VariableDeclaration_Writes_Const_NoType.ts | 34 +++ ...n_VariableDeclaration_Writes_Const_Type.ts | 34 +++ ...n_VariableDeclaration_Writes_Let_NoType.js | 34 +++ ...n_VariableDeclaration_Writes_Let_NoType.ts | 34 +++ ...ion_VariableDeclaration_Writes_Let_Type.ts | 34 +++ ...ction_VariableDeclaration_Writes_Mixed1.js | 38 +++ ...ction_VariableDeclaration_Writes_Mixed1.ts | 38 +++ ...ction_VariableDeclaration_Writes_Mixed2.js | 38 +++ ...ction_VariableDeclaration_Writes_Mixed2.ts | 38 +++ ...ction_VariableDeclaration_Writes_Mixed3.ts | 38 +++ ...riableDeclaration_Writes_UnionUndefined.ts | 42 +++ ...Function_VariableDeclaration_Writes_Var.js | 34 +++ ...Function_VariableDeclaration_Writes_Var.ts | 34 +++ tests/cases/fourslash/extract-method14.ts | 2 +- 38 files changed, 1117 insertions(+), 70 deletions(-) create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Const_NoType.js create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Const_NoType.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Const_Type.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ConsumedTwice.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_DeclaredTwice.js create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_DeclaredTwice.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Let_NoType.js create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Let_NoType.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Let_Type.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Multiple1.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Multiple2.js create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Multiple2.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Multiple3.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ShorthandProperty.js create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ShorthandProperty.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Var.js create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Var.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_NoType.js create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_NoType.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_Type.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_NoType.js create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_NoType.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_Type.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed1.js create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed1.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed2.js create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed2.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed3.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_UnionUndefined.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Var.js create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Var.ts diff --git a/src/harness/unittests/extractFunctions.ts b/src/harness/unittests/extractFunctions.ts index 750e590ca4c..715a4f5aa0c 100644 --- a/src/harness/unittests/extractFunctions.ts +++ b/src/harness/unittests/extractFunctions.ts @@ -360,6 +360,142 @@ function parsePrimaryExpression(): any { export const j = 10; export const y = [#|j * j|]; }`); + + testExtractFunction("extractFunction_VariableDeclaration_Var", ` +[#|var x = 1;|] +x; +`); + + testExtractFunction("extractFunction_VariableDeclaration_Let_Type", ` +[#|let x: number = 1;|] +x; +`); + + testExtractFunction("extractFunction_VariableDeclaration_Let_NoType", ` +[#|let x = 1;|] +x; +`); + + testExtractFunction("extractFunction_VariableDeclaration_Const_Type", ` +[#|const x: number = 1;|] +x; +`); + + testExtractFunction("extractFunction_VariableDeclaration_Const_NoType", ` +[#|const x = 1;|] +x; +`); + + testExtractFunction("extractFunction_VariableDeclaration_Multiple1", ` +[#|const x = 1, y: string = "a";|] +x; y; +`); + + testExtractFunction("extractFunction_VariableDeclaration_Multiple2", ` +[#|const x = 1, y = "a"; +const z = 3;|] +x; y; z; +`); + + testExtractFunction("extractFunction_VariableDeclaration_Multiple3", ` +[#|const x = 1, y: string = "a"; +let z = 3;|] +x; y; z; +`); + + testExtractFunction("extractFunction_VariableDeclaration_ConsumedTwice", ` +[#|const x: number = 1;|] +x; x; +`); + + testExtractFunction("extractFunction_VariableDeclaration_DeclaredTwice", ` +[#|var x = 1; +var x = 2;|] +x; +`); + + testExtractFunction("extractFunction_VariableDeclaration_Writes_Var", ` +function f() { + let a = 1; + [#|var x = 1; + a++;|] + a; x; +}`); + + testExtractFunction("extractFunction_VariableDeclaration_Writes_Let_NoType", ` +function f() { + let a = 1; + [#|let x = 1; + a++;|] + a; x; +}`); + + testExtractFunction("extractFunction_VariableDeclaration_Writes_Let_Type", ` +function f() { + let a = 1; + [#|let x: number = 1; + a++;|] + a; x; +}`); + + testExtractFunction("extractFunction_VariableDeclaration_Writes_Const_NoType", ` +function f() { + let a = 1; + [#|const x = 1; + a++;|] + a; x; +}`); + + testExtractFunction("extractFunction_VariableDeclaration_Writes_Const_Type", ` +function f() { + let a = 1; + [#|const x: number = 1; + a++;|] + a; x; +}`); + + testExtractFunction("extractFunction_VariableDeclaration_Writes_Mixed1", ` +function f() { + let a = 1; + [#|const x = 1; + let y = 2; + a++;|] + a; x; y; +}`); + + testExtractFunction("extractFunction_VariableDeclaration_Writes_Mixed2", ` +function f() { + let a = 1; + [#|var x = 1; + let y = 2; + a++;|] + a; x; y; +}`); + + testExtractFunction("extractFunction_VariableDeclaration_Writes_Mixed3", ` +function f() { + let a = 1; + [#|let x: number = 1; + let y = 2; + a++;|] + a; x; y; +}`); + + testExtractFunction("extractFunction_VariableDeclaration_Writes_UnionUndefined", ` +function f() { + let a = 1; + [#|let x: number | undefined = 1; + let y: undefined | number = 2; + let z: (undefined | number) = 3; + a++;|] + a; x; y; z; +}`); + + testExtractFunction("extractFunction_VariableDeclaration_ShorthandProperty", ` +function f() { + [#|let x;|] + return { x }; +}`); }); function testExtractFunction(caption: string, text: string) { diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 9defe3dd1f0..a03bb843600 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -137,7 +137,7 @@ namespace ts.refactor.extractSymbol { export const FunctionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope."); export const CannotExtractIdentifier = createMessage("Select more than a single identifier."); export const CannotExtractExportedEntity = createMessage("Cannot extract exported declaration"); - export const CannotCombineWritesAndReturns = createMessage("Cannot combine writes and returns"); + export const CannotWriteInExpression = createMessage("Cannot write back side-effects when extracting an expression"); export const CannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor"); export const CannotExtractAmbientBlock = createMessage("Cannot extract code from ambient contexts"); export const CannotAccessVariablesFromNestedScopes = createMessage("Cannot access variables from nested scopes"); @@ -507,15 +507,16 @@ namespace ts.refactor.extractSymbol { } function getFunctionExtractionAtIndex(targetRange: TargetRange, context: RefactorContext, requestedChangesIndex: number): RefactorEditInfo { - const { scopes, readsAndWrites: { target, usagesPerScope, functionErrorsPerScope } } = getPossibleExtractionsWorker(targetRange, context); + const { scopes, readsAndWrites: { target, usagesPerScope, functionErrorsPerScope, exposedVariableDeclarations } } = getPossibleExtractionsWorker(targetRange, context); Debug.assert(!functionErrorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?"); context.cancellationToken.throwIfCancellationRequested(); - return extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange, context); + return extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], exposedVariableDeclarations, targetRange, context); } function getConstantExtractionAtIndex(targetRange: TargetRange, context: RefactorContext, requestedChangesIndex: number): RefactorEditInfo { - const { scopes, readsAndWrites: { target, usagesPerScope, constantErrorsPerScope } } = getPossibleExtractionsWorker(targetRange, context); + const { scopes, readsAndWrites: { target, usagesPerScope, constantErrorsPerScope, exposedVariableDeclarations } } = getPossibleExtractionsWorker(targetRange, context); Debug.assert(!constantErrorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?"); + Debug.assert(exposedVariableDeclarations.length === 0, "Extract constant accepted a range containing a variable declaration?"); context.cancellationToken.throwIfCancellationRequested(); const expression = isExpression(target) ? target @@ -674,6 +675,7 @@ namespace ts.refactor.extractSymbol { node: Statement | Expression | Block, scope: Scope, { usages: usagesInScope, typeParameterUsages, substitutions }: ScopeUsages, + exposedVariableDeclarations: ReadonlyArray, range: TargetRange, context: RefactorContext): RefactorEditInfo { @@ -731,10 +733,10 @@ namespace ts.refactor.extractSymbol { // to avoid problems when there are literal types present if (isExpression(node) && !isJS) { const contextualType = checker.getContextualType(node); - returnType = checker.typeToTypeNode(contextualType); + returnType = checker.typeToTypeNode(contextualType, scope, NodeBuilderFlags.NoTruncation); } - const { body, returnValueProperty } = transformFunctionBody(node, writes, substitutions, !!(range.facts & RangeFacts.HasReturn)); + const { body, returnValueProperty } = transformFunctionBody(node, exposedVariableDeclarations, writes, substitutions, !!(range.facts & RangeFacts.HasReturn)); let newFunction: MethodDeclaration | FunctionDeclaration; if (isClassLike(scope)) { @@ -796,38 +798,114 @@ namespace ts.refactor.extractSymbol { call = createAwait(call); } - if (writes) { + if (exposedVariableDeclarations.length && !writes) { + // No need to mix declarations and writes. + + // How could any variables be exposed if there's a return statement? + Debug.assert(!returnValueProperty); + Debug.assert(!(range.facts & RangeFacts.HasReturn)); + + if (exposedVariableDeclarations.length === 1) { + // Declaring exactly one variable: let x = newFunction(); + const variableDeclaration = exposedVariableDeclarations[0]; + newNodes.push(createVariableStatement( + /*modifiers*/ undefined, + createVariableDeclarationList( + [createVariableDeclaration(getSynthesizedDeepClone(variableDeclaration.name), /*type*/ getSynthesizedDeepClone(variableDeclaration.type), /*initializer*/ call)], // TODO (acasey): test binding patterns + variableDeclaration.parent.flags))); + } + else { + // Declaring multiple variables / return properties: + // let {x, y} = newFunction(); + const bindingElements: BindingElement[] = []; + const typeElements: TypeElement[] = []; + let commonNodeFlags = exposedVariableDeclarations[0].parent.flags; + let sawExplicitType = false; + for (const variableDeclaration of exposedVariableDeclarations) { + bindingElements.push(createBindingElement( + /*dotDotDotToken*/ undefined, + /*propertyName*/ undefined, + /*name*/ getSynthesizedDeepClone(variableDeclaration.name))); + + // Being returned through an object literal will have widened the type. + const variableType: TypeNode = checker.typeToTypeNode( + checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(variableDeclaration)), + scope, + NodeBuilderFlags.NoTruncation); + + typeElements.push(createPropertySignature( + /*modifiers*/ undefined, + /*name*/ variableDeclaration.symbol.name, + /*questionToken*/ undefined, + /*type*/ variableType, + /*initializer*/ undefined)); + sawExplicitType = sawExplicitType || variableDeclaration.type !== undefined; + commonNodeFlags = commonNodeFlags & variableDeclaration.parent.flags; + } + + const typeLiteral: TypeLiteralNode | undefined = sawExplicitType ? createTypeLiteralNode(typeElements) : undefined; + if (typeLiteral) { + setEmitFlags(typeLiteral, EmitFlags.SingleLine); + } + + newNodes.push(createVariableStatement( + /*modifiers*/ undefined, + createVariableDeclarationList( + [createVariableDeclaration( + createObjectBindingPattern(bindingElements), + /*type*/ typeLiteral, + /*initializer*/call)], + commonNodeFlags))); + } + } + else if (exposedVariableDeclarations.length || writes) { + if (exposedVariableDeclarations.length) { + // CONSIDER: we're going to create one statement per variable, but we could actually preserve their original grouping. + for (const variableDeclaration of exposedVariableDeclarations) { + let flags: NodeFlags = variableDeclaration.parent.flags; + if (flags & NodeFlags.Const) { + flags = (flags & ~NodeFlags.Const) | NodeFlags.Let; + } + + newNodes.push(createVariableStatement( + /*modifiers*/ undefined, + createVariableDeclarationList( + [createVariableDeclaration(variableDeclaration.symbol.name, getTypeDeepCloneUnionUndefined(variableDeclaration.type))], + flags))); + } + } + if (returnValueProperty) { // has both writes and return, need to create variable declaration to hold return value; newNodes.push(createVariableStatement( /*modifiers*/ undefined, - [createVariableDeclaration(returnValueProperty, createKeywordTypeNode(SyntaxKind.AnyKeyword))] - )); + createVariableDeclarationList( + [createVariableDeclaration(returnValueProperty, getTypeDeepCloneUnionUndefined(returnType))], + NodeFlags.Let))); } - const assignments = getPropertyAssignmentsForWrites(writes); + const assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes); if (returnValueProperty) { assignments.unshift(createShorthandPropertyAssignment(returnValueProperty)); } // propagate writes back if (assignments.length === 1) { - if (returnValueProperty) { - newNodes.push(createReturn(createIdentifier(returnValueProperty))); - } - else { - newNodes.push(createStatement(createBinary(assignments[0].name, SyntaxKind.EqualsToken, call))); + // We would only have introduced a return value property if there had been + // other assignments to make. + Debug.assert(!returnValueProperty); - if (range.facts & RangeFacts.HasReturn) { - newNodes.push(createReturn()); - } + newNodes.push(createStatement(createAssignment(assignments[0].name, call))); + + if (range.facts & RangeFacts.HasReturn) { + newNodes.push(createReturn()); } } else { // emit e.g. // { a, b, __return } = newFunction(a, b); // return __return; - newNodes.push(createStatement(createBinary(createObjectLiteral(assignments), SyntaxKind.EqualsToken, call))); + newNodes.push(createStatement(createAssignment(createObjectLiteral(assignments), call))); if (returnValueProperty) { newNodes.push(createReturn(createIdentifier(returnValueProperty))); } @@ -861,6 +939,21 @@ namespace ts.refactor.extractSymbol { const renameFilename = renameRange.getSourceFile().fileName; const renameLocation = getRenameLocation(edits, renameFilename, functionNameText, /*isDeclaredBeforeUse*/ false); return { renameFilename, renameLocation, edits }; + + function getTypeDeepCloneUnionUndefined(typeNode: TypeNode | undefined): TypeNode | undefined { + if (typeNode === undefined) { + return undefined; + } + + const clone = getSynthesizedDeepClone(typeNode); + let withoutParens = clone; + while (isParenthesizedTypeNode(withoutParens)) { + withoutParens = withoutParens.type; + } + return isUnionTypeNode(withoutParens) && find(withoutParens.types, t => t.kind === SyntaxKind.UndefinedKeyword) + ? clone + : createUnionTypeNode([clone, createKeywordTypeNode(SyntaxKind.UndefinedKeyword)]); + } } /** @@ -883,7 +976,7 @@ namespace ts.refactor.extractSymbol { const variableType = isJS ? undefined - : checker.typeToTypeNode(checker.getContextualType(node)); + : checker.typeToTypeNode(checker.getContextualType(node), scope, NodeBuilderFlags.NoTruncation); const initializer = transformConstantInitializer(node, substitutions); @@ -1088,21 +1181,22 @@ namespace ts.refactor.extractSymbol { } } - function transformFunctionBody(body: Node, writes: ReadonlyArray, substitutions: ReadonlyMap, hasReturn: boolean): { body: Block, returnValueProperty: string } { - if (isBlock(body) && !writes && substitutions.size === 0) { - // already block, no writes to propagate back, no substitutions - can use node as is + function transformFunctionBody(body: Node, exposedVariableDeclarations: ReadonlyArray, writes: ReadonlyArray, substitutions: ReadonlyMap, hasReturn: boolean): { body: Block, returnValueProperty: string } { + const hasWritesOrVariableDeclarations = writes !== undefined || exposedVariableDeclarations.length > 0; + if (isBlock(body) && !hasWritesOrVariableDeclarations && substitutions.size === 0) { + // already block, no declarations or writes to propagate back, no substitutions - can use node as is return { body: createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined }; } let returnValueProperty: string; let ignoreReturns = false; const statements = createNodeArray(isBlock(body) ? body.statements.slice(0) : [isStatement(body) ? body : createReturn(body)]); // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions - if (writes || substitutions.size) { + if (hasWritesOrVariableDeclarations || substitutions.size) { const rewrittenStatements = visitNodes(statements, visitor).slice(); - if (writes && !hasReturn && isStatement(body)) { + if (hasWritesOrVariableDeclarations && !hasReturn && isStatement(body)) { // add return at the end to propagate writes back in case if control flow falls out of the function body // it is ok to know that range has at least one return since it we only allow unconditional returns - const assignments = getPropertyAssignmentsForWrites(writes); + const assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes); if (assignments.length === 1) { rewrittenStatements.push(createReturn(assignments[0].name)); } @@ -1117,8 +1211,8 @@ namespace ts.refactor.extractSymbol { } function visitor(node: Node): VisitResult { - if (!ignoreReturns && node.kind === SyntaxKind.ReturnStatement && writes) { - const assignments: ObjectLiteralElementLike[] = getPropertyAssignmentsForWrites(writes); + if (!ignoreReturns && node.kind === SyntaxKind.ReturnStatement && hasWritesOrVariableDeclarations) { + const assignments: ObjectLiteralElementLike[] = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes); if ((node).expression) { if (!returnValueProperty) { returnValueProperty = "__return"; @@ -1240,8 +1334,18 @@ namespace ts.refactor.extractSymbol { } } - function getPropertyAssignmentsForWrites(writes: ReadonlyArray): ShorthandPropertyAssignment[] { - return writes.map(w => createShorthandPropertyAssignment(w.symbol.name)); + function getPropertyAssignmentsForWritesAndVariableDeclarations( + exposedVariableDeclarations: ReadonlyArray, + writes: ReadonlyArray) { + + const variableAssignments = map(exposedVariableDeclarations, v => createShorthandPropertyAssignment(v.symbol.name)); + const writeAssignments = map(writes, w => createShorthandPropertyAssignment(w.symbol.name)); + + return variableAssignments === undefined + ? writeAssignments + : writeAssignments === undefined + ? variableAssignments + : variableAssignments.concat(writeAssignments); } function isReadonlyArray(v: any): v is ReadonlyArray { @@ -1287,6 +1391,7 @@ namespace ts.refactor.extractSymbol { readonly usagesPerScope: ReadonlyArray; readonly functionErrorsPerScope: ReadonlyArray>; readonly constantErrorsPerScope: ReadonlyArray>; + readonly exposedVariableDeclarations: ReadonlyArray; } function collectReadsAndWrites( targetRange: TargetRange, @@ -1301,7 +1406,10 @@ namespace ts.refactor.extractSymbol { const substitutionsPerScope: Map[] = []; const functionErrorsPerScope: Diagnostic[][] = []; const constantErrorsPerScope: Diagnostic[][] = []; - const visibleDeclarationsInExtractedRange: Symbol[] = []; + const visibleDeclarationsInExtractedRange: NamedDeclaration[] = []; + const exposedVariableSymbolSet = createMap(); // Key is symbol ID + const exposedVariableDeclarations: VariableDeclaration[] = []; + let firstExposedNonVariableDeclaration: NamedDeclaration | undefined = undefined; const expression = !isReadonlyArray(targetRange.range) ? targetRange.range @@ -1346,7 +1454,6 @@ namespace ts.refactor.extractSymbol { const seenUsages = createMap(); const target = isReadonlyArray(targetRange.range) ? createBlock(targetRange.range) : targetRange.range; - const containingLexicalScopeOfExtraction = isBlockScope(scopes[0], scopes[0].parent) ? scopes[0] : getEnclosingBlockScopeContainer(scopes[0]); const unmodifiedNode = isReadonlyArray(targetRange.range) ? first(targetRange.range) : targetRange.range; const inGenericContext = isInGenericContext(unmodifiedNode); @@ -1392,6 +1499,15 @@ namespace ts.refactor.extractSymbol { Debug.assert(i === scopes.length); } + // If there are any declarations in the extracted block that are used in the same enclosing + // lexical scope, we can't move the extraction "up" as those declarations will become unreachable + if (visibleDeclarationsInExtractedRange.length) { + const containingLexicalScopeOfExtraction = isBlockScope(scopes[0], scopes[0].parent) + ? scopes[0] + : getEnclosingBlockScopeContainer(scopes[0]); + forEachChild(containingLexicalScopeOfExtraction, checkForUsedDeclarations); + } + for (let i = 0; i < scopes.length; i++) { const scopeUsages = usagesPerScope[i]; // Special case: in the innermost scope, all usages are available. @@ -1415,8 +1531,11 @@ namespace ts.refactor.extractSymbol { } }); - if (hasWrite && !isReadonlyArray(targetRange.range) && isExpression(targetRange.range)) { - const diag = createDiagnosticForNode(targetRange.range, Messages.CannotCombineWritesAndReturns); + // If an expression was extracted, then there shouldn't have been any variable declarations. + Debug.assert(isReadonlyArray(targetRange.range) || exposedVariableDeclarations.length === 0); + + if (hasWrite && !isReadonlyArray(targetRange.range)) { + const diag = createDiagnosticForNode(targetRange.range, Messages.CannotWriteInExpression); functionErrorsPerScope[i].push(diag); constantErrorsPerScope[i].push(diag); } @@ -1425,15 +1544,14 @@ namespace ts.refactor.extractSymbol { functionErrorsPerScope[i].push(diag); constantErrorsPerScope[i].push(diag); } + else if (firstExposedNonVariableDeclaration) { + const diag = createDiagnosticForNode(firstExposedNonVariableDeclaration, Messages.CannotExtractExportedEntity); + functionErrorsPerScope[i].push(diag); + constantErrorsPerScope[i].push(diag); + } } - // If there are any declarations in the extracted block that are used in the same enclosing - // lexical scope, we can't move the extraction "up" as those declarations will become unreachable - if (visibleDeclarationsInExtractedRange.length) { - forEachChild(containingLexicalScopeOfExtraction, checkForUsedDeclarations); - } - - return { target, usagesPerScope, functionErrorsPerScope, constantErrorsPerScope }; + return { target, usagesPerScope, functionErrorsPerScope, constantErrorsPerScope, exposedVariableDeclarations }; function hasTypeParameters(node: Node) { return isDeclarationWithTypeParameters(node) && @@ -1472,7 +1590,7 @@ namespace ts.refactor.extractSymbol { } if (isDeclaration(node) && node.symbol) { - visibleDeclarationsInExtractedRange.push(node.symbol); + visibleDeclarationsInExtractedRange.push(node); } if (isAssignmentExpression(node)) { @@ -1518,11 +1636,7 @@ namespace ts.refactor.extractSymbol { } function recordUsagebySymbol(identifier: Identifier, usage: Usage, isTypeName: boolean) { - // If the identifier is both a property name and its value, we're only interested in its value - // (since the name is a declaration and will be included in the extracted range). - const symbol = identifier.parent && isShorthandPropertyAssignment(identifier.parent) && identifier.parent.name === identifier - ? checker.getShorthandAssignmentValueSymbol(identifier.parent) - : checker.getSymbolAtLocation(identifier); + const symbol = getSymbolReferencedByIdentifier(identifier); if (!symbol) { // cannot find symbol - do nothing return undefined; @@ -1606,20 +1720,39 @@ namespace ts.refactor.extractSymbol { } // Otherwise check and recurse. - const sym = checker.getSymbolAtLocation(node); - if (sym && visibleDeclarationsInExtractedRange.some(d => d === sym)) { - const diag = createDiagnosticForNode(node, Messages.CannotExtractExportedEntity); - for (const errors of functionErrorsPerScope) { - errors.push(diag); + const sym = isIdentifier(node) + ? getSymbolReferencedByIdentifier(node) + : checker.getSymbolAtLocation(node); + if (sym) { + const decl = find(visibleDeclarationsInExtractedRange, d => d.symbol === sym); + if (decl) { + if (isVariableDeclaration(decl)) { + const idString = decl.symbol.id.toString(); + if (!exposedVariableSymbolSet.has(idString)) { + exposedVariableDeclarations.push(decl); + exposedVariableSymbolSet.set(idString, true); + } + } + else { + // CONSIDER: this includes binding elements, which we could + // expose in the same way as variables. + firstExposedNonVariableDeclaration = firstExposedNonVariableDeclaration || decl; + } } - for (const errors of constantErrorsPerScope) { - errors.push(diag); - } - return true; - } - else { - forEachChild(node, checkForUsedDeclarations); } + + forEachChild(node, checkForUsedDeclarations); + } + + /** + * Return the symbol referenced by an identifier (even if it declares a different symbol). + */ + function getSymbolReferencedByIdentifier(identifier: Identifier) { + // If the identifier is both a property name and its value, we're only interested in its value + // (since the name is a declaration and will be included in the extracted range). + return identifier.parent && isShorthandPropertyAssignment(identifier.parent) && identifier.parent.name === identifier + ? checker.getShorthandAssignmentValueSymbol(identifier.parent) + : checker.getSymbolAtLocation(identifier); } function tryReplaceWithQualifiedNameOrPropertyAccess(symbol: Symbol, scopeDecl: Node, isTypeNode: boolean): PropertyAccessExpression | EntityName { diff --git a/tests/baselines/reference/extractFunction/extractFunction11.ts b/tests/baselines/reference/extractFunction/extractFunction11.ts index d07a1826439..4bb88123a2f 100644 --- a/tests/baselines/reference/extractFunction/extractFunction11.ts +++ b/tests/baselines/reference/extractFunction/extractFunction11.ts @@ -17,7 +17,7 @@ namespace A { class C { a() { let z = 1; - var __return: any; + let __return; ({ __return, z } = this./*RENAME*/newMethod(z)); return __return; } @@ -36,7 +36,7 @@ namespace A { class C { a() { let z = 1; - var __return: any; + let __return; ({ __return, z } = /*RENAME*/newFunction(z)); return __return; } @@ -55,7 +55,7 @@ namespace A { class C { a() { let z = 1; - var __return: any; + let __return; ({ __return, y, z } = /*RENAME*/newFunction(y, z)); return __return; } diff --git a/tests/baselines/reference/extractFunction/extractFunction12.ts b/tests/baselines/reference/extractFunction/extractFunction12.ts index 37274bdcc87..49e87151b9b 100644 --- a/tests/baselines/reference/extractFunction/extractFunction12.ts +++ b/tests/baselines/reference/extractFunction/extractFunction12.ts @@ -20,7 +20,7 @@ namespace A { b() {} a() { let z = 1; - var __return: any; + let __return; ({ __return, z } = this./*RENAME*/newMethod(z)); return __return; } diff --git a/tests/baselines/reference/extractFunction/extractFunction6.ts b/tests/baselines/reference/extractFunction/extractFunction6.ts index f6c94216b46..a01cb25e061 100644 --- a/tests/baselines/reference/extractFunction/extractFunction6.ts +++ b/tests/baselines/reference/extractFunction/extractFunction6.ts @@ -43,7 +43,7 @@ namespace A { function a() { let a = 1; - var __return: any; + let __return; ({ __return, a } = /*RENAME*/newFunction(a)); return __return; } @@ -65,7 +65,7 @@ namespace A { function a() { let a = 1; - var __return: any; + let __return; ({ __return, a } = /*RENAME*/newFunction(a)); return __return; } @@ -87,7 +87,7 @@ namespace A { function a() { let a = 1; - var __return: any; + let __return; ({ __return, a } = /*RENAME*/newFunction(x, a)); return __return; } diff --git a/tests/baselines/reference/extractFunction/extractFunction7.ts b/tests/baselines/reference/extractFunction/extractFunction7.ts index 91377868e0f..4111558904c 100644 --- a/tests/baselines/reference/extractFunction/extractFunction7.ts +++ b/tests/baselines/reference/extractFunction/extractFunction7.ts @@ -49,7 +49,7 @@ namespace A { function a() { let a = 1; - var __return: any; + let __return; ({ __return, a } = /*RENAME*/newFunction(a)); return __return; } @@ -73,7 +73,7 @@ namespace A { function a() { let a = 1; - var __return: any; + let __return; ({ __return, a } = /*RENAME*/newFunction(a)); return __return; } @@ -97,7 +97,7 @@ namespace A { function a() { let a = 1; - var __return: any; + let __return; ({ __return, a } = /*RENAME*/newFunction(x, a)); return __return; } diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Const_NoType.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Const_NoType.js new file mode 100644 index 00000000000..fff1488ef41 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Const_NoType.js @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +/*[#|*/const x = 1;/*|]*/ +x; + +// ==SCOPE::Extract to function in global scope== + +const x = /*RENAME*/newFunction(); +x; + +function newFunction() { + const x = 1; + return x; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Const_NoType.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Const_NoType.ts new file mode 100644 index 00000000000..fff1488ef41 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Const_NoType.ts @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +/*[#|*/const x = 1;/*|]*/ +x; + +// ==SCOPE::Extract to function in global scope== + +const x = /*RENAME*/newFunction(); +x; + +function newFunction() { + const x = 1; + return x; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Const_Type.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Const_Type.ts new file mode 100644 index 00000000000..94576953758 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Const_Type.ts @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +/*[#|*/const x: number = 1;/*|]*/ +x; + +// ==SCOPE::Extract to function in global scope== + +const x: number = /*RENAME*/newFunction(); +x; + +function newFunction() { + const x: number = 1; + return x; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ConsumedTwice.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ConsumedTwice.ts new file mode 100644 index 00000000000..ac57711614c --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ConsumedTwice.ts @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +/*[#|*/const x: number = 1;/*|]*/ +x; x; + +// ==SCOPE::Extract to function in global scope== + +const x: number = /*RENAME*/newFunction(); +x; x; + +function newFunction() { + const x: number = 1; + return x; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_DeclaredTwice.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_DeclaredTwice.js new file mode 100644 index 00000000000..e6f314acd9c --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_DeclaredTwice.js @@ -0,0 +1,16 @@ +// ==ORIGINAL== + +/*[#|*/var x = 1; +var x = 2;/*|]*/ +x; + +// ==SCOPE::Extract to function in global scope== + +var x = /*RENAME*/newFunction(); +x; + +function newFunction() { + var x = 1; + var x = 2; + return x; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_DeclaredTwice.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_DeclaredTwice.ts new file mode 100644 index 00000000000..e6f314acd9c --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_DeclaredTwice.ts @@ -0,0 +1,16 @@ +// ==ORIGINAL== + +/*[#|*/var x = 1; +var x = 2;/*|]*/ +x; + +// ==SCOPE::Extract to function in global scope== + +var x = /*RENAME*/newFunction(); +x; + +function newFunction() { + var x = 1; + var x = 2; + return x; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Let_NoType.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Let_NoType.js new file mode 100644 index 00000000000..4f407ce5703 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Let_NoType.js @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +/*[#|*/let x = 1;/*|]*/ +x; + +// ==SCOPE::Extract to function in global scope== + +let x = /*RENAME*/newFunction(); +x; + +function newFunction() { + let x = 1; + return x; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Let_NoType.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Let_NoType.ts new file mode 100644 index 00000000000..4f407ce5703 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Let_NoType.ts @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +/*[#|*/let x = 1;/*|]*/ +x; + +// ==SCOPE::Extract to function in global scope== + +let x = /*RENAME*/newFunction(); +x; + +function newFunction() { + let x = 1; + return x; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Let_Type.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Let_Type.ts new file mode 100644 index 00000000000..048b77094ea --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Let_Type.ts @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +/*[#|*/let x: number = 1;/*|]*/ +x; + +// ==SCOPE::Extract to function in global scope== + +let x: number = /*RENAME*/newFunction(); +x; + +function newFunction() { + let x: number = 1; + return x; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Multiple1.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Multiple1.ts new file mode 100644 index 00000000000..07ec452e360 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Multiple1.ts @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +/*[#|*/const x = 1, y: string = "a";/*|]*/ +x; y; + +// ==SCOPE::Extract to function in global scope== + +const { x, y }: { x: number; y: string; } = /*RENAME*/newFunction(); +x; y; + +function newFunction() { + const x = 1, y: string = "a"; + return { x, y }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Multiple2.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Multiple2.js new file mode 100644 index 00000000000..c58c39bf6b8 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Multiple2.js @@ -0,0 +1,16 @@ +// ==ORIGINAL== + +/*[#|*/const x = 1, y = "a"; +const z = 3;/*|]*/ +x; y; z; + +// ==SCOPE::Extract to function in global scope== + +const { x, y, z } = /*RENAME*/newFunction(); +x; y; z; + +function newFunction() { + const x = 1, y = "a"; + const z = 3; + return { x, y, z }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Multiple2.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Multiple2.ts new file mode 100644 index 00000000000..c58c39bf6b8 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Multiple2.ts @@ -0,0 +1,16 @@ +// ==ORIGINAL== + +/*[#|*/const x = 1, y = "a"; +const z = 3;/*|]*/ +x; y; z; + +// ==SCOPE::Extract to function in global scope== + +const { x, y, z } = /*RENAME*/newFunction(); +x; y; z; + +function newFunction() { + const x = 1, y = "a"; + const z = 3; + return { x, y, z }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Multiple3.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Multiple3.ts new file mode 100644 index 00000000000..b8ae2b72883 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Multiple3.ts @@ -0,0 +1,16 @@ +// ==ORIGINAL== + +/*[#|*/const x = 1, y: string = "a"; +let z = 3;/*|]*/ +x; y; z; + +// ==SCOPE::Extract to function in global scope== + +var { x, y, z }: { x: number; y: string; z: number; } = /*RENAME*/newFunction(); +x; y; z; + +function newFunction() { + const x = 1, y: string = "a"; + let z = 3; + return { x, y, z }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ShorthandProperty.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ShorthandProperty.js new file mode 100644 index 00000000000..67b4f64290c --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ShorthandProperty.js @@ -0,0 +1,27 @@ +// ==ORIGINAL== + +function f() { + /*[#|*/let x;/*|]*/ + return { x }; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let x = /*RENAME*/newFunction(); + return { x }; + + function newFunction() { + let x; + return x; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let x = /*RENAME*/newFunction(); + return { x }; +} +function newFunction() { + let x; + return x; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ShorthandProperty.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ShorthandProperty.ts new file mode 100644 index 00000000000..67b4f64290c --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ShorthandProperty.ts @@ -0,0 +1,27 @@ +// ==ORIGINAL== + +function f() { + /*[#|*/let x;/*|]*/ + return { x }; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let x = /*RENAME*/newFunction(); + return { x }; + + function newFunction() { + let x; + return x; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let x = /*RENAME*/newFunction(); + return { x }; +} +function newFunction() { + let x; + return x; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Var.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Var.js new file mode 100644 index 00000000000..5a784c366c1 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Var.js @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +/*[#|*/var x = 1;/*|]*/ +x; + +// ==SCOPE::Extract to function in global scope== + +var x = /*RENAME*/newFunction(); +x; + +function newFunction() { + var x = 1; + return x; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Var.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Var.ts new file mode 100644 index 00000000000..5a784c366c1 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Var.ts @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +/*[#|*/var x = 1;/*|]*/ +x; + +// ==SCOPE::Extract to function in global scope== + +var x = /*RENAME*/newFunction(); +x; + +function newFunction() { + var x = 1; + return x; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_NoType.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_NoType.js new file mode 100644 index 00000000000..1da5a568333 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_NoType.js @@ -0,0 +1,34 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/const x = 1; + a++;/*|]*/ + a; x; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + const x = /*RENAME*/newFunction(); + a; x; + + function newFunction() { + const x = 1; + a++; + return x; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + let x; + ({ x, a } = /*RENAME*/newFunction(a)); + a; x; +} +function newFunction(a) { + const x = 1; + a++; + return { x, a }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_NoType.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_NoType.ts new file mode 100644 index 00000000000..f93f43ceebf --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_NoType.ts @@ -0,0 +1,34 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/const x = 1; + a++;/*|]*/ + a; x; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + const x = /*RENAME*/newFunction(); + a; x; + + function newFunction() { + const x = 1; + a++; + return x; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + let x; + ({ x, a } = /*RENAME*/newFunction(a)); + a; x; +} +function newFunction(a: number) { + const x = 1; + a++; + return { x, a }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_Type.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_Type.ts new file mode 100644 index 00000000000..ec846f7f288 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_Type.ts @@ -0,0 +1,34 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/const x: number = 1; + a++;/*|]*/ + a; x; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + const x: number = /*RENAME*/newFunction(); + a; x; + + function newFunction() { + const x: number = 1; + a++; + return x; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + let x: number | undefined; + ({ x, a } = /*RENAME*/newFunction(a)); + a; x; +} +function newFunction(a: number) { + const x: number = 1; + a++; + return { x, a }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_NoType.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_NoType.js new file mode 100644 index 00000000000..2f298c8719f --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_NoType.js @@ -0,0 +1,34 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/let x = 1; + a++;/*|]*/ + a; x; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + let x = /*RENAME*/newFunction(); + a; x; + + function newFunction() { + let x = 1; + a++; + return x; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + let x; + ({ x, a } = /*RENAME*/newFunction(a)); + a; x; +} +function newFunction(a) { + let x = 1; + a++; + return { x, a }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_NoType.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_NoType.ts new file mode 100644 index 00000000000..e4afefa9da6 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_NoType.ts @@ -0,0 +1,34 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/let x = 1; + a++;/*|]*/ + a; x; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + let x = /*RENAME*/newFunction(); + a; x; + + function newFunction() { + let x = 1; + a++; + return x; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + let x; + ({ x, a } = /*RENAME*/newFunction(a)); + a; x; +} +function newFunction(a: number) { + let x = 1; + a++; + return { x, a }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_Type.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_Type.ts new file mode 100644 index 00000000000..795effbeb7e --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_Type.ts @@ -0,0 +1,34 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/let x: number = 1; + a++;/*|]*/ + a; x; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + let x: number = /*RENAME*/newFunction(); + a; x; + + function newFunction() { + let x: number = 1; + a++; + return x; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + let x: number | undefined; + ({ x, a } = /*RENAME*/newFunction(a)); + a; x; +} +function newFunction(a: number) { + let x: number = 1; + a++; + return { x, a }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed1.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed1.js new file mode 100644 index 00000000000..c36557847f7 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed1.js @@ -0,0 +1,38 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/const x = 1; + let y = 2; + a++;/*|]*/ + a; x; y; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + var { x, y } = /*RENAME*/newFunction(); + a; x; y; + + function newFunction() { + const x = 1; + let y = 2; + a++; + return { x, y }; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + let x; + let y; + ({ x, y, a } = /*RENAME*/newFunction(a)); + a; x; y; +} +function newFunction(a) { + const x = 1; + let y = 2; + a++; + return { x, y, a }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed1.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed1.ts new file mode 100644 index 00000000000..eaeb781bc48 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed1.ts @@ -0,0 +1,38 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/const x = 1; + let y = 2; + a++;/*|]*/ + a; x; y; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + var { x, y } = /*RENAME*/newFunction(); + a; x; y; + + function newFunction() { + const x = 1; + let y = 2; + a++; + return { x, y }; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + let x; + let y; + ({ x, y, a } = /*RENAME*/newFunction(a)); + a; x; y; +} +function newFunction(a: number) { + const x = 1; + let y = 2; + a++; + return { x, y, a }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed2.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed2.js new file mode 100644 index 00000000000..2d1151a549c --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed2.js @@ -0,0 +1,38 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/var x = 1; + let y = 2; + a++;/*|]*/ + a; x; y; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + var { x, y } = /*RENAME*/newFunction(); + a; x; y; + + function newFunction() { + var x = 1; + let y = 2; + a++; + return { x, y }; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + var x; + let y; + ({ x, y, a } = /*RENAME*/newFunction(a)); + a; x; y; +} +function newFunction(a) { + var x = 1; + let y = 2; + a++; + return { x, y, a }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed2.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed2.ts new file mode 100644 index 00000000000..9466b5dc37f --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed2.ts @@ -0,0 +1,38 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/var x = 1; + let y = 2; + a++;/*|]*/ + a; x; y; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + var { x, y } = /*RENAME*/newFunction(); + a; x; y; + + function newFunction() { + var x = 1; + let y = 2; + a++; + return { x, y }; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + var x; + let y; + ({ x, y, a } = /*RENAME*/newFunction(a)); + a; x; y; +} +function newFunction(a: number) { + var x = 1; + let y = 2; + a++; + return { x, y, a }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed3.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed3.ts new file mode 100644 index 00000000000..604d2a33c43 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed3.ts @@ -0,0 +1,38 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/let x: number = 1; + let y = 2; + a++;/*|]*/ + a; x; y; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + let { x, y }: { x: number; y: number; } = /*RENAME*/newFunction(); + a; x; y; + + function newFunction() { + let x: number = 1; + let y = 2; + a++; + return { x, y }; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + let x: number | undefined; + let y; + ({ x, y, a } = /*RENAME*/newFunction(a)); + a; x; y; +} +function newFunction(a: number) { + let x: number = 1; + let y = 2; + a++; + return { x, y, a }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_UnionUndefined.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_UnionUndefined.ts new file mode 100644 index 00000000000..0cf71e45e28 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_UnionUndefined.ts @@ -0,0 +1,42 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/let x: number | undefined = 1; + let y: undefined | number = 2; + let z: (undefined | number) = 3; + a++;/*|]*/ + a; x; y; z; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + let { x, y, z }: { x: number; y: number; z: number; } = /*RENAME*/newFunction(); + a; x; y; z; + + function newFunction() { + let x: number | undefined = 1; + let y: undefined | number = 2; + let z: (undefined | number) = 3; + a++; + return { x, y, z }; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + let x: number | undefined; + let y: undefined | number; + let z: (undefined | number); + ({ x, y, z, a } = /*RENAME*/newFunction(a)); + a; x; y; z; +} +function newFunction(a: number) { + let x: number | undefined = 1; + let y: undefined | number = 2; + let z: (undefined | number) = 3; + a++; + return { x, y, z, a }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Var.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Var.js new file mode 100644 index 00000000000..25e910713d8 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Var.js @@ -0,0 +1,34 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/var x = 1; + a++;/*|]*/ + a; x; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + var x = /*RENAME*/newFunction(); + a; x; + + function newFunction() { + var x = 1; + a++; + return x; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + var x; + ({ x, a } = /*RENAME*/newFunction(a)); + a; x; +} +function newFunction(a) { + var x = 1; + a++; + return { x, a }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Var.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Var.ts new file mode 100644 index 00000000000..e215e3d0978 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Var.ts @@ -0,0 +1,34 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/var x = 1; + a++;/*|]*/ + a; x; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + var x = /*RENAME*/newFunction(); + a; x; + + function newFunction() { + var x = 1; + a++; + return x; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + var x; + ({ x, a } = /*RENAME*/newFunction(a)); + a; x; +} +function newFunction(a: number) { + var x = 1; + a++; + return { x, a }; +} diff --git a/tests/cases/fourslash/extract-method14.ts b/tests/cases/fourslash/extract-method14.ts index ea051aabbe7..ddfd8cbcbd6 100644 --- a/tests/cases/fourslash/extract-method14.ts +++ b/tests/cases/fourslash/extract-method14.ts @@ -18,7 +18,7 @@ edit.applyRefactor({ newContent: `function foo() { var i = 10; - var __return: any; + let __return; ({ __return, i } = /*RENAME*/newFunction(i)); return __return; } From c5f40a1b2b77d99d3ed81b4e9ecb3dac41d15e8a Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 11 Oct 2017 17:26:41 -0700 Subject: [PATCH 109/312] Add additional deep clone tests --- src/harness/unittests/extractFunctions.ts | 36 +++++++++++++++++++ src/services/utilities.ts | 5 +++ ...ableDeclaration_Writes_Let_LiteralType1.ts | 34 ++++++++++++++++++ ...ableDeclaration_Writes_Let_LiteralType2.ts | 34 ++++++++++++++++++ ...Declaration_Writes_Let_TypeWithComments.ts | 34 ++++++++++++++++++ 5 files changed, 143 insertions(+) create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_LiteralType1.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_LiteralType2.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_TypeWithComments.ts diff --git a/src/harness/unittests/extractFunctions.ts b/src/harness/unittests/extractFunctions.ts index 715a4f5aa0c..c69026c0be8 100644 --- a/src/harness/unittests/extractFunctions.ts +++ b/src/harness/unittests/extractFunctions.ts @@ -438,6 +438,42 @@ function f() { a; x; }`); + // We propagate numericLiteralFlags, but it's not consumed by the emitter, + // so everything comes out decimal. It would be nice to improve this. + testExtractFunction("extractFunction_VariableDeclaration_Writes_Let_LiteralType1", ` +function f() { + let a = 1; + [#|let x: 0o10 | 10 | 0b10 = 10; + a++;|] + a; x; +}`); + + testExtractFunction("extractFunction_VariableDeclaration_Writes_Let_LiteralType2", ` +function f() { + let a = 1; + [#|let x: "a" | 'b' = 'a'; + a++;|] + a; x; +}`); + + // We propagate numericLiteralFlags, but it's not consumed by the emitter, + // so everything comes out decimal. It would be nice to improve this. + testExtractFunction("extractFunction_VariableDeclaration_Writes_Let_LiteralType1", ` +function f() { + let a = 1; + [#|let x: 0o10 | 10 | 0b10 = 10; + a++;|] + a; x; +}`); + + testExtractFunction("extractFunction_VariableDeclaration_Writes_Let_TypeWithComments", ` +function f() { + let a = 1; + [#|let x: /*A*/ "a" /*B*/ | /*C*/ 'b' /*D*/ = 'a'; + a++;|] + a; x; +}`); + testExtractFunction("extractFunction_VariableDeclaration_Writes_Const_NoType", ` function f() { let a = 1; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index a8dea4ddd0e..c57b82bc8b8 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1350,6 +1350,11 @@ namespace ts { if (visited === node) { // This only happens for leaf nodes - internal nodes always see their children change. const clone = getSynthesizedClone(node); + if (isStringLiteral(clone)) { + clone.textSourceNode = node as any; + } else if (isNumericLiteral(clone)) { + clone.numericLiteralFlags = (node as any).numericLiteralFlags; + } clone.pos = node.pos; clone.end = node.end; return clone; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_LiteralType1.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_LiteralType1.ts new file mode 100644 index 00000000000..50bad34efce --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_LiteralType1.ts @@ -0,0 +1,34 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/let x: 0o10 | 10 | 0b10 = 10; + a++;/*|]*/ + a; x; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + let x: 8 | 10 | 2 = /*RENAME*/newFunction(); + a; x; + + function newFunction() { + let x: 0o10 | 10 | 0b10 = 10; + a++; + return x; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + let x: (8 | 10 | 2) | undefined; + ({ x, a } = /*RENAME*/newFunction(a)); + a; x; +} +function newFunction(a: number) { + let x: 0o10 | 10 | 0b10 = 10; + a++; + return { x, a }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_LiteralType2.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_LiteralType2.ts new file mode 100644 index 00000000000..2df8ab67e9f --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_LiteralType2.ts @@ -0,0 +1,34 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/let x: "a" | 'b' = 'a'; + a++;/*|]*/ + a; x; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + let x: "a" | 'b' = /*RENAME*/newFunction(); + a; x; + + function newFunction() { + let x: "a" | 'b' = 'a'; + a++; + return x; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + let x: ("a" | 'b') | undefined; + ({ x, a } = /*RENAME*/newFunction(a)); + a; x; +} +function newFunction(a: number) { + let x: "a" | 'b' = 'a'; + a++; + return { x, a }; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_TypeWithComments.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_TypeWithComments.ts new file mode 100644 index 00000000000..53599c26d08 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_TypeWithComments.ts @@ -0,0 +1,34 @@ +// ==ORIGINAL== + +function f() { + let a = 1; + /*[#|*/let x: /*A*/ "a" /*B*/ | /*C*/ 'b' /*D*/ = 'a'; + a++;/*|]*/ + a; x; +} +// ==SCOPE::Extract to inner function in function 'f'== + +function f() { + let a = 1; + let x: /*A*/ "a" /*B*/ | /*C*/ 'b' /*D*/ = /*RENAME*/newFunction(); + a; x; + + function newFunction() { + let x: /*A*/ "a" /*B*/ | /*C*/ 'b' /*D*/ = 'a'; + a++; + return x; + } +} +// ==SCOPE::Extract to function in global scope== + +function f() { + let a = 1; + let x: (/*A*/ "a" /*B*/ | /*C*/ 'b' /*D*/) | undefined; + ({ x, a } = /*RENAME*/newFunction(a)); + a; x; +} +function newFunction(a: number) { + let x: /*A*/ "a" /*B*/ | /*C*/ 'b' /*D*/ = 'a'; + a++; + return { x, a }; +} From 1b896c2f80d7283fa06dd6dca17568e627f5af13 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Wed, 11 Oct 2017 17:35:52 -0700 Subject: [PATCH 110/312] Fix lint error --- src/services/utilities.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/services/utilities.ts b/src/services/utilities.ts index c57b82bc8b8..0eb3f88cc9a 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1352,7 +1352,8 @@ namespace ts { const clone = getSynthesizedClone(node); if (isStringLiteral(clone)) { clone.textSourceNode = node as any; - } else if (isNumericLiteral(clone)) { + } + else if (isNumericLiteral(clone)) { clone.numericLiteralFlags = (node as any).numericLiteralFlags; } clone.pos = node.pos; From 625486455d5a4333fa564772c488b014f7967424 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 12 Oct 2017 09:02:22 -0700 Subject: [PATCH 111/312] Update public api baseline --- tests/baselines/reference/api/tsserverlibrary.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 61320be7eb7..baa7abbbd9c 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7190,7 +7190,7 @@ declare namespace ts.server { private _isJsInferredProject; toggleJsInferredProject(isJsInferredProject: boolean): void; setCompilerOptions(options?: CompilerOptions): void; - /** this is canonical project root path*/ + /** this is canonical project root path */ readonly projectRootPath: string | undefined; addRoot(info: ScriptInfo): void; removeRoot(info: ScriptInfo): void; From 73826bdb7b921e1bf497f97e95ef9ce5e01e5857 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 3 Oct 2017 15:39:12 -0700 Subject: [PATCH 112/312] Allow Extract Constant into enclosing scope in spite of RangeFacts.UsesThis --- src/harness/unittests/extractConstants.ts | 24 +++++++++++++++++ src/services/refactors/extractSymbol.ts | 5 +++- .../extractConstant_This_Constructor.js | 16 ++++++++++++ .../extractConstant_This_Constructor.ts | 26 +++++++++++++++++++ .../extractConstant_This_Method.js | 16 ++++++++++++ .../extractConstant_This_Method.ts | 26 +++++++++++++++++++ .../extractConstant_This_Property.ts | 18 +++++++++++++ tests/cases/fourslash/extract-method20.ts | 5 ++-- 8 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/extractConstant/extractConstant_This_Constructor.js create mode 100644 tests/baselines/reference/extractConstant/extractConstant_This_Constructor.ts create mode 100644 tests/baselines/reference/extractConstant/extractConstant_This_Method.js create mode 100644 tests/baselines/reference/extractConstant/extractConstant_This_Method.ts create mode 100644 tests/baselines/reference/extractConstant/extractConstant_This_Property.ts diff --git a/src/harness/unittests/extractConstants.ts b/src/harness/unittests/extractConstants.ts index c5ddc18fea4..09f8db34f31 100644 --- a/src/harness/unittests/extractConstants.ts +++ b/src/harness/unittests/extractConstants.ts @@ -230,6 +230,30 @@ function f(): void { } testExtractConstantFailed("extractConstant_Never", ` function f(): never { } [#|f();|]`); + + testExtractConstant("extractConstant_This_Constructor", ` +class C { + constructor() { + [#|this.m2()|]; + } + m2() { return 1; } +}`); + + testExtractConstant("extractConstant_This_Method", ` +class C { + m1() { + [#|this.m2()|]; + } + m2() { return 1; } +}`); + + testExtractConstant("extractConstant_This_Property", ` +namespace N { // Force this test to be TS-only + class C { + x = 1; + y = [#|this.x|]; + } +}`); }); function testExtractConstant(caption: string, text: string) { diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index a03bb843600..9dd148e5420 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -476,7 +476,10 @@ namespace ts.refactor.extractSymbol { // if range uses this as keyword or as type inside the class then it can only be extracted to a method of the containing class const containingClass = getContainingClass(current); if (containingClass) { - return [containingClass]; + const containingFunction = findAncestor(current, isFunctionLikeDeclaration); + return containingFunction + ? [containingFunction, containingClass] + : [containingClass]; } } diff --git a/tests/baselines/reference/extractConstant/extractConstant_This_Constructor.js b/tests/baselines/reference/extractConstant/extractConstant_This_Constructor.js new file mode 100644 index 00000000000..cf45ab2cd3f --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_This_Constructor.js @@ -0,0 +1,16 @@ +// ==ORIGINAL== + +class C { + constructor() { + /*[#|*/this.m2()/*|]*/; + } + m2() { return 1; } +} +// ==SCOPE::Extract to constant in enclosing scope== + +class C { + constructor() { + const /*RENAME*/newLocal = this.m2(); + } + m2() { return 1; } +} \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_This_Constructor.ts b/tests/baselines/reference/extractConstant/extractConstant_This_Constructor.ts new file mode 100644 index 00000000000..d36d1a6fa21 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_This_Constructor.ts @@ -0,0 +1,26 @@ +// ==ORIGINAL== + +class C { + constructor() { + /*[#|*/this.m2()/*|]*/; + } + m2() { return 1; } +} +// ==SCOPE::Extract to constant in enclosing scope== + +class C { + constructor() { + const /*RENAME*/newLocal = this.m2(); + } + m2() { return 1; } +} +// ==SCOPE::Extract to readonly field in class 'C'== + +class C { + private readonly newProperty = this.m2(); + + constructor() { + this./*RENAME*/newProperty; + } + m2() { return 1; } +} \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_This_Method.js b/tests/baselines/reference/extractConstant/extractConstant_This_Method.js new file mode 100644 index 00000000000..fd703868e9f --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_This_Method.js @@ -0,0 +1,16 @@ +// ==ORIGINAL== + +class C { + m1() { + /*[#|*/this.m2()/*|]*/; + } + m2() { return 1; } +} +// ==SCOPE::Extract to constant in enclosing scope== + +class C { + m1() { + const /*RENAME*/newLocal = this.m2(); + } + m2() { return 1; } +} \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_This_Method.ts b/tests/baselines/reference/extractConstant/extractConstant_This_Method.ts new file mode 100644 index 00000000000..0dbaa4372d4 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_This_Method.ts @@ -0,0 +1,26 @@ +// ==ORIGINAL== + +class C { + m1() { + /*[#|*/this.m2()/*|]*/; + } + m2() { return 1; } +} +// ==SCOPE::Extract to constant in enclosing scope== + +class C { + m1() { + const /*RENAME*/newLocal = this.m2(); + } + m2() { return 1; } +} +// ==SCOPE::Extract to readonly field in class 'C'== + +class C { + private readonly newProperty = this.m2(); + + m1() { + this./*RENAME*/newProperty; + } + m2() { return 1; } +} \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_This_Property.ts b/tests/baselines/reference/extractConstant/extractConstant_This_Property.ts new file mode 100644 index 00000000000..04b3b50da1b --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_This_Property.ts @@ -0,0 +1,18 @@ +// ==ORIGINAL== + +namespace N { // Force this test to be TS-only + class C { + x = 1; + y = /*[#|*/this.x/*|]*/; + } +} +// ==SCOPE::Extract to readonly field in class 'C'== + +namespace N { // Force this test to be TS-only + class C { + x = 1; + private readonly newProperty = this.x; + + y = this./*RENAME*/newProperty; + } +} \ No newline at end of file diff --git a/tests/cases/fourslash/extract-method20.ts b/tests/cases/fourslash/extract-method20.ts index 75927f0fd5c..bd137c55d19 100644 --- a/tests/cases/fourslash/extract-method20.ts +++ b/tests/cases/fourslash/extract-method20.ts @@ -10,5 +10,6 @@ //// } goTo.select('a', 'b') -verify.refactorAvailable('Extract Symbol', 'function_scope_0'); -verify.not.refactorAvailable('Extract Symbol', 'function_scope_1'); +verify.not.refactorAvailable('Extract Symbol', 'function_scope_0'); +verify.refactorAvailable('Extract Symbol', 'function_scope_1'); +verify.not.refactorAvailable('Extract Symbol', 'function_scope_2'); From e4313f62c66375316dd9c6e979e770f3c36c8e27 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 12 Oct 2017 09:44:02 -0700 Subject: [PATCH 113/312] Add missing test coverage for jumps in finally blocks --- src/harness/unittests/extractRanges.ts | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/harness/unittests/extractRanges.ts b/src/harness/unittests/extractRanges.ts index 2ddcac482a9..a467bb23e0f 100644 --- a/src/harness/unittests/extractRanges.ts +++ b/src/harness/unittests/extractRanges.ts @@ -152,6 +152,16 @@ namespace ts { } } `); + testExtractRange(` + function f(x: number) { + [#|[$|try { + x++; + } + finally { + return 1; + }|]|] + } + `); }); testExtractRangeFailed("extractRangeFailed1", @@ -313,6 +323,23 @@ switch (x) { refactor.extractSymbol.Messages.CannotExtractRange.message ]); + testExtractRangeFailed("extractRangeFailed11", + ` + function f(x: number) { + while (true) { + [#|try { + x++; + } + finally { + break; + }|] + } + } + `, + [ + refactor.extractSymbol.Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements.message + ]); + testExtractRangeFailed("extract-method-not-for-token-expression-statement", `[#|a|]`, [refactor.extractSymbol.Messages.CannotExtractIdentifier.message]); }); } \ No newline at end of file From da0c79f2a3fe4793c00b1c47274c36e26a0ff2c4 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 12 Oct 2017 10:09:52 -0700 Subject: [PATCH 114/312] Simplify checkTypeArguments based on PR comments --- src/compiler/checker.ts | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ff78ccaa135..a58fa1cc9b5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15643,32 +15643,28 @@ namespace ts { return getInferredTypes(context); } - function checkTypeArguments(signature: Signature, typeArguments: ReadonlyArray, reportErrors: boolean, headMessage?: DiagnosticMessage): Type[] | false { + function checkTypeArguments(signature: Signature, typeArgumentNodes: ReadonlyArray, reportErrors: boolean, headMessage?: DiagnosticMessage): Type[] | false { const isJavascript = isInJavaScriptFile(signature.declaration); const typeParameters = signature.typeParameters; - const typeArgumentTypes = fillMissingTypeArguments(map(typeArguments, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isJavascript); + const typeArgumentTypes = fillMissingTypeArguments(map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isJavascript); let mapper: TypeMapper; - for (let i = 0; i < typeArguments.length; i++) { + for (let i = 0; i < typeArgumentNodes.length; i++) { const constraint = getConstraintOfTypeParameter(typeParameters[i]); - if (constraint) { - let errorInfo: DiagnosticMessageChain; - let typeArgumentHeadMessage = Diagnostics.Type_0_does_not_satisfy_the_constraint_1; - if (reportErrors && headMessage) { - errorInfo = chainDiagnosticMessages(errorInfo, typeArgumentHeadMessage); - typeArgumentHeadMessage = headMessage; - } - if (!mapper) { - mapper = createTypeMapper(typeParameters, typeArgumentTypes); - } - const typeArgument = typeArgumentTypes[i]; - if (!checkTypeAssignableTo( - typeArgument, - getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument), - reportErrors ? typeArguments[i] : undefined, - typeArgumentHeadMessage, - errorInfo)) { - return false; - } + if (!constraint) continue; + + const errorInfo = reportErrors && headMessage && chainDiagnosticMessages(undefined, Diagnostics.Type_0_does_not_satisfy_the_constraint_1); + const typeArgumentHeadMessage = headMessage || Diagnostics.Type_0_does_not_satisfy_the_constraint_1; + if (!mapper) { + mapper = createTypeMapper(typeParameters, typeArgumentTypes); + } + const typeArgument = typeArgumentTypes[i]; + if (!checkTypeAssignableTo( + typeArgument, + getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument), + reportErrors ? typeArgumentNodes[i] : undefined, + typeArgumentHeadMessage, + errorInfo)) { + return false; } } return typeArgumentTypes; From 8ea13bef48cc276634e770009144995b843f5553 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 12 Oct 2017 10:11:09 -0700 Subject: [PATCH 115/312] Fix lint --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a58fa1cc9b5..3380e89cd0f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15652,7 +15652,7 @@ namespace ts { const constraint = getConstraintOfTypeParameter(typeParameters[i]); if (!constraint) continue; - const errorInfo = reportErrors && headMessage && chainDiagnosticMessages(undefined, Diagnostics.Type_0_does_not_satisfy_the_constraint_1); + const errorInfo = reportErrors && headMessage && chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Type_0_does_not_satisfy_the_constraint_1); const typeArgumentHeadMessage = headMessage || Diagnostics.Type_0_does_not_satisfy_the_constraint_1; if (!mapper) { mapper = createTypeMapper(typeParameters, typeArgumentTypes); From 4487917f89bd5e068a4d35e8db22bf728cab4b74 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 12 Oct 2017 10:14:58 -0700 Subject: [PATCH 116/312] Quick fix for no-implicit-any errors to add explicit type annotation (#14786) * Infer from usage quick fix * Change full function singature * Add property/element access support * Fix a few issues * Some cleanup * Expose getArrayType and getPromiseType * Switch to collecting all usage before infering * Infer array and promise type arguments * Handel enums in binary operators * consolidate usage of addCandidateTypes * Handel rest paramters * Properly handel `+=` and `+` inference for numbers and strings * Add print quickfixes debug helper * Add rest param tests * Add optional paramter tests * Handel set accessors * Support getters * Support no implicit any error for variable at use site * Support properties * Only offer quick fix if an infered type other than any is available * Rename functions * Move to a separate namespace * Check cancellation token * Cleanup * Check for accesibile symbols where serializing types * Remove JS support * Reorganize functions * Mark APIs as internal * Fix lint errors * Removed conflict markers. * Update 'createSymbol' to use '__String'. * Fixed most problems relating to '__String' and 'includeJsDocComments' in the fix itself. * Addressed most API changes. * Make all helpers internal * Use a diffrent writer and not the built-in single line write * Infer types for all parameters in a parameter list instead of one at a time * Accept baselines * Code review commments * Respond to code review comments --- src/compiler/checker.ts | 18 + src/compiler/core.ts | 6 +- src/compiler/diagnosticMessages.json | 16 +- src/compiler/types.ts | 18 + src/compiler/utilities.ts | 8 + src/services/codefixes/fixes.ts | 1 + src/services/codefixes/inferFromUsage.ts | 653 ++++++++++++++++++ .../reference/api/tsserverlibrary.d.ts | 2 + tests/baselines/reference/api/typescript.d.ts | 2 + .../cases/fourslash/codeFixInferFromUsage.ts | 9 + .../fourslash/codeFixInferFromUsageGetter.ts | 10 + .../fourslash/codeFixInferFromUsageGetter2.ts | 11 + .../codeFixInferFromUsageInaccessibleTypes.ts | 20 + .../fourslash/codeFixInferFromUsageMember.ts | 11 + .../fourslash/codeFixInferFromUsageMember2.ts | 10 + .../fourslash/codeFixInferFromUsageMember3.ts | 9 + ...codeFixInferFromUsageMultipleParameters.ts | 9 + .../codeFixInferFromUsageOptionalParam.ts | 9 + .../codeFixInferFromUsageOptionalParam2.ts | 8 + .../codeFixInferFromUsageRestParam.ts | 11 + .../codeFixInferFromUsageRestParam2.ts | 11 + .../codeFixInferFromUsageRestParam3.ts | 8 + .../fourslash/codeFixInferFromUsageSetter.ts | 10 + .../fourslash/codeFixInferFromUsageSetter2.ts | 10 + .../codeFixInferFromUsageVariable.ts | 9 + .../codeFixInferFromUsageVariable2.ts | 13 + 26 files changed, 893 insertions(+), 9 deletions(-) create mode 100644 src/services/codefixes/inferFromUsage.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsage.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageGetter.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageGetter2.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageInaccessibleTypes.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageMember.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageMember2.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageMember3.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageMultipleParameters.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageOptionalParam.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageOptionalParam2.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageRestParam.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageRestParam2.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageRestParam3.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageSetter.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageSetter2.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageVariable.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageVariable2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index efdf4589be4..e835fb6c828 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -226,6 +226,23 @@ namespace ts { return tryFindAmbientModule(moduleName, /*withAugmentations*/ false); }, getApparentType, + getUnionType, + createAnonymousType, + createSignature, + createSymbol, + createIndexInfo, + getAnyType: () => anyType, + getStringType: () => stringType, + getNumberType: () => numberType, + createPromiseType, + createArrayType, + getBooleanType: () => booleanType, + getVoidType: () => voidType, + getUndefinedType: () => undefinedType, + getNullType: () => nullType, + getESSymbolType: () => esSymbolType, + getNeverType: () => neverType, + isSymbolAccessible, isArrayLikeType, getAllPossiblePropertiesOfTypes, getSuggestionForNonexistentProperty: (node, type) => getSuggestionForNonexistentProperty(node, type), @@ -3675,6 +3692,7 @@ namespace ts { function buildParameterDisplay(p: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { const parameterNode = p.valueDeclaration; + if (parameterNode ? isRestParameter(parameterNode) : isTransientSymbol(p) && p.isRestParameter) { writePunctuation(writer, SyntaxKind.DotDotDotToken); } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index af02cec79c5..f838d6abfef 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -213,11 +213,13 @@ namespace ts { return undefined; } - export function zipWith(arrayA: ReadonlyArray, arrayB: ReadonlyArray, callback: (a: T, b: U, index: number) => void): void { + export function zipWith(arrayA: ReadonlyArray, arrayB: ReadonlyArray, callback: (a: T, b: U, index: number) => V): V[] { + const result: V[] = []; Debug.assert(arrayA.length === arrayB.length); for (let i = 0; i < arrayA.length; i++) { - callback(arrayA[i], arrayB[i], i); + result.push(callback(arrayA[i], arrayB[i], i)); } + return result; } export function zipToMap(keys: ReadonlyArray, values: ReadonlyArray): Map { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 5b601c1b2a1..1db368bb541 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3681,6 +3681,7 @@ "category": "Message", "code": 90017 }, + "Disable checking for this file.": { "category": "Message", "code": 90018 @@ -3725,7 +3726,6 @@ "category": "Message", "code": 90028 }, - "Convert function to an ES2015 class": { "category": "Message", "code": 95001 @@ -3734,34 +3734,36 @@ "category": "Message", "code": 95002 }, - "Extract symbol": { "category": "Message", "code": 95003 }, - "Extract to {0} in {1}": { "category": "Message", "code": 95004 }, - "Extract function": { "category": "Message", "code": 95005 }, - "Extract constant": { "category": "Message", "code": 95006 }, - "Extract to {0} in enclosing scope": { "category": "Message", "code": 95007 }, - "Extract to {0} in {1} scope": { "category": "Message", "code": 95008 + }, + "Infer type of '{0}' from usage.": { + "category": "Message", + "code": 95009 + }, + "Infer parameter types from usage.": { + "category": "Message", + "code": 95010 } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 528664f5eee..42e8292b13b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2695,6 +2695,24 @@ namespace ts { getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined; /* @internal */ getBaseConstraintOfType(type: Type): Type | undefined; + /* @internal */ getAnyType(): Type; + /* @internal */ getStringType(): Type; + /* @internal */ getNumberType(): Type; + /* @internal */ getBooleanType(): Type; + /* @internal */ getVoidType(): Type; + /* @internal */ getUndefinedType(): Type; + /* @internal */ getNullType(): Type; + /* @internal */ getESSymbolType(): Type; + /* @internal */ getNeverType(): Type; + /* @internal */ getUnionType(types: Type[], subtypeReduction?: boolean): Type; + /* @internal */ createArrayType(elementType: Type): Type; + /* @internal */ createPromiseType(type: Type): Type; + + /* @internal */ createAnonymousType(symbol: Symbol, members: SymbolTable, callSignatures: Signature[], constructSignatures: Signature[], stringIndexInfo: IndexInfo, numberIndexInfo: IndexInfo): Type; + /* @internal */ createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], thisParameter: Symbol | undefined, parameters: Symbol[], resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasLiteralTypes: boolean): Signature; + /* @internal */ createSymbol(flags: SymbolFlags, name: __String): TransientSymbol; + /* @internal */ createIndexInfo(type: Type, isReadonly: boolean, declaration?: SignatureDeclaration): IndexInfo; + /* @internal */ isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult; /* @internal */ tryFindAmbientModuleWithoutAugmentations(moduleName: string): Symbol | undefined; /* @internal */ getSymbolWalker(accept?: (symbol: Symbol) => boolean): SymbolWalker; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 291e1f2fa66..4688a7779e3 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -5649,6 +5649,14 @@ namespace ts { return node.kind >= SyntaxKind.FirstJSDocTagNode && node.kind <= SyntaxKind.LastJSDocTagNode; } + export function isSetAccessor(node: Node): node is SetAccessorDeclaration { + return node.kind === SyntaxKind.SetAccessor; + } + + export function isGetAccessor(node: Node): node is GetAccessorDeclaration { + return node.kind === SyntaxKind.GetAccessor; + } + /** True if has jsdoc nodes attached to it. */ /* @internal */ export function hasJSDocNodes(node: Node): node is HasJSDoc { diff --git a/src/services/codefixes/fixes.ts b/src/services/codefixes/fixes.ts index b024dfae7cd..7ee0aaa6799 100644 --- a/src/services/codefixes/fixes.ts +++ b/src/services/codefixes/fixes.ts @@ -13,3 +13,4 @@ /// /// /// +/// diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts new file mode 100644 index 00000000000..046eb915c1e --- /dev/null +++ b/src/services/codefixes/inferFromUsage.ts @@ -0,0 +1,653 @@ +/* @internal */ +namespace ts.codefix { + registerCodeFix({ + errorCodes: [ + // Variable declarations + Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code, + + // Variable uses + Diagnostics.Variable_0_implicitly_has_an_1_type.code, + + // Parameter declarations + Diagnostics.Parameter_0_implicitly_has_an_1_type.code, + Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code, + + // Get Accessor declarations + Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code, + Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code, + + // Set Accessor declarations + Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code, + + // Property declarations + Diagnostics.Member_0_implicitly_has_an_1_type.code, + ], + getCodeActions: getActionsForAddExplicitTypeAnnotation + }); + + function getActionsForAddExplicitTypeAnnotation({ sourceFile, program, span: { start }, errorCode, cancellationToken }: CodeFixContext): CodeAction[] | undefined { + const token = getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); + let writer: StringSymbolWriter; + + if (isInJavaScriptFile(token)) { + return undefined; + } + + switch (token.kind) { + case SyntaxKind.Identifier: + case SyntaxKind.DotDotDotToken: + case SyntaxKind.PublicKeyword: + case SyntaxKind.PrivateKeyword: + case SyntaxKind.ProtectedKeyword: + case SyntaxKind.ReadonlyKeyword: + // Allowed + break; + default: + return undefined; + } + + const containingFunction = getContainingFunction(token); + const checker = program.getTypeChecker(); + + switch (errorCode) { + // Variable and Property declarations + case Diagnostics.Member_0_implicitly_has_an_1_type.code: + case Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code: + return getCodeActionForVariableDeclaration(token.parent); + case Diagnostics.Variable_0_implicitly_has_an_1_type.code: + return getCodeActionForVariableUsage(token); + + // Parameter declarations + case Diagnostics.Parameter_0_implicitly_has_an_1_type.code: + if (isSetAccessor(containingFunction)) { + return getCodeActionForSetAccessor(containingFunction); + } + // falls through + case Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code: + return getCodeActionForParameters(token.parent); + + // Get Accessor declarations + case Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code: + case Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code: + return isGetAccessor(containingFunction) ? getCodeActionForGetAccessor(containingFunction) : undefined; + + // Set Accessor declarations + case Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code: + return isSetAccessor(containingFunction) ? getCodeActionForSetAccessor(containingFunction) : undefined; + } + + return undefined; + + function getCodeActionForVariableDeclaration(declaration: VariableDeclaration | PropertyDeclaration | PropertySignature) { + if (!isIdentifier(declaration.name)) { + return undefined; + } + + const type = inferTypeForVariableFromUsage(declaration.name); + const typeString = type && typeToString(type, declaration); + + if (!typeString) { + return undefined; + } + + return createCodeActions(declaration.name.getText(), declaration.name.getEnd(), `: ${typeString}`); + } + + function getCodeActionForVariableUsage(token: Identifier) { + const symbol = checker.getSymbolAtLocation(token); + return symbol && symbol.valueDeclaration && getCodeActionForVariableDeclaration(symbol.valueDeclaration); + } + + function isApplicableFunctionForInference(declaration: FunctionLike): declaration is MethodDeclaration | FunctionDeclaration | ConstructorDeclaration { + switch (declaration.kind) { + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.Constructor: + return true; + case SyntaxKind.FunctionExpression: + return !!(declaration as FunctionExpression).name; + } + return false; + } + + function getCodeActionForParameters(parameterDeclaration: ParameterDeclaration): CodeAction[] { + if (!isIdentifier(parameterDeclaration.name) || !isApplicableFunctionForInference(containingFunction)) { + return undefined; + } + + const types = inferTypeForParametersFromUsage(containingFunction) || + map(containingFunction.parameters, p => isIdentifier(p.name) && inferTypeForVariableFromUsage(p.name)); + + if (!types) { + return undefined; + } + + const textChanges: TextChange[] = zipWith(containingFunction.parameters, types, (parameter, type) => { + if (type && !parameter.type && !parameter.initializer) { + const typeString = typeToString(type, containingFunction); + return typeString ? { + span: { start: parameter.end, length: 0 }, + newText: `: ${typeString}` + } : undefined; + } + }).filter(c => !!c); + + return textChanges.length ? [{ + description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Infer_parameter_types_from_usage), [parameterDeclaration.name.getText()]), + changes: [{ + fileName: sourceFile.fileName, + textChanges + }] + }] : undefined; + } + + function getCodeActionForSetAccessor(setAccessorDeclaration: SetAccessorDeclaration) { + const setAccessorParameter = setAccessorDeclaration.parameters[0]; + if (!setAccessorParameter || !isIdentifier(setAccessorDeclaration.name) || !isIdentifier(setAccessorParameter.name)) { + return undefined; + } + + const type = inferTypeForVariableFromUsage(setAccessorDeclaration.name) || + inferTypeForVariableFromUsage(setAccessorParameter.name); + const typeString = type && typeToString(type, containingFunction); + if (!typeString) { + return undefined; + } + + return createCodeActions(setAccessorDeclaration.name.getText(), setAccessorParameter.name.getEnd(), `: ${typeString}`); + } + + function getCodeActionForGetAccessor(getAccessorDeclaration: GetAccessorDeclaration) { + if (!isIdentifier(getAccessorDeclaration.name)) { + return undefined; + } + + const type = inferTypeForVariableFromUsage(getAccessorDeclaration.name); + const typeString = type && typeToString(type, containingFunction); + if (!typeString) { + return undefined; + } + + const closeParenToken = getFirstChildOfKind(getAccessorDeclaration, sourceFile, SyntaxKind.CloseParenToken); + return createCodeActions(getAccessorDeclaration.name.getText(), closeParenToken.getEnd(), `: ${typeString}`); + } + + function createCodeActions(name: string, start: number, typeString: string) { + return [{ + description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Infer_type_of_0_from_usage), [name]), + changes: [{ + fileName: sourceFile.fileName, + textChanges: [{ + span: { start, length: 0 }, + newText: typeString + }] + }] + }]; + } + + function getReferences(token: PropertyName | Token) { + const references = FindAllReferences.findReferencedSymbols( + program, + cancellationToken, + program.getSourceFiles(), + token.getSourceFile(), + token.getStart()); + + Debug.assert(!!references, "Found no references!"); + Debug.assert(references.length === 1, "Found more references than expected"); + + return map(references[0].references, r => getTokenAtPosition(program.getSourceFile(r.fileName), r.textSpan.start, /*includeJsDocComment*/ false)); + } + + function inferTypeForVariableFromUsage(token: Identifier) { + return InferFromReference.inferTypeFromReferences(getReferences(token), checker, cancellationToken); + } + + function inferTypeForParametersFromUsage(containingFunction: FunctionLikeDeclaration) { + switch (containingFunction.kind) { + case SyntaxKind.Constructor: + case SyntaxKind.FunctionExpression: + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.MethodDeclaration: + const isConstructor = containingFunction.kind === SyntaxKind.Constructor; + const searchToken = isConstructor ? + >getFirstChildOfKind(containingFunction, sourceFile, SyntaxKind.ConstructorKeyword) : + containingFunction.name; + if (searchToken) { + return InferFromReference.inferTypeForParametersFromReferences(getReferences(searchToken), containingFunction, checker, cancellationToken); + } + } + } + + function getTypeAccessiblityWriter() { + if (!writer) { + let str = ""; + let typeIsAccessible = true; + + const writeText: (text: string) => void = text => str += text; + writer = { + string: () => typeIsAccessible ? str : undefined, + writeKeyword: writeText, + writeOperator: writeText, + writePunctuation: writeText, + writeSpace: writeText, + writeStringLiteral: writeText, + writeParameter: writeText, + writeProperty: writeText, + writeSymbol: writeText, + writeLine: () => str += " ", + increaseIndent: noop, + decreaseIndent: noop, + clear: () => { str = ""; typeIsAccessible = true; }, + trackSymbol: (symbol, declaration, meaning) => { + if (checker.isSymbolAccessible(symbol, declaration, meaning, /*shouldComputeAliasToMarkVisible*/ false).accessibility !== SymbolAccessibility.Accessible) { + typeIsAccessible = false; + } + }, + reportInaccessibleThisError: () => { typeIsAccessible = false; }, + reportPrivateInBaseOfClassExpression: () => { typeIsAccessible = false; }, + }; + } + writer.clear(); + return writer; + } + + function typeToString(type: Type, enclosingDeclaration: Declaration) { + const writer = getTypeAccessiblityWriter(); + checker.getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration); + return writer.string(); + } + + function getFirstChildOfKind(node: Node, sourcefile: SourceFile, kind: SyntaxKind) { + for (const child of node.getChildren(sourcefile)) { + if (child.kind === kind) return child; + } + return undefined; + } + } + + namespace InferFromReference { + interface CallContext { + argumentTypes: Type[]; + returnType: UsageContext; + } + + interface UsageContext { + isNumber?: boolean; + isString?: boolean; + isNumberOrString?: boolean; + candidateTypes?: Type[]; + properties?: UnderscoreEscapedMap; + callContexts?: CallContext[]; + constructContexts?: CallContext[]; + numberIndexContext?: UsageContext; + stringIndexContext?: UsageContext; + } + + export function inferTypeFromReferences(references: Identifier[], checker: TypeChecker, cancellationToken: CancellationToken): Type | undefined { + const usageContext: UsageContext = {}; + for (const reference of references) { + cancellationToken.throwIfCancellationRequested(); + inferTypeFromContext(reference, checker, usageContext); + } + return getTypeFromUsageContext(usageContext, checker); + } + + export function inferTypeForParametersFromReferences(references: Identifier[], declaration: FunctionLikeDeclaration, checker: TypeChecker, cancellationToken: CancellationToken): (Type | undefined)[] | undefined { + if (declaration.parameters) { + const usageContext: UsageContext = {}; + for (const reference of references) { + cancellationToken.throwIfCancellationRequested(); + inferTypeFromContext(reference, checker, usageContext); + } + const isConstructor = declaration.kind === SyntaxKind.Constructor; + const callContexts = isConstructor ? usageContext.constructContexts : usageContext.callContexts; + if (callContexts) { + const paramTypes: Type[] = []; + for (let parameterIndex = 0; parameterIndex < declaration.parameters.length; parameterIndex++) { + let types: Type[] = []; + const isRestParameter = ts.isRestParameter(declaration.parameters[parameterIndex]); + for (const callContext of callContexts) { + if (callContext.argumentTypes.length > parameterIndex) { + if (isRestParameter) { + types = concatenate(types, map(callContext.argumentTypes.slice(parameterIndex), a => checker.getBaseTypeOfLiteralType(a))); + } + else { + types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[parameterIndex])); + } + } + } + if (types.length) { + const type = checker.getWidenedType(checker.getUnionType(types, /*subtypeReduction*/ true)); + paramTypes[parameterIndex] = isRestParameter ? checker.createArrayType(type) : type; + } + } + return paramTypes; + } + } + return undefined; + } + + function inferTypeFromContext(node: Expression, checker: TypeChecker, usageContext: UsageContext): void { + while (isRightSideOfQualifiedNameOrPropertyAccess(node)) { + node = node.parent; + } + + switch (node.parent.kind) { + case SyntaxKind.PostfixUnaryExpression: + usageContext.isNumber = true; + break; + case SyntaxKind.PrefixUnaryExpression: + inferTypeFromPrefixUnaryExpressionContext(node.parent, usageContext); + break; + case SyntaxKind.BinaryExpression: + inferTypeFromBinaryExpressionContext(node, node.parent, checker, usageContext); + break; + case SyntaxKind.CaseClause: + case SyntaxKind.DefaultClause: + inferTypeFromSwitchStatementLabelContext(node.parent, checker, usageContext); + break; + case SyntaxKind.CallExpression: + case SyntaxKind.NewExpression: + if ((node.parent).expression === node) { + inferTypeFromCallExpressionContext(node.parent, checker, usageContext); + } + else { + inferTypeFromContextualType(node, checker, usageContext); + } + break; + case SyntaxKind.PropertyAccessExpression: + inferTypeFromPropertyAccessExpressionContext(node.parent, checker, usageContext); + break; + case SyntaxKind.ElementAccessExpression: + inferTypeFromPropertyElementExpressionContext(node.parent, node, checker, usageContext); + break; + default: + return inferTypeFromContextualType(node, checker, usageContext); + } + } + + function inferTypeFromContextualType(node: Expression, checker: TypeChecker, usageContext: UsageContext): void { + if (isPartOfExpression(node)) { + addCandidateType(usageContext, checker.getContextualType(node)); + } + } + + function inferTypeFromPrefixUnaryExpressionContext(node: PrefixUnaryExpression, usageContext: UsageContext): void { + switch (node.operator) { + case SyntaxKind.PlusPlusToken: + case SyntaxKind.MinusMinusToken: + case SyntaxKind.MinusToken: + case SyntaxKind.TildeToken: + usageContext.isNumber = true; + break; + + case SyntaxKind.PlusToken: + usageContext.isNumberOrString = true; + break; + + // case SyntaxKind.ExclamationToken: + // no inferences here; + } + } + + function inferTypeFromBinaryExpressionContext(node: Expression, parent: BinaryExpression, checker: TypeChecker, usageContext: UsageContext): void { + switch (parent.operatorToken.kind) { + // ExponentiationOperator + case SyntaxKind.AsteriskAsteriskToken: + + // MultiplicativeOperator + case SyntaxKind.AsteriskToken: + case SyntaxKind.SlashToken: + case SyntaxKind.PercentToken: + + // ShiftOperator + case SyntaxKind.LessThanLessThanToken: + case SyntaxKind.GreaterThanGreaterThanToken: + case SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + + // BitwiseOperator + case SyntaxKind.AmpersandToken: + case SyntaxKind.BarToken: + case SyntaxKind.CaretToken: + + // CompoundAssignmentOperator + case SyntaxKind.MinusEqualsToken: + case SyntaxKind.AsteriskAsteriskEqualsToken: + case SyntaxKind.AsteriskEqualsToken: + case SyntaxKind.SlashEqualsToken: + case SyntaxKind.PercentEqualsToken: + case SyntaxKind.AmpersandEqualsToken: + case SyntaxKind.BarEqualsToken: + case SyntaxKind.CaretEqualsToken: + case SyntaxKind.LessThanLessThanEqualsToken: + case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: + case SyntaxKind.GreaterThanGreaterThanEqualsToken: + + // AdditiveOperator + case SyntaxKind.MinusToken: + + // RelationalOperator + case SyntaxKind.LessThanToken: + case SyntaxKind.LessThanEqualsToken: + case SyntaxKind.GreaterThanToken: + case SyntaxKind.GreaterThanEqualsToken: + const operandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left); + if (operandType.flags & TypeFlags.EnumLike) { + addCandidateType(usageContext, operandType); + } + else { + usageContext.isNumber = true; + } + break; + + case SyntaxKind.PlusEqualsToken: + case SyntaxKind.PlusToken: + const otherOperandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left); + if (otherOperandType.flags & TypeFlags.EnumLike) { + addCandidateType(usageContext, otherOperandType); + } + else if (otherOperandType.flags & TypeFlags.NumberLike) { + usageContext.isNumber = true; + } + else if (otherOperandType.flags & TypeFlags.StringLike) { + usageContext.isString = true; + } + else { + usageContext.isNumberOrString = true; + } + break; + + // AssignmentOperators + case SyntaxKind.EqualsToken: + case SyntaxKind.EqualsEqualsToken: + case SyntaxKind.EqualsEqualsEqualsToken: + case SyntaxKind.ExclamationEqualsEqualsToken: + case SyntaxKind.ExclamationEqualsToken: + addCandidateType(usageContext, checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left)); + break; + + case SyntaxKind.InKeyword: + if (node === parent.left) { + usageContext.isString = true; + } + break; + + // LogicalOperator + case SyntaxKind.BarBarToken: + if (node === parent.left && + (node.parent.parent.kind === SyntaxKind.VariableDeclaration || isAssignmentExpression(node.parent.parent, /*excludeCompoundAssignment*/ true))) { + // var x = x || {}; + // TODO: use getFalsyflagsOfType + addCandidateType(usageContext, checker.getTypeAtLocation(parent.right)); + } + break; + + case SyntaxKind.AmpersandAmpersandToken: + case SyntaxKind.CommaToken: + case SyntaxKind.InstanceOfKeyword: + // nothing to infer here + break; + } + } + + function inferTypeFromSwitchStatementLabelContext(parent: CaseOrDefaultClause, checker: TypeChecker, usageContext: UsageContext): void { + addCandidateType(usageContext, checker.getTypeAtLocation((parent.parent.parent).expression)); + } + + function inferTypeFromCallExpressionContext(parent: CallExpression | NewExpression, checker: TypeChecker, usageContext: UsageContext): void { + const callContext: CallContext = { + argumentTypes: [], + returnType: {} + }; + + if (parent.arguments) { + for (const argument of parent.arguments) { + callContext.argumentTypes.push(checker.getTypeAtLocation(argument)); + } + } + + inferTypeFromContext(parent, checker, callContext.returnType); + if (parent.kind === SyntaxKind.CallExpression) { + (usageContext.callContexts || (usageContext.callContexts = [])).push(callContext); + } + else { + (usageContext.constructContexts || (usageContext.constructContexts = [])).push(callContext); + } + } + + function inferTypeFromPropertyAccessExpressionContext(parent: PropertyAccessExpression, checker: TypeChecker, usageContext: UsageContext): void { + const name = escapeLeadingUnderscores(parent.name.text); + if (!usageContext.properties) { + usageContext.properties = createUnderscoreEscapedMap(); + } + const propertyUsageContext = {}; + inferTypeFromContext(parent, checker, propertyUsageContext); + usageContext.properties.set(name, propertyUsageContext); + } + + function inferTypeFromPropertyElementExpressionContext(parent: ElementAccessExpression, node: Expression, checker: TypeChecker, usageContext: UsageContext): void { + if (node === parent.argumentExpression) { + usageContext.isNumberOrString = true; + return; + } + else { + const indexType = checker.getTypeAtLocation(parent); + const indexUsageContext = {}; + inferTypeFromContext(parent, checker, indexUsageContext); + if (indexType.flags & TypeFlags.NumberLike) { + usageContext.numberIndexContext = indexUsageContext; + } + else { + usageContext.stringIndexContext = indexUsageContext; + } + } + } + + function getTypeFromUsageContext(usageContext: UsageContext, checker: TypeChecker): Type | undefined { + if (usageContext.isNumberOrString && !usageContext.isNumber && !usageContext.isString) { + return checker.getUnionType([checker.getNumberType(), checker.getStringType()]); + } + else if (usageContext.isNumber) { + return checker.getNumberType(); + } + else if (usageContext.isString) { + return checker.getStringType(); + } + else if (usageContext.candidateTypes) { + return checker.getWidenedType(checker.getUnionType(map(usageContext.candidateTypes, t => checker.getBaseTypeOfLiteralType(t)), /*subtypeReduction*/ true)); + } + else if (usageContext.properties && hasCallContext(usageContext.properties.get("then" as __String))) { + const paramType = getParameterTypeFromCallContexts(0, usageContext.properties.get("then" as __String).callContexts, /*isRestParameter*/ false, checker); + const types = paramType.getCallSignatures().map(c => c.getReturnType()); + return checker.createPromiseType(types.length ? checker.getUnionType(types, /*subtypeReduction*/ true) : checker.getAnyType()); + } + else if (usageContext.properties && hasCallContext(usageContext.properties.get("push" as __String))) { + return checker.createArrayType(getParameterTypeFromCallContexts(0, usageContext.properties.get("push" as __String).callContexts, /*isRestParameter*/ false, checker)); + } + else if (usageContext.properties || usageContext.callContexts || usageContext.constructContexts || usageContext.numberIndexContext || usageContext.stringIndexContext) { + const members = createUnderscoreEscapedMap(); + const callSignatures: Signature[] = []; + const constructSignatures: Signature[] = []; + let stringIndexInfo: IndexInfo; + let numberIndexInfo: IndexInfo; + + if (usageContext.properties) { + usageContext.properties.forEach((context, name) => { + const symbol = checker.createSymbol(SymbolFlags.Property, name); + symbol.type = getTypeFromUsageContext(context, checker); + members.set(name, symbol); + }); + } + + if (usageContext.callContexts) { + for (const callContext of usageContext.callContexts) { + callSignatures.push(getSignatureFromCallContext(callContext, checker)); + } + } + + if (usageContext.constructContexts) { + for (const constructContext of usageContext.constructContexts) { + constructSignatures.push(getSignatureFromCallContext(constructContext, checker)); + } + } + + if (usageContext.numberIndexContext) { + numberIndexInfo = checker.createIndexInfo(getTypeFromUsageContext(usageContext.numberIndexContext, checker), /*isReadonly*/ false); + } + + if (usageContext.stringIndexContext) { + stringIndexInfo = checker.createIndexInfo(getTypeFromUsageContext(usageContext.stringIndexContext, checker), /*isReadonly*/ false); + } + + return checker.createAnonymousType(/*symbol*/ undefined, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); + } + else { + return undefined; + } + } + + function getParameterTypeFromCallContexts(parameterIndex: number, callContexts: CallContext[], isRestParameter: boolean, checker: TypeChecker) { + let types: Type[] = []; + if (callContexts) { + for (const callContext of callContexts) { + if (callContext.argumentTypes.length > parameterIndex) { + if (isRestParameter) { + types = concatenate(types, map(callContext.argumentTypes.slice(parameterIndex), a => checker.getBaseTypeOfLiteralType(a))); + } + else { + types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[parameterIndex])); + } + } + } + } + + if (types.length) { + const type = checker.getWidenedType(checker.getUnionType(types, /*subtypeReduction*/ true)); + return isRestParameter ? checker.createArrayType(type) : type; + } + return undefined; + } + + function getSignatureFromCallContext(callContext: CallContext, checker: TypeChecker): Signature { + const parameters: Symbol[] = []; + for (let i = 0; i < callContext.argumentTypes.length; i++) { + const symbol = checker.createSymbol(SymbolFlags.FunctionScopedVariable, escapeLeadingUnderscores(`arg${i}`)); + symbol.type = checker.getWidenedType(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[i])); + parameters.push(symbol); + } + const returnType = getTypeFromUsageContext(callContext.returnType, checker); + return checker.createSignature(/*declaration*/ undefined, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, callContext.argumentTypes.length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); + } + + function addCandidateType(context: UsageContext, type: Type) { + if (type && !(type.flags & TypeFlags.Any) && !(type.flags & TypeFlags.Never)) { + (context.candidateTypes || (context.candidateTypes = [])).push(type); + } + } + + function hasCallContext(usageContext: UsageContext) { + return usageContext && usageContext.callContexts; + } + } +} diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index b1595030df0..82c593d8d42 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3068,6 +3068,8 @@ declare namespace ts { function isCaseOrDefaultClause(node: Node): node is CaseOrDefaultClause; /** True if node is of a kind that may contain comment text. */ function isJSDocCommentContainingNode(node: Node): boolean; + function isSetAccessor(node: Node): node is SetAccessorDeclaration; + function isGetAccessor(node: Node): node is GetAccessorDeclaration; } declare namespace ts { interface ErrorCallback { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 0c74f74c741..14fae7d0d77 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3123,6 +3123,8 @@ declare namespace ts { function isCaseOrDefaultClause(node: Node): node is CaseOrDefaultClause; /** True if node is of a kind that may contain comment text. */ function isJSDocCommentContainingNode(node: Node): boolean; + function isSetAccessor(node: Node): node is SetAccessorDeclaration; + function isGetAccessor(node: Node): node is GetAccessorDeclaration; } declare namespace ts { function createNode(kind: SyntaxKind, pos?: number, end?: number): Node; diff --git a/tests/cases/fourslash/codeFixInferFromUsage.ts b/tests/cases/fourslash/codeFixInferFromUsage.ts new file mode 100644 index 00000000000..5de8d989799 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsage.ts @@ -0,0 +1,9 @@ +/// + +// @noImplicitAny: true +////[|var foo;|] +////function f() { +//// foo += 2; +////} + +verify.rangeAfterCodeFix("var foo: number;",/*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 0); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixInferFromUsageGetter.ts b/tests/cases/fourslash/codeFixInferFromUsageGetter.ts new file mode 100644 index 00000000000..f83eed1432d --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageGetter.ts @@ -0,0 +1,10 @@ +/// + +// @noImplicitAny: true +////declare class C { +//// [|get x();|] +////} +////} +////(new C).x = 1; + +verify.rangeAfterCodeFix("get x(): number;", undefined, undefined, 0); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixInferFromUsageGetter2.ts b/tests/cases/fourslash/codeFixInferFromUsageGetter2.ts new file mode 100644 index 00000000000..a50d471ad12 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageGetter2.ts @@ -0,0 +1,11 @@ +/// + +// @noImplicitAny: true +////class C { +//// [|get x() |]{ +//// return undefined; +//// } +////} +////(new C).x = 1; + +verify.rangeAfterCodeFix("get x(): number", undefined, undefined, 0); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixInferFromUsageInaccessibleTypes.ts b/tests/cases/fourslash/codeFixInferFromUsageInaccessibleTypes.ts new file mode 100644 index 00000000000..ae9106be8c4 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageInaccessibleTypes.ts @@ -0,0 +1,20 @@ +/// + +// @noImplicitAny: true +////function f1([|a |]) { } +////function h1() { +//// class C { p: number }; +//// f1({ ofTypeC: new C() }); +////} +//// +////function f2([|a |]) { } +////function h2() { +//// interface I { a: number } +//// var i: I = {a : 1}; +//// f2(i); +//// f2(2); +//// f2(false); +////} +//// + +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixInferFromUsageMember.ts b/tests/cases/fourslash/codeFixInferFromUsageMember.ts new file mode 100644 index 00000000000..c82542e5e3f --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageMember.ts @@ -0,0 +1,11 @@ +/// + +// @noImplicitAny: true +////class C { +//// [|p;|] +//// method() { +//// this.p.push(10); +//// } +////} + +verify.rangeAfterCodeFix("p: number[];"); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixInferFromUsageMember2.ts b/tests/cases/fourslash/codeFixInferFromUsageMember2.ts new file mode 100644 index 00000000000..486112935ee --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageMember2.ts @@ -0,0 +1,10 @@ +/// + +// @noImplicitAny: true +////interface I { +//// [|p;|] +////} +////var i: I; +////i.p = 0; + +verify.rangeAfterCodeFix("p: number;"); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixInferFromUsageMember3.ts b/tests/cases/fourslash/codeFixInferFromUsageMember3.ts new file mode 100644 index 00000000000..49f2cb66c18 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageMember3.ts @@ -0,0 +1,9 @@ +/// + +// @noImplicitAny: true +////class C { +//// constructor([|public p)|] { } +////} +////new C("string"); + +verify.rangeAfterCodeFix("public p: string)"); diff --git a/tests/cases/fourslash/codeFixInferFromUsageMultipleParameters.ts b/tests/cases/fourslash/codeFixInferFromUsageMultipleParameters.ts new file mode 100644 index 00000000000..89e2c935e87 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageMultipleParameters.ts @@ -0,0 +1,9 @@ +/// + +// @noImplicitAny: true +//// function f([|a, b, c, d: number, e = 0, ...d |]) { +//// } +//// f(1, "string", { a: 1 }, {shouldNotBeHere: 2}, {shouldNotBeHere: 2}, 3, "string"); + + +verify.rangeAfterCodeFix("a: number, b: string, c: { a: number; }, d: number, e = 0, ...d: (string | number)[]", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 1); diff --git a/tests/cases/fourslash/codeFixInferFromUsageOptionalParam.ts b/tests/cases/fourslash/codeFixInferFromUsageOptionalParam.ts new file mode 100644 index 00000000000..f10de4bb03a --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageOptionalParam.ts @@ -0,0 +1,9 @@ +/// + +// @noImplicitAny: true +////function f([|a? |]){ +////} +////f(); +////f(1); + +verify.rangeAfterCodeFix("a?: number"); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixInferFromUsageOptionalParam2.ts b/tests/cases/fourslash/codeFixInferFromUsageOptionalParam2.ts new file mode 100644 index 00000000000..2ca820e0327 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageOptionalParam2.ts @@ -0,0 +1,8 @@ +/// + +// @noImplicitAny: true +////function f([|a? |]){ +//// if (a < 9) return; +////} + +verify.rangeAfterCodeFix("a?: number"); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixInferFromUsageRestParam.ts b/tests/cases/fourslash/codeFixInferFromUsageRestParam.ts new file mode 100644 index 00000000000..963f84d6515 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageRestParam.ts @@ -0,0 +1,11 @@ +/// + +// @noImplicitAny: true +////function f(a: number, [|...rest |]){ +////} +////f(1); +////f(2, "s1"); +////f(3, "s1", "s2"); +////f(3, "s1", "s2", "s3", "s4"); + +verify.rangeAfterCodeFix("...rest: string[]"); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixInferFromUsageRestParam2.ts b/tests/cases/fourslash/codeFixInferFromUsageRestParam2.ts new file mode 100644 index 00000000000..ae826240228 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageRestParam2.ts @@ -0,0 +1,11 @@ +/// + +// @noImplicitAny: true +////function f(a: number, [|...rest |]){ +////} +////f(1); +////f(2, "s1"); +////f(3, false, "s2"); +////f(4, "s1", "s2", false, "s4"); + +verify.rangeAfterCodeFix("...rest: (string | boolean)[]"); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixInferFromUsageRestParam3.ts b/tests/cases/fourslash/codeFixInferFromUsageRestParam3.ts new file mode 100644 index 00000000000..4752176a324 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageRestParam3.ts @@ -0,0 +1,8 @@ +/// + +// @noImplicitAny: true +////function f(a: number, [|...rest |]){ +//// rest.push(22); +////} + +verify.rangeAfterCodeFix("...rest: number[]"); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixInferFromUsageSetter.ts b/tests/cases/fourslash/codeFixInferFromUsageSetter.ts new file mode 100644 index 00000000000..f515cd5a906 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageSetter.ts @@ -0,0 +1,10 @@ +/// + +// @noImplicitAny: true +////class C { +//// set [|x(v)|] { +//// } +////} +////(new C).x = 1; + +verify.rangeAfterCodeFix("x(v: number)", undefined, undefined, 0); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixInferFromUsageSetter2.ts b/tests/cases/fourslash/codeFixInferFromUsageSetter2.ts new file mode 100644 index 00000000000..a1169a03df1 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageSetter2.ts @@ -0,0 +1,10 @@ +/// + +// @noImplicitAny: true +////class C { +//// set [|x(v)|] { +//// } +////} +////(new C).x = 1; + +verify.rangeAfterCodeFix("x(v: number)", undefined, undefined, 1); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixInferFromUsageVariable.ts b/tests/cases/fourslash/codeFixInferFromUsageVariable.ts new file mode 100644 index 00000000000..f89b8c867f9 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageVariable.ts @@ -0,0 +1,9 @@ +/// + +// @noImplicitAny: true +////[|var x;|] +////function f() { +//// x++; +////} + +verify.rangeAfterCodeFix("var x: number;", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 0); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixInferFromUsageVariable2.ts b/tests/cases/fourslash/codeFixInferFromUsageVariable2.ts new file mode 100644 index 00000000000..bf8e2bb07e5 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageVariable2.ts @@ -0,0 +1,13 @@ +/// + +// @noImplicitAny: true +////[|var x; +////function f() { +//// x++; +////}|] + +verify.rangeAfterCodeFix(`var x: number; +function f() { + x++; +} +`, /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 1); \ No newline at end of file From 27b4417304cebfc6fe22aeb747c0dca368ed906f Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 12 Oct 2017 10:38:02 -0700 Subject: [PATCH 117/312] Assert:checkTypeArguments isn't passed too many type arguments --- src/compiler/checker.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3380e89cd0f..3b6ef850ce8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15649,6 +15649,7 @@ namespace ts { const typeArgumentTypes = fillMissingTypeArguments(map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isJavascript); let mapper: TypeMapper; for (let i = 0; i < typeArgumentNodes.length; i++) { + Debug.assert(typeParameters[i] !== undefined, "Should not call checkTypeArguments with too many type arguments"); const constraint = getConstraintOfTypeParameter(typeParameters[i]); if (!constraint) continue; From 4de6b0dd2d104754ddca97d3c03e1819e0793668 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 12 Oct 2017 11:34:34 -0700 Subject: [PATCH 118/312] Introduce and consume suppressLeadingAndTrailingTrivia Fixes #18626 --- src/compiler/factory.ts | 10 ++++++ src/harness/unittests/extractConstants.ts | 8 +++++ src/harness/unittests/extractFunctions.ts | 8 +++++ src/services/refactors/extractSymbol.ts | 18 +++++----- src/services/utilities.ts | 35 +++++++++++++++++++ .../extractConstant_PreserveTrivia.js | 17 +++++++++ .../extractConstant_PreserveTrivia.ts | 17 +++++++++ .../extractFunction/extractFunction13.ts | 6 ++-- .../extractFunction_PreserveTrivia.js | 19 ++++++++++ .../extractFunction_PreserveTrivia.ts | 19 ++++++++++ .../fourslash/extract-method-uniqueName.ts | 5 ++- 11 files changed, 146 insertions(+), 16 deletions(-) create mode 100644 tests/baselines/reference/extractConstant/extractConstant_PreserveTrivia.js create mode 100644 tests/baselines/reference/extractConstant/extractConstant_PreserveTrivia.ts create mode 100644 tests/baselines/reference/extractFunction/extractFunction_PreserveTrivia.js create mode 100644 tests/baselines/reference/extractFunction/extractFunction_PreserveTrivia.ts diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index fe183c5e806..65c1c92f366 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -2612,6 +2612,16 @@ namespace ts { return node; } + /** + * Sets flags that control emit behavior of a node. + */ + /* @internal */ + export function addEmitFlags(node: T, emitFlags: EmitFlags) { + const emitNode = getOrCreateEmitNode(node); + emitNode.flags = emitNode.flags | emitFlags; + return node; + } + /** * Gets a custom text range to use when emitting source maps. */ diff --git a/src/harness/unittests/extractConstants.ts b/src/harness/unittests/extractConstants.ts index 09f8db34f31..61ffbd01a63 100644 --- a/src/harness/unittests/extractConstants.ts +++ b/src/harness/unittests/extractConstants.ts @@ -223,6 +223,14 @@ const f = () => { testExtractConstant("extractConstant_ArrowFunction_Expression", `const f = () => [#|2 + 1|];`); + testExtractConstant("extractConstant_PreserveTrivia", ` +// a +var q = /*b*/ //c + /*d*/ [#|1 /*e*/ //f + /*g*/ + /*h*/ //i + /*j*/ 2|] /*k*/ //l + /*m*/; /*n*/ //o`); + testExtractConstantFailed("extractConstant_Void", ` function f(): void { } [#|f();|]`); diff --git a/src/harness/unittests/extractFunctions.ts b/src/harness/unittests/extractFunctions.ts index c69026c0be8..789882ffd50 100644 --- a/src/harness/unittests/extractFunctions.ts +++ b/src/harness/unittests/extractFunctions.ts @@ -532,6 +532,14 @@ function f() { [#|let x;|] return { x }; }`); + + testExtractFunction("extractFunction_PreserveTrivia", ` +// a +var q = /*b*/ //c + /*d*/ [#|1 /*e*/ //f + /*g*/ + /*h*/ //i + /*j*/ 2|] /*k*/ //l + /*m*/; /*n*/ //o`); }); function testExtractFunction(caption: string, text: string) { diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 9dd148e5420..715b42b6bc8 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -740,6 +740,8 @@ namespace ts.refactor.extractSymbol { } const { body, returnValueProperty } = transformFunctionBody(node, exposedVariableDeclarations, writes, substitutions, !!(range.facts & RangeFacts.HasReturn)); + suppressLeadingAndTrailingTrivia(body); + let newFunction: MethodDeclaration | FunctionDeclaration; if (isClassLike(scope)) { @@ -926,15 +928,10 @@ namespace ts.refactor.extractSymbol { } } - if (isReadonlyArray(range.range)) { - changeTracker.replaceNodesWithNodes(context.file, range.range, newNodes, { - nodeSeparator: context.newLineCharacter, - suffix: context.newLineCharacter // insert newline only when replacing statements - }); - } - else { - changeTracker.replaceNodeWithNodes(context.file, range.range, newNodes, { nodeSeparator: context.newLineCharacter }); - } + const replacementRange = isReadonlyArray(range.range) + ? { pos: first(range.range).getStart(), end: last(range.range).end } + : { pos: range.range.getStart(), end: range.range.end }; + changeTracker.replaceRangeWithNodes(context.file, replacementRange, newNodes, { nodeSeparator: context.newLineCharacter }); const edits = changeTracker.getChanges(); const renameRange = isReadonlyArray(range.range) ? first(range.range) : range.range; @@ -982,6 +979,7 @@ namespace ts.refactor.extractSymbol { : checker.typeToTypeNode(checker.getContextualType(node), scope, NodeBuilderFlags.NoTruncation); const initializer = transformConstantInitializer(node, substitutions); + suppressLeadingAndTrailingTrivia(initializer); const changeTracker = textChanges.ChangeTracker.fromContext(context); @@ -1014,7 +1012,7 @@ namespace ts.refactor.extractSymbol { changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newVariable, { suffix: context.newLineCharacter + context.newLineCharacter }); // Consume - changeTracker.replaceNodeWithNodes(context.file, node, [localReference], { nodeSeparator: context.newLineCharacter }); + changeTracker.replaceRange(context.file, { pos: node.getStart(), end: node.end }, localReference); } else { const newVariableDeclaration = createVariableDeclaration(localNameText, variableType, initializer); diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 0eb3f88cc9a..df3f3c5c6b4 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1369,4 +1369,39 @@ namespace ts { return visited; } + + /** + * Sets EmitFlags to suppress leading and trailing trivia on the node. + */ + /* @internal */ + export function suppressLeadingAndTrailingTrivia(node: Node) { + Debug.assert(node !== undefined); + + suppressLeading(node); + suppressTrailing(node); + + function suppressLeading(node: Node) { + addEmitFlags(node, EmitFlags.NoLeadingComments); + + const firstChild = forEachChild(node, child => child); + firstChild && suppressLeading(firstChild); + } + + function suppressTrailing(node: Node) { + addEmitFlags(node, EmitFlags.NoTrailingComments); + + let lastChild: Node = undefined; + forEachChild( + node, + child => (lastChild = child, undefined), + children => { + // As an optimization, jump straight to the end of the list. + if (children.length) { + lastChild = last(children); + } + return undefined; + }); + lastChild && suppressTrailing(lastChild); + } + } } diff --git a/tests/baselines/reference/extractConstant/extractConstant_PreserveTrivia.js b/tests/baselines/reference/extractConstant/extractConstant_PreserveTrivia.js new file mode 100644 index 00000000000..22abb77901d --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_PreserveTrivia.js @@ -0,0 +1,17 @@ +// ==ORIGINAL== + +// a +var q = /*b*/ //c + /*d*/ /*[#|*/1 /*e*/ //f + /*g*/ + /*h*/ //i + /*j*/ 2/*|]*/ /*k*/ //l + /*m*/; /*n*/ //o +// ==SCOPE::Extract to constant in enclosing scope== +const newLocal = 1 /*e*/ //f + /*g*/ + /*h*/ //i + /*j*/ 2; + +// a +var q = /*b*/ //c + /*d*/ /*RENAME*/newLocal /*k*/ //l + /*m*/; /*n*/ //o \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_PreserveTrivia.ts b/tests/baselines/reference/extractConstant/extractConstant_PreserveTrivia.ts new file mode 100644 index 00000000000..22abb77901d --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_PreserveTrivia.ts @@ -0,0 +1,17 @@ +// ==ORIGINAL== + +// a +var q = /*b*/ //c + /*d*/ /*[#|*/1 /*e*/ //f + /*g*/ + /*h*/ //i + /*j*/ 2/*|]*/ /*k*/ //l + /*m*/; /*n*/ //o +// ==SCOPE::Extract to constant in enclosing scope== +const newLocal = 1 /*e*/ //f + /*g*/ + /*h*/ //i + /*j*/ 2; + +// a +var q = /*b*/ //c + /*d*/ /*RENAME*/newLocal /*k*/ //l + /*m*/; /*n*/ //o \ No newline at end of file diff --git a/tests/baselines/reference/extractFunction/extractFunction13.ts b/tests/baselines/reference/extractFunction/extractFunction13.ts index 4987039d5da..662701ebf41 100644 --- a/tests/baselines/reference/extractFunction/extractFunction13.ts +++ b/tests/baselines/reference/extractFunction/extractFunction13.ts @@ -20,7 +20,7 @@ (u2a: U2a, u2b: U2b) => { function F2(t2a: T2a, t2b: T2b) { (u3a: U3a, u3b: U3b) => { - /*RENAME*/newFunction(u3a); + /*RENAME*/newFunction(u3a); } function newFunction(u3a: U3a) { @@ -40,7 +40,7 @@ (u2a: U2a, u2b: U2b) => { function F2(t2a: T2a, t2b: T2b) { (u3a: U3a, u3b: U3b) => { - /*RENAME*/newFunction(t2a, u2a, u3a); + /*RENAME*/newFunction(t2a, u2a, u3a); } } } @@ -60,7 +60,7 @@ (u2a: U2a, u2b: U2b) => { function F2(t2a: T2a, t2b: T2b) { (u3a: U3a, u3b: U3b) => { - /*RENAME*/newFunction(t1a, t2a, u1a, u2a, u3a); + /*RENAME*/newFunction(t1a, t2a, u1a, u2a, u3a); } } } diff --git a/tests/baselines/reference/extractFunction/extractFunction_PreserveTrivia.js b/tests/baselines/reference/extractFunction/extractFunction_PreserveTrivia.js new file mode 100644 index 00000000000..b5e4bc76c6e --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_PreserveTrivia.js @@ -0,0 +1,19 @@ +// ==ORIGINAL== + +// a +var q = /*b*/ //c + /*d*/ /*[#|*/1 /*e*/ //f + /*g*/ + /*h*/ //i + /*j*/ 2/*|]*/ /*k*/ //l + /*m*/; /*n*/ //o +// ==SCOPE::Extract to function in global scope== + +// a +var q = /*b*/ //c + /*d*/ /*RENAME*/newFunction() /*k*/ //l + /*m*/; /*n*/ //o +function newFunction() { + return 1 /*e*/ //f + /*g*/ + /*h*/ //i + /*j*/ 2; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_PreserveTrivia.ts b/tests/baselines/reference/extractFunction/extractFunction_PreserveTrivia.ts new file mode 100644 index 00000000000..b5e4bc76c6e --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_PreserveTrivia.ts @@ -0,0 +1,19 @@ +// ==ORIGINAL== + +// a +var q = /*b*/ //c + /*d*/ /*[#|*/1 /*e*/ //f + /*g*/ + /*h*/ //i + /*j*/ 2/*|]*/ /*k*/ //l + /*m*/; /*n*/ //o +// ==SCOPE::Extract to function in global scope== + +// a +var q = /*b*/ //c + /*d*/ /*RENAME*/newFunction() /*k*/ //l + /*m*/; /*n*/ //o +function newFunction() { + return 1 /*e*/ //f + /*g*/ + /*h*/ //i + /*j*/ 2; +} diff --git a/tests/cases/fourslash/extract-method-uniqueName.ts b/tests/cases/fourslash/extract-method-uniqueName.ts index 4271d9e84d2..da4c68cfb7e 100644 --- a/tests/cases/fourslash/extract-method-uniqueName.ts +++ b/tests/cases/fourslash/extract-method-uniqueName.ts @@ -11,10 +11,9 @@ edit.applyRefactor({ actionName: "function_scope_0", actionDescription: "Extract to function in global scope", newContent: -`/*RENAME*/newFunction_1(); - +`// newFunction +/*RENAME*/newFunction_1(); function newFunction_1() { - // newFunction 1 + 1; } ` From 123347d5c42390068325590f348b4e7be3b78f87 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 12 Oct 2017 11:40:07 -0700 Subject: [PATCH 119/312] Convert @template tag to type parameters in refactor --- src/compiler/utilities.ts | 16 ++++++------ .../refactors/annotateWithTypeFromJSDoc.ts | 25 ++++++++++--------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 2c1e25f74af..c4d3de453ba 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2700,11 +2700,11 @@ namespace ts { * Gets the effective type annotation of a variable, parameter, or property. If the node was * parsed in a JavaScript file, gets the type annotation from JSDoc. */ - export function getEffectiveTypeAnnotationNode(node: VariableLikeDeclaration): TypeNode | undefined { + export function getEffectiveTypeAnnotationNode(node: VariableLikeDeclaration, checkJSDoc?: boolean): TypeNode | undefined { if (node.type) { return node.type; } - if (isInJavaScriptFile(node)) { + if (checkJSDoc || isInJavaScriptFile(node)) { return getJSDocType(node); } } @@ -2713,11 +2713,11 @@ namespace ts { * Gets the effective return type annotation of a signature. If the node was parsed in a * JavaScript file, gets the return type annotation from JSDoc. */ - export function getEffectiveReturnTypeNode(node: SignatureDeclaration): TypeNode | undefined { + export function getEffectiveReturnTypeNode(node: SignatureDeclaration, checkJSDoc?: boolean): TypeNode | undefined { if (node.type) { return node.type; } - if (isInJavaScriptFile(node)) { + if (checkJSDoc || isInJavaScriptFile(node)) { return getJSDocReturnType(node); } } @@ -2726,11 +2726,11 @@ namespace ts { * Gets the effective type parameters. If the node was parsed in a * JavaScript file, gets the type parameters from the `@template` tag from JSDoc. */ - export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray { + export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters, checkJSDoc?: boolean): ReadonlyArray { if (node.typeParameters) { return node.typeParameters; } - if (isInJavaScriptFile(node)) { + if (checkJSDoc || isInJavaScriptFile(node)) { const templateTag = getJSDocTemplateTag(node); return templateTag && templateTag.typeParameters; } @@ -2740,9 +2740,9 @@ namespace ts { * Gets the effective type annotation of the value parameter of a set accessor. If the node * was parsed in a JavaScript file, gets the type annotation from JSDoc. */ - export function getEffectiveSetAccessorTypeAnnotationNode(node: SetAccessorDeclaration): TypeNode { + export function getEffectiveSetAccessorTypeAnnotationNode(node: SetAccessorDeclaration, checkJSDoc?: boolean): TypeNode { const parameter = getSetAccessorValueParameter(node); - return parameter && getEffectiveTypeAnnotationNode(parameter); + return parameter && getEffectiveTypeAnnotationNode(parameter, checkJSDoc); } export function emitNewLineBeforeLeadingComments(lineMap: ReadonlyArray, writer: EmitTextWriter, node: TextRange, leadingComments: ReadonlyArray) { diff --git a/src/services/refactors/annotateWithTypeFromJSDoc.ts b/src/services/refactors/annotateWithTypeFromJSDoc.ts index 529793b7cd1..bc6dcd073bf 100644 --- a/src/services/refactors/annotateWithTypeFromJSDoc.ts +++ b/src/services/refactors/annotateWithTypeFromJSDoc.ts @@ -31,11 +31,11 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { } const node = getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false); - const decl = findAncestor(node, isTypedNode); + const decl = findAncestor(node, isDeclarationWithType); if (decl && !decl.type) { const type = getJSDocType(decl); - const returnType = getJSDocReturnType(decl); - const annotate = (returnType || type && decl.kind === SyntaxKind.Parameter) ? annotateFunctionFromJSDoc : + const isFunctionWithJSDoc = isFunctionLikeDeclaration(decl) && (getJSDocReturnType(decl) || decl.parameters.some(p => !!getJSDocType(p))); + const annotate = (isFunctionWithJSDoc || type && decl.kind === SyntaxKind.Parameter) ? annotateFunctionFromJSDoc : type ? annotateTypeFromJSDoc : undefined; if (annotate) { @@ -61,7 +61,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { const sourceFile = context.file; const token = getTokenAtPosition(sourceFile, context.startPosition, /*includeJsDocComment*/ false); - const decl = findAncestor(token, isTypedNode); + const decl = findAncestor(token, isDeclarationWithType); const jsdocType = getJSDocReturnType(decl) || getJSDocType(decl); if (!decl || !jsdocType || decl.type) { Debug.fail(`!decl || !jsdocType || decl.type: !${decl} || !${jsdocType} || ${decl.type}`); @@ -95,7 +95,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { }; } - function isTypedNode(node: Node): node is DeclarationWithType { + function isDeclarationWithType(node: Node): node is DeclarationWithType { return isFunctionLikeDeclaration(node) || node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.Parameter || @@ -104,22 +104,23 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { } function addTypesToFunctionLike(decl: FunctionLikeDeclaration) { - const returnType = decl.type || transformJSDocType(getJSDocReturnType(decl)) as TypeNode; + const typeParameters = getEffectiveTypeParameterDeclarations(decl, /*checkJSDoc*/ true); const parameters = decl.parameters.map( - p => createParameter(p.decorators, p.modifiers, p.dotDotDotToken, p.name, p.questionToken, p.type || transformJSDocType(getJSDocType(p)) as TypeNode, p.initializer)); + p => createParameter(p.decorators, p.modifiers, p.dotDotDotToken, p.name, p.questionToken, transformJSDocType(getEffectiveTypeAnnotationNode(p, /*checkJSDoc*/ true)) as TypeNode, p.initializer)); + const returnType = transformJSDocType(getEffectiveReturnTypeNode(decl, /*checkJSDoc*/ true)) as TypeNode; switch (decl.kind) { case SyntaxKind.FunctionDeclaration: - return createFunctionDeclaration(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.typeParameters, parameters, returnType, decl.body); + return createFunctionDeclaration(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, typeParameters, parameters, returnType, decl.body); case SyntaxKind.Constructor: return createConstructor(decl.decorators, decl.modifiers, parameters, decl.body); case SyntaxKind.FunctionExpression: - return createFunctionExpression(decl.modifiers, decl.asteriskToken, (decl as FunctionExpression).name, decl.typeParameters, parameters, returnType, decl.body); + return createFunctionExpression(decl.modifiers, decl.asteriskToken, (decl as FunctionExpression).name, typeParameters, parameters, returnType, decl.body); case SyntaxKind.ArrowFunction: - return createArrowFunction(decl.modifiers, decl.typeParameters, parameters, returnType, decl.equalsGreaterThanToken, decl.body); + return createArrowFunction(decl.modifiers, typeParameters, parameters, returnType, decl.equalsGreaterThanToken, decl.body); case SyntaxKind.MethodDeclaration: - return createMethod(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.questionToken, decl.typeParameters, parameters, returnType, decl.body); + return createMethod(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.questionToken, typeParameters, parameters, returnType, decl.body); case SyntaxKind.GetAccessor: - return createGetAccessor(decl.decorators, decl.modifiers, decl.name, parameters, returnType, decl.body); + return createGetAccessor(decl.decorators, decl.modifiers, decl.name, decl.parameters, returnType, decl.body); case SyntaxKind.SetAccessor: return createSetAccessor(decl.decorators, decl.modifiers, decl.name, parameters, decl.body); default: From b440d75bc427636211c46eb2b1140d51af34820a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 12 Oct 2017 11:40:40 -0700 Subject: [PATCH 120/312] Test refactor of JSDoc @template tag --- .../fourslash/annotateWithTypeFromJSDoc19.ts | 19 +++++++++++++++++++ .../fourslash/annotateWithTypeFromJSDoc20.ts | 17 +++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 tests/cases/fourslash/annotateWithTypeFromJSDoc19.ts create mode 100644 tests/cases/fourslash/annotateWithTypeFromJSDoc20.ts diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc19.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc19.ts new file mode 100644 index 00000000000..9e7ef6d25fd --- /dev/null +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc19.ts @@ -0,0 +1,19 @@ +/// +// @strict: true +/////** +//// * @template T +//// * @param {number} a +//// * @param {T} b +//// */ +////function /*1*/f(a, b) { +////} + +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`/** + * @template T + * @param {number} a + * @param {T} b + */ +function f(a: number, b: T) { +}`, 'Annotate with types from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc20.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc20.ts new file mode 100644 index 00000000000..a45eb788c73 --- /dev/null +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc20.ts @@ -0,0 +1,17 @@ +/// +// @strict: true +/////** +//// * @param {number} a +//// * @param {T} b +//// */ +////function /*1*/f(a, b) { +////} + +verify.applicableRefactorAvailableAtMarker('1'); +verify.fileAfterApplyingRefactorAtMarker('1', +`/** + * @param {number} a + * @param {T} b + */ +function f(a: number, b: T) { +}`, 'Annotate with types from JSDoc', 'annotate'); From 412e31b8bc99472c17641bb12f65efd349a93cb8 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 11 Oct 2017 17:10:45 -0700 Subject: [PATCH 121/312] Adding test case where opened file included in project is not added to ref count of configured project --- .../unittests/tsserverProjectSystem.ts | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 236f52db134..40eef501e52 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -335,6 +335,10 @@ namespace ts.projectSystem { return countWhere(recursiveWatchedDirs, dir => file.length > dir.length && startsWith(file, dir) && file[dir.length] === directorySeparator); } + function checkOpenFiles(projectService: server.ProjectService, expectedFiles: FileOrFolder[]) { + checkFileNames("Open files", projectService.openFiles.map(info => info.fileName), expectedFiles.map(file => file.path)); + } + /** * Test server cancellation token used to mock host token cancellation requests. * The cancelAfterRequest constructor param specifies how many isCancellationRequested() calls @@ -2109,6 +2113,90 @@ namespace ts.projectSystem { assert.equal(project1.openRefCount, 1, "Open ref count in project1 - 5"); }); + it("Open ref of configured project when open file gets added to the project as part of configured file update", () => { + const file1 = { + path: "/a/b/src/file1.ts", + content: "let x = 1;" + }; + const file2 = { + path: "/a/b/src/file2.ts", + content: "let y = 1;" + }; + const file3 = { + path: "/a/b/file3.ts", + content: "let z = 1;" + }; + const file4 = { + path: "/a/file4.ts", + content: "let z = 1;" + }; + const configFile = { + path: "/a/b/tsconfig.json", + content: JSON.stringify({ files: ["src/file1.ts", "file3.ts"] }) + }; + + const files = [file1, file2, file3, file4]; + const host = createServerHost(files.concat(configFile)); + const projectService = createProjectService(host); + + projectService.openClientFile(file1.path); + projectService.openClientFile(file2.path); + projectService.openClientFile(file3.path); + projectService.openClientFile(file4.path); + + const infos = files.map(file => projectService.getScriptInfoForPath(file.path as Path)); + checkOpenFiles(projectService, files); + checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 }); + const configProject1 = projectService.configuredProjects.get(configFile.path); + assert.equal(configProject1.openRefCount, 2); + checkProjectActualFiles(configProject1, [file1.path, file3.path, configFile.path]); + const inferredProject1 = projectService.inferredProjects[0]; + checkProjectActualFiles(inferredProject1, [file2.path]); + const inferredProject2 = projectService.inferredProjects[1]; + checkProjectActualFiles(inferredProject2, [file4.path]); + + configFile.content = "{}"; + host.reloadFS(files.concat(configFile)); + host.runQueuedTimeoutCallbacks(); + + verifyScriptInfos(); + checkOpenFiles(projectService, files); + verifyConfiguredProjectStateAfterUpdate(3); + checkNumberOfInferredProjects(projectService, 1); + const inferredProject3 = projectService.inferredProjects[0]; + checkProjectActualFiles(inferredProject3, [file4.path]); + assert.strictEqual(inferredProject2, inferredProject3); + + projectService.closeClientFile(file1.path); + projectService.closeClientFile(file2.path); + projectService.closeClientFile(file4.path); + + verifyScriptInfos(); + checkOpenFiles(projectService, [file3]); + verifyConfiguredProjectStateAfterUpdate(1); + checkNumberOfInferredProjects(projectService, 0); + + projectService.openClientFile(file4.path); + //verifyScriptInfos(); + checkOpenFiles(projectService, [file3, file4]); + //verifyConfiguredProjectStateAfterUpdate(1); + checkNumberOfInferredProjects(projectService, 1); + const inferredProject4 = projectService.inferredProjects[0]; + checkProjectActualFiles(inferredProject4, [file4.path]); + + function verifyScriptInfos() { + infos.forEach(info => assert.strictEqual(projectService.getScriptInfoForPath(info.path), info)); + } + + function verifyConfiguredProjectStateAfterUpdate(_openRefCount: number) { + checkNumberOfConfiguredProjects(projectService, 1); + const configProject2 = projectService.configuredProjects.get(configFile.path); + assert.strictEqual(configProject1, configProject2); + checkProjectActualFiles(configProject2, [file1.path, file2.path, file3.path, configFile.path]); + //assert.equal(configProject2.openRefCount, openRefCount); + } + }); + it("language service disabled state is updated in external projects", () => { const f1 = { path: "/a/app.js", From b68a6363480409067e244da35b1372868947e17b Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 12 Oct 2017 11:48:25 -0700 Subject: [PATCH 122/312] Fix the way configured project's reference is managed so that the open file --- .../unittests/tsserverProjectSystem.ts | 186 +++++++++++++++--- src/server/editorServices.ts | 55 +++--- src/server/project.ts | 48 +++-- .../reference/api/tsserverlibrary.d.ts | 10 +- 4 files changed, 224 insertions(+), 75 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 40eef501e52..dfed47084e0 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1053,16 +1053,19 @@ namespace ts.projectSystem { projectService.openClientFile(file1.path); checkNumberOfConfiguredProjects(projectService, 1); const project = projectService.configuredProjects.get(configFile.path); + assert.isTrue(project.hasOpenRef()); // file1 projectService.closeClientFile(file1.path); checkNumberOfConfiguredProjects(projectService, 1); assert.strictEqual(projectService.configuredProjects.get(configFile.path), project); - assert.equal(project.openRefCount, 0); + assert.isFalse(project.hasOpenRef()); // No open files + assert.isFalse(project.isClosed()); projectService.openClientFile(file2.path); checkNumberOfConfiguredProjects(projectService, 1); assert.strictEqual(projectService.configuredProjects.get(configFile.path), project); - assert.equal(project.openRefCount, 1); + assert.isTrue(project.hasOpenRef()); // file2 + assert.isFalse(project.isClosed()); }); it("should not close configured project after closing last open file, but should be closed on next file open if its not the file from same project", () => { @@ -1084,14 +1087,18 @@ namespace ts.projectSystem { projectService.openClientFile(file1.path); checkNumberOfConfiguredProjects(projectService, 1); const project = projectService.configuredProjects.get(configFile.path); + assert.isTrue(project.hasOpenRef()); // file1 projectService.closeClientFile(file1.path); checkNumberOfConfiguredProjects(projectService, 1); assert.strictEqual(projectService.configuredProjects.get(configFile.path), project); - assert.equal(project.openRefCount, 0); + assert.isFalse(project.hasOpenRef()); // No files + assert.isFalse(project.isClosed()); projectService.openClientFile(libFile.path); checkNumberOfConfiguredProjects(projectService, 0); + assert.isFalse(project.hasOpenRef()); // No files + project closed + assert.isTrue(project.isClosed()); }); it("should not close external project with no open files", () => { @@ -2078,55 +2085,64 @@ namespace ts.projectSystem { projectService.openClientFile(file2.path); checkNumberOfProjects(projectService, { configuredProjects: 1 }); const project1 = projectService.configuredProjects.get(tsconfig1.path); - assert.equal(project1.openRefCount, 1, "Open ref count in project1 - 1"); + assert.isTrue(project1.hasOpenRef(), "Has open ref count in project1 - 1"); // file2 assert.equal(project1.getScriptInfo(file2.path).containingProjects.length, 1, "containing projects count"); + assert.isFalse(project1.isClosed()); projectService.openClientFile(file1.path); checkNumberOfProjects(projectService, { configuredProjects: 2 }); - assert.equal(project1.openRefCount, 2, "Open ref count in project1 - 2"); + assert.isTrue(project1.hasOpenRef(), "Has open ref count in project1 - 2"); // file2 assert.strictEqual(projectService.configuredProjects.get(tsconfig1.path), project1); + assert.isFalse(project1.isClosed()); const project2 = projectService.configuredProjects.get(tsconfig2.path); - assert.equal(project2.openRefCount, 1, "Open ref count in project2 - 2"); + assert.isTrue(project2.hasOpenRef(), "Has open ref count in project2 - 2"); // file1 + assert.isFalse(project2.isClosed()); assert.equal(project1.getScriptInfo(file1.path).containingProjects.length, 2, `${file1.path} containing projects count`); assert.equal(project1.getScriptInfo(file2.path).containingProjects.length, 1, `${file2.path} containing projects count`); projectService.closeClientFile(file2.path); checkNumberOfProjects(projectService, { configuredProjects: 2 }); - assert.equal(project1.openRefCount, 1, "Open ref count in project1 - 3"); - assert.equal(project2.openRefCount, 1, "Open ref count in project2 - 3"); + assert.isFalse(project1.hasOpenRef(), "Has open ref count in project1 - 3"); // No files + assert.isTrue(project2.hasOpenRef(), "Has open ref count in project2 - 3"); // file1 assert.strictEqual(projectService.configuredProjects.get(tsconfig1.path), project1); assert.strictEqual(projectService.configuredProjects.get(tsconfig2.path), project2); + assert.isFalse(project1.isClosed()); + assert.isFalse(project2.isClosed()); projectService.closeClientFile(file1.path); checkNumberOfProjects(projectService, { configuredProjects: 2 }); - assert.equal(project1.openRefCount, 0, "Open ref count in project1 - 4"); - assert.equal(project2.openRefCount, 0, "Open ref count in project2 - 4"); + assert.isFalse(project1.hasOpenRef(), "Has open ref count in project1 - 4"); // No files + assert.isFalse(project2.hasOpenRef(), "Has open ref count in project2 - 4"); // No files assert.strictEqual(projectService.configuredProjects.get(tsconfig1.path), project1); assert.strictEqual(projectService.configuredProjects.get(tsconfig2.path), project2); + assert.isFalse(project1.isClosed()); + assert.isFalse(project2.isClosed()); projectService.openClientFile(file2.path); checkNumberOfProjects(projectService, { configuredProjects: 1 }); assert.strictEqual(projectService.configuredProjects.get(tsconfig1.path), project1); assert.isUndefined(projectService.configuredProjects.get(tsconfig2.path)); - assert.equal(project1.openRefCount, 1, "Open ref count in project1 - 5"); + assert.isTrue(project1.hasOpenRef(), "Has open ref count in project1 - 5"); // file2 + assert.isFalse(project1.isClosed()); + assert.isTrue(project2.isClosed()); }); it("Open ref of configured project when open file gets added to the project as part of configured file update", () => { - const file1 = { + const file1: FileOrFolder = { path: "/a/b/src/file1.ts", content: "let x = 1;" }; - const file2 = { + const file2: FileOrFolder = { path: "/a/b/src/file2.ts", content: "let y = 1;" }; - const file3 = { + const file3: FileOrFolder = { path: "/a/b/file3.ts", content: "let z = 1;" }; - const file4 = { + const file4: FileOrFolder = { path: "/a/file4.ts", content: "let z = 1;" }; @@ -2148,7 +2164,7 @@ namespace ts.projectSystem { checkOpenFiles(projectService, files); checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 }); const configProject1 = projectService.configuredProjects.get(configFile.path); - assert.equal(configProject1.openRefCount, 2); + assert.isTrue(configProject1.hasOpenRef()); // file1 and file3 checkProjectActualFiles(configProject1, [file1.path, file3.path, configFile.path]); const inferredProject1 = projectService.inferredProjects[0]; checkProjectActualFiles(inferredProject1, [file2.path]); @@ -2161,11 +2177,11 @@ namespace ts.projectSystem { verifyScriptInfos(); checkOpenFiles(projectService, files); - verifyConfiguredProjectStateAfterUpdate(3); + verifyConfiguredProjectStateAfterUpdate(/*hasOpenRef*/ true); // file1, file2, file3 checkNumberOfInferredProjects(projectService, 1); const inferredProject3 = projectService.inferredProjects[0]; checkProjectActualFiles(inferredProject3, [file4.path]); - assert.strictEqual(inferredProject2, inferredProject3); + assert.strictEqual(inferredProject3, inferredProject2); projectService.closeClientFile(file1.path); projectService.closeClientFile(file2.path); @@ -2173,30 +2189,122 @@ namespace ts.projectSystem { verifyScriptInfos(); checkOpenFiles(projectService, [file3]); - verifyConfiguredProjectStateAfterUpdate(1); + verifyConfiguredProjectStateAfterUpdate(/*hasOpenRef*/ true); // file3 checkNumberOfInferredProjects(projectService, 0); projectService.openClientFile(file4.path); - //verifyScriptInfos(); + verifyScriptInfos(); checkOpenFiles(projectService, [file3, file4]); - //verifyConfiguredProjectStateAfterUpdate(1); + verifyConfiguredProjectStateAfterUpdate(/*hasOpenRef*/ true); // file3 checkNumberOfInferredProjects(projectService, 1); const inferredProject4 = projectService.inferredProjects[0]; checkProjectActualFiles(inferredProject4, [file4.path]); + projectService.closeClientFile(file3.path); + verifyScriptInfos(); + checkOpenFiles(projectService, [file4]); + verifyConfiguredProjectStateAfterUpdate(/*hasOpenRef*/ false); // No open files + checkNumberOfInferredProjects(projectService, 1); + const inferredProject5 = projectService.inferredProjects[0]; + checkProjectActualFiles(inferredProject4, [file4.path]); + assert.strictEqual(inferredProject5, inferredProject4); + + const file5: FileOrFolder = { + path: "/file5.ts", + content: "let zz = 1;" + }; + host.reloadFS(files.concat(configFile, file5)); + projectService.openClientFile(file5.path); + verifyScriptInfosAreUndefined([file1, file2, file3]); + assert.strictEqual(projectService.getScriptInfoForPath(file4.path as Path), find(infos, info => info.path === file4.path)); + assert.isDefined(projectService.getScriptInfoForPath(file5.path as Path)); + checkOpenFiles(projectService, [file4, file5]); + checkNumberOfConfiguredProjects(projectService, 0); + function verifyScriptInfos() { infos.forEach(info => assert.strictEqual(projectService.getScriptInfoForPath(info.path), info)); } - function verifyConfiguredProjectStateAfterUpdate(_openRefCount: number) { + function verifyScriptInfosAreUndefined(files: FileOrFolder[]) { + for (const file of files) { + assert.isUndefined(projectService.getScriptInfoForPath(file.path as Path)); + } + } + + function verifyConfiguredProjectStateAfterUpdate(hasOpenRef: boolean) { checkNumberOfConfiguredProjects(projectService, 1); const configProject2 = projectService.configuredProjects.get(configFile.path); - assert.strictEqual(configProject1, configProject2); + assert.strictEqual(configProject2, configProject1); checkProjectActualFiles(configProject2, [file1.path, file2.path, file3.path, configFile.path]); - //assert.equal(configProject2.openRefCount, openRefCount); + assert.equal(configProject2.hasOpenRef(), hasOpenRef); } }); + it("Open ref of configured project when open file gets added to the project as part of configured file update buts its open file references are all closed when the update happens", () => { + const file1: FileOrFolder = { + path: "/a/b/src/file1.ts", + content: "let x = 1;" + }; + const file2: FileOrFolder = { + path: "/a/b/src/file2.ts", + content: "let y = 1;" + }; + const file3: FileOrFolder = { + path: "/a/b/file3.ts", + content: "let z = 1;" + }; + const file4: FileOrFolder = { + path: "/a/file4.ts", + content: "let z = 1;" + }; + const configFile = { + path: "/a/b/tsconfig.json", + content: JSON.stringify({ files: ["src/file1.ts", "file3.ts"] }) + }; + + const files = [file1, file2, file3]; + const hostFiles = files.concat(file4, configFile); + const host = createServerHost(hostFiles); + const projectService = createProjectService(host); + + projectService.openClientFile(file1.path); + projectService.openClientFile(file2.path); + projectService.openClientFile(file3.path); + + checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 }); + const configuredProject = projectService.configuredProjects.get(configFile.path); + assert.isTrue(configuredProject.hasOpenRef()); // file1 and file3 + checkProjectActualFiles(configuredProject, [file1.path, file3.path, configFile.path]); + const inferredProject1 = projectService.inferredProjects[0]; + checkProjectActualFiles(inferredProject1, [file2.path]); + + projectService.closeClientFile(file1.path); + projectService.closeClientFile(file3.path); + assert.isFalse(configuredProject.hasOpenRef()); // No files + + configFile.content = "{}"; + host.reloadFS(files.concat(configFile)); + // Time out is not yet run so there is project update pending + assert.isTrue(configuredProject.hasOpenRef()); // Pending update and file2 might get into the project + + projectService.openClientFile(file4.path); + + checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 }); + assert.strictEqual(projectService.configuredProjects.get(configFile.path), configuredProject); + assert.isTrue(configuredProject.hasOpenRef()); // Pending update and F2 might get into the project + assert.strictEqual(projectService.inferredProjects[0], inferredProject1); + const inferredProject2 = projectService.inferredProjects[1]; + checkProjectActualFiles(inferredProject2, [file4.path]); + + host.runQueuedTimeoutCallbacks(); + checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 }); + assert.strictEqual(projectService.configuredProjects.get(configFile.path), configuredProject); + assert.isTrue(configuredProject.hasOpenRef()); // file2 + checkProjectActualFiles(configuredProject, [file1.path, file2.path, file3.path, configFile.path]); + assert.strictEqual(projectService.inferredProjects[0], inferredProject2); + checkProjectActualFiles(inferredProject2, [file4.path]); + }); + it("language service disabled state is updated in external projects", () => { const f1 = { path: "/a/app.js", @@ -2265,18 +2373,36 @@ namespace ts.projectSystem { projectService.openClientFile(f1.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); const project = projectService.configuredProjects.get(config.path); + assert.isTrue(project.hasOpenRef()); // f1 + assert.isFalse(project.isClosed()); projectService.closeClientFile(f1.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); assert.strictEqual(projectService.configuredProjects.get(config.path), project); - assert.equal(project.openRefCount, 0); + assert.isFalse(project.hasOpenRef()); // No files + assert.isFalse(project.isClosed()); for (const f of [f1, f2, f3]) { - // There shouldnt be any script info as we closed the file that resulted in creation of it + // All the script infos should be present and contain the project since it is still alive. const scriptInfo = projectService.getScriptInfoForNormalizedPath(server.toNormalizedPath(f.path)); assert.equal(scriptInfo.containingProjects.length, 1, `expect 1 containing projects for '${f.path}'`); assert.equal(scriptInfo.containingProjects[0], project, `expect configured project to be the only containing project for '${f.path}'`); } + + const f4 = { + path: "/aa.js", + content: "var x = 1" + }; + host.reloadFS([f1, f2, f3, config, f4]); + projectService.openClientFile(f4.path); + projectService.checkNumberOfProjects({ inferredProjects: 1 }); + assert.isFalse(project.hasOpenRef()); // No files + assert.isTrue(project.isClosed()); + + for (const f of [f1, f2, f3]) { + // All the script infos should not be present since the project is closed and orphan script infos are collected + assert.isUndefined(projectService.getScriptInfoForNormalizedPath(server.toNormalizedPath(f.path))); + } }); it("language service disabled events are triggered", () => { @@ -2910,17 +3036,19 @@ namespace ts.projectSystem { projectService.openClientFile(f.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); const project = projectService.configuredProjects.get(config.path); - assert.equal(project.openRefCount, 1); + assert.isTrue(project.hasOpenRef()); // f projectService.closeClientFile(f.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); assert.strictEqual(projectService.configuredProjects.get(config.path), project); - assert.equal(project.openRefCount, 0); + assert.isFalse(project.hasOpenRef()); // No files + assert.isFalse(project.isClosed()); projectService.openClientFile(f.path); projectService.checkNumberOfProjects({ configuredProjects: 1 }); assert.strictEqual(projectService.configuredProjects.get(config.path), project); - assert.equal(project.openRefCount, 1); + assert.isTrue(project.hasOpenRef()); // f + assert.isFalse(project.isClosed()); }); }); diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 70598313a73..a017ac5e45e 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -554,6 +554,11 @@ namespace ts.server { }); } + /*@internal*/ + hasPendingProjectUpdate(project: Project) { + return this.pendingProjectUpdates.has(project.getProjectName()); + } + private sendProjectsUpdatedInBackgroundEvent() { if (!this.eventHandler) { return; @@ -795,8 +800,14 @@ namespace ts.server { ); } + /** Gets the config file existence info for the configured project */ + /*@internal*/ + getConfigFileExistenceInfo(project: ConfiguredProject) { + return this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath); + } + private onConfigChangedForConfiguredProject(project: ConfiguredProject, eventKind: FileWatcherEventKind) { - const configFileExistenceInfo = this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath); + const configFileExistenceInfo = this.getConfigFileExistenceInfo(project); if (eventKind === FileWatcherEventKind.Deleted) { // Update the cached status // We arent updating or removing the cached config file presence info as that will be taken care of by @@ -898,18 +909,6 @@ namespace ts.server { return project; } - private addToListOfOpenFiles(info: ScriptInfo) { - Debug.assert(!info.isOrphan()); - for (const p of info.containingProjects) { - // file is the part of configured project, addref the project - if (p.projectKind === ProjectKind.Configured) { - ((p)).addOpenRef(); - } - } - - this.openFiles.push(info); - } - /** * Remove this file from the set of open, non-configured files. * @param info The file that has been closed or newly configured @@ -932,10 +931,8 @@ namespace ts.server { if (info.hasMixedContent) { info.registerFileUpdate(); } - // Delete the reference to the open configured projects but - // do not remove the project so that we can reuse this project + // Do not remove the project so that we can reuse this project // if it would need to be re-created with next file open - (p).deleteOpenRef(); } else if (p.projectKind === ProjectKind.Inferred && p.isRoot(info)) { // If this was the open root file of inferred project @@ -1025,7 +1022,7 @@ namespace ts.server { } private setConfigFileExistenceByNewConfiguredProject(project: ConfiguredProject) { - const configFileExistenceInfo = this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath); + const configFileExistenceInfo = this.getConfigFileExistenceInfo(project); if (configFileExistenceInfo) { Debug.assert(configFileExistenceInfo.exists); // close existing watcher @@ -1054,7 +1051,7 @@ namespace ts.server { } private setConfigFileExistenceInfoByClosedConfiguredProject(closedProject: ConfiguredProject) { - const configFileExistenceInfo = this.configFileExistenceInfoCache.get(closedProject.canonicalConfigFilePath); + const configFileExistenceInfo = this.getConfigFileExistenceInfo(closedProject); Debug.assert(!!configFileExistenceInfo); if (configFileExistenceInfo.openFilesImpactedByConfigFile.size) { const configFileName = closedProject.getConfigFilePath(); @@ -1943,7 +1940,8 @@ namespace ts.server { this.assignOrphanScriptInfoToInferredProject(info, projectRootPath); } - this.addToListOfOpenFiles(info); + Debug.assert(!info.isOrphan()); + this.openFiles.push(info); if (sendConfigFileDiagEvent) { configFileErrors = project.getAllProjectErrors(); @@ -2043,11 +2041,14 @@ namespace ts.server { } } - private closeConfiguredProject(configFile: NormalizedPath): boolean { + private closeConfiguredProjectReferencedFromExternalProject(configFile: NormalizedPath): boolean { const configuredProject = this.findConfiguredProjectByProjectName(configFile); - if (configuredProject && configuredProject.deleteOpenRef() === 0) { - this.removeProject(configuredProject); - return true; + if (configuredProject) { + configuredProject.deleteExternalProjectReference(); + if (!configuredProject.hasOpenRef()) { + this.removeProject(configuredProject); + return true; + } } return false; } @@ -2058,7 +2059,7 @@ namespace ts.server { if (configFiles) { let shouldRefreshInferredProjects = false; for (const configFile of configFiles) { - if (this.closeConfiguredProject(configFile)) { + if (this.closeConfiguredProjectReferencedFromExternalProject(configFile)) { shouldRefreshInferredProjects = true; } } @@ -2253,7 +2254,7 @@ namespace ts.server { const newConfig = tsConfigFiles[iNew]; const oldConfig = oldConfigFiles[iOld]; if (oldConfig < newConfig) { - this.closeConfiguredProject(oldConfig); + this.closeConfiguredProjectReferencedFromExternalProject(oldConfig); iOld++; } else if (oldConfig > newConfig) { @@ -2268,7 +2269,7 @@ namespace ts.server { } for (let i = iOld; i < oldConfigFiles.length; i++) { // projects for all remaining old config files should be closed - this.closeConfiguredProject(oldConfigFiles[i]); + this.closeConfiguredProjectReferencedFromExternalProject(oldConfigFiles[i]); } } } @@ -2283,7 +2284,7 @@ namespace ts.server { } if (project && !contains(exisingConfigFiles, tsconfigFile)) { // keep project alive even if no documents are opened - its lifetime is bound to the lifetime of containing external project - project.addOpenRef(); + project.addExternalProjectReference(); } } } diff --git a/src/server/project.ts b/src/server/project.ts index 7653fbf93cf..395da1bd643 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -892,9 +892,7 @@ namespace ts.server { } getScriptInfoForNormalizedPath(fileName: NormalizedPath) { - const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath( - fileName, /*scriptKind*/ undefined, /*hasMixedContent*/ undefined, this.directoryStructureHost - ); + const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(fileName); if (scriptInfo && !scriptInfo.isAttached(this)) { return Errors.ThrowProjectDoesNotContainDocument(fileName, this); } @@ -902,7 +900,7 @@ namespace ts.server { } getScriptInfo(uncheckedFileName: string) { - return this.getScriptInfoForNormalizedPath(toNormalizedPath(uncheckedFileName)); + return this.projectService.getScriptInfo(uncheckedFileName); } filesToString(writeProjectFileNames: boolean) { @@ -1130,8 +1128,8 @@ namespace ts.server { private plugins: PluginModule[] = []; - /** Used for configured projects which may have multiple open roots */ - openRefCount = 0; + /** Ref count to the project when opened from external project */ + private externalProjectRefCount = 0; private projectErrors: Diagnostic[]; @@ -1342,17 +1340,43 @@ namespace ts.server { super.close(); } - addOpenRef() { - this.openRefCount++; + /* @internal */ + addExternalProjectReference() { + this.externalProjectRefCount++; } - deleteOpenRef() { - this.openRefCount--; - return this.openRefCount; + /* @internal */ + deleteExternalProjectReference() { + this.externalProjectRefCount--; } + /** Returns true if the project is needed by any of the open script info/external project */ + /* @internal */ hasOpenRef() { - return !!this.openRefCount; + if (!!this.externalProjectRefCount) { + return true; + } + + // Closed project doesnt have any reference + if (this.isClosed()) { + return false; + } + + const configFileExistenceInfo = this.projectService.getConfigFileExistenceInfo(this); + if (this.projectService.hasPendingProjectUpdate(this)) { + // If there is pending update for this project, + // we dont know if this project would be needed by any of the open files impacted by this config file + // In that case keep the project alive if there are open files impacted by this project + return !!configFileExistenceInfo.openFilesImpactedByConfigFile.size; + } + + // If there is no pending update for this project, + // We know exact set of open files that get impacted by this configured project as the files in the project + // The project is referenced only if open files impacted by this project are present in this project + return forEachEntry( + configFileExistenceInfo.openFilesImpactedByConfigFile, + (_value, infoPath) => this.containsScriptInfo(this.projectService.getScriptInfoForPath(infoPath as Path)) + ) || false; } getEffectiveTypeRoots() { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 151c948602d..204c718fabd 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7211,8 +7211,8 @@ declare namespace ts.server { private directoriesWatchedForWildcards; readonly canonicalConfigFilePath: NormalizedPath; private plugins; - /** Used for configured projects which may have multiple open roots */ - openRefCount: number; + /** Ref count to the project when opened from external project */ + private externalProjectRefCount; private projectErrors; /** * If the project has reload from disk pending, it reloads (and then updates graph as part of that) instead of just updating the graph @@ -7236,9 +7236,6 @@ declare namespace ts.server { getTypeAcquisition(): TypeAcquisition; getExternalFiles(): SortedReadonlyArray; close(): void; - addOpenRef(): void; - deleteOpenRef(): number; - hasOpenRef(): boolean; getEffectiveTypeRoots(): string[]; } /** @@ -7468,7 +7465,6 @@ declare namespace ts.server { */ private onConfigFileChangeForOpenScriptInfo(configFileName, eventKind); private removeProject(project); - private addToListOfOpenFiles(info); /** * Remove this file from the set of open, non-configured files. * @param info The file that has been closed or newly configured @@ -7576,7 +7572,7 @@ declare namespace ts.server { */ closeClientFile(uncheckedFileName: string): void; private collectChanges(lastKnownProjectVersions, currentProjects, result); - private closeConfiguredProject(configFile); + private closeConfiguredProjectReferencedFromExternalProject(configFile); closeExternalProject(uncheckedFileName: string, suppressRefresh?: boolean): void; openExternalProjects(projects: protocol.ExternalProject[]): void; /** Makes a filename safe to insert in a RegExp */ From 9af21eb00eb957240159745c181077e21df9da17 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 12 Oct 2017 12:53:12 -0700 Subject: [PATCH 123/312] Transform nested dynamic imports (#18998) * Fix nested dynamic imports when targeting es6 * Fixup nested dynamic imports when targeting downlevel * Remove duplicated expressions in UMD emit * Code review feedback, clone arg if need be * More CR feedback, apply user quotemark styles * Remove blank lines * Use behavior of visitEachChild instead of enw codepath, add new test, use createLiteral to retain quotemarks * Set lib flag for test --- src/compiler/transformers/generators.ts | 3 +- src/compiler/transformers/module/module.ts | 46 ++++++---- src/compiler/transformers/module/system.ts | 2 +- src/compiler/transformers/utilities.ts | 13 +++ .../reference/asyncImportNestedYield.js | 58 +++++++++++++ .../reference/asyncImportNestedYield.symbols | 6 ++ .../reference/asyncImportNestedYield.types | 14 ++++ .../dynamicImportWithNestedThis_es2015.js | 3 +- .../dynamicImportWithNestedThis_es5.js | 3 +- .../importCallExpressionGrammarError.js | 2 +- .../importCallExpressionNestedAMD.js | 33 ++++++++ .../importCallExpressionNestedAMD.symbols | 12 +++ .../importCallExpressionNestedAMD.types | 17 ++++ .../importCallExpressionNestedAMD2.js | 66 +++++++++++++++ .../importCallExpressionNestedAMD2.symbols | 12 +++ .../importCallExpressionNestedAMD2.types | 17 ++++ .../importCallExpressionNestedCJS.js | 28 +++++++ .../importCallExpressionNestedCJS.symbols | 12 +++ .../importCallExpressionNestedCJS.types | 17 ++++ .../importCallExpressionNestedCJS2.js | 61 ++++++++++++++ .../importCallExpressionNestedCJS2.symbols | 12 +++ .../importCallExpressionNestedCJS2.types | 17 ++++ ...mportCallExpressionNestedES2015.errors.txt | 15 ++++ .../importCallExpressionNestedES2015.js | 26 ++++++ .../importCallExpressionNestedES2015.symbols | 12 +++ .../importCallExpressionNestedES2015.types | 17 ++++ ...portCallExpressionNestedES20152.errors.txt | 15 ++++ .../importCallExpressionNestedES20152.js | 59 +++++++++++++ .../importCallExpressionNestedES20152.symbols | 12 +++ .../importCallExpressionNestedES20152.types | 17 ++++ .../importCallExpressionNestedESNext.js | 26 ++++++ .../importCallExpressionNestedESNext.symbols | 12 +++ .../importCallExpressionNestedESNext.types | 17 ++++ .../importCallExpressionNestedESNext2.js | 59 +++++++++++++ .../importCallExpressionNestedESNext2.symbols | 12 +++ .../importCallExpressionNestedESNext2.types | 17 ++++ .../importCallExpressionNestedSystem.js | 43 ++++++++++ .../importCallExpressionNestedSystem.symbols | 12 +++ .../importCallExpressionNestedSystem.types | 17 ++++ .../importCallExpressionNestedSystem2.js | 76 +++++++++++++++++ .../importCallExpressionNestedSystem2.symbols | 12 +++ .../importCallExpressionNestedSystem2.types | 17 ++++ .../importCallExpressionNestedUMD.js | 51 +++++++++++ .../importCallExpressionNestedUMD.symbols | 12 +++ .../importCallExpressionNestedUMD.types | 17 ++++ .../importCallExpressionNestedUMD2.js | 84 +++++++++++++++++++ .../importCallExpressionNestedUMD2.symbols | 12 +++ .../importCallExpressionNestedUMD2.types | 17 ++++ .../cases/compiler/asyncImportNestedYield.ts | 4 + .../importCallExpressionNestedAMD.ts | 11 +++ .../importCallExpressionNestedAMD2.ts | 11 +++ .../importCallExpressionNestedCJS.ts | 11 +++ .../importCallExpressionNestedCJS2.ts | 11 +++ .../importCallExpressionNestedES2015.ts | 11 +++ .../importCallExpressionNestedES20152.ts | 11 +++ .../importCallExpressionNestedESNext.ts | 11 +++ .../importCallExpressionNestedESNext2.ts | 11 +++ .../importCallExpressionNestedSystem.ts | 11 +++ .../importCallExpressionNestedSystem2.ts | 11 +++ .../importCallExpressionNestedUMD.ts | 11 +++ .../importCallExpressionNestedUMD2.ts | 11 +++ 61 files changed, 1254 insertions(+), 22 deletions(-) create mode 100644 tests/baselines/reference/asyncImportNestedYield.js create mode 100644 tests/baselines/reference/asyncImportNestedYield.symbols create mode 100644 tests/baselines/reference/asyncImportNestedYield.types create mode 100644 tests/baselines/reference/importCallExpressionNestedAMD.js create mode 100644 tests/baselines/reference/importCallExpressionNestedAMD.symbols create mode 100644 tests/baselines/reference/importCallExpressionNestedAMD.types create mode 100644 tests/baselines/reference/importCallExpressionNestedAMD2.js create mode 100644 tests/baselines/reference/importCallExpressionNestedAMD2.symbols create mode 100644 tests/baselines/reference/importCallExpressionNestedAMD2.types create mode 100644 tests/baselines/reference/importCallExpressionNestedCJS.js create mode 100644 tests/baselines/reference/importCallExpressionNestedCJS.symbols create mode 100644 tests/baselines/reference/importCallExpressionNestedCJS.types create mode 100644 tests/baselines/reference/importCallExpressionNestedCJS2.js create mode 100644 tests/baselines/reference/importCallExpressionNestedCJS2.symbols create mode 100644 tests/baselines/reference/importCallExpressionNestedCJS2.types create mode 100644 tests/baselines/reference/importCallExpressionNestedES2015.errors.txt create mode 100644 tests/baselines/reference/importCallExpressionNestedES2015.js create mode 100644 tests/baselines/reference/importCallExpressionNestedES2015.symbols create mode 100644 tests/baselines/reference/importCallExpressionNestedES2015.types create mode 100644 tests/baselines/reference/importCallExpressionNestedES20152.errors.txt create mode 100644 tests/baselines/reference/importCallExpressionNestedES20152.js create mode 100644 tests/baselines/reference/importCallExpressionNestedES20152.symbols create mode 100644 tests/baselines/reference/importCallExpressionNestedES20152.types create mode 100644 tests/baselines/reference/importCallExpressionNestedESNext.js create mode 100644 tests/baselines/reference/importCallExpressionNestedESNext.symbols create mode 100644 tests/baselines/reference/importCallExpressionNestedESNext.types create mode 100644 tests/baselines/reference/importCallExpressionNestedESNext2.js create mode 100644 tests/baselines/reference/importCallExpressionNestedESNext2.symbols create mode 100644 tests/baselines/reference/importCallExpressionNestedESNext2.types create mode 100644 tests/baselines/reference/importCallExpressionNestedSystem.js create mode 100644 tests/baselines/reference/importCallExpressionNestedSystem.symbols create mode 100644 tests/baselines/reference/importCallExpressionNestedSystem.types create mode 100644 tests/baselines/reference/importCallExpressionNestedSystem2.js create mode 100644 tests/baselines/reference/importCallExpressionNestedSystem2.symbols create mode 100644 tests/baselines/reference/importCallExpressionNestedSystem2.types create mode 100644 tests/baselines/reference/importCallExpressionNestedUMD.js create mode 100644 tests/baselines/reference/importCallExpressionNestedUMD.symbols create mode 100644 tests/baselines/reference/importCallExpressionNestedUMD.types create mode 100644 tests/baselines/reference/importCallExpressionNestedUMD2.js create mode 100644 tests/baselines/reference/importCallExpressionNestedUMD2.symbols create mode 100644 tests/baselines/reference/importCallExpressionNestedUMD2.types create mode 100644 tests/cases/compiler/asyncImportNestedYield.ts create mode 100644 tests/cases/conformance/dynamicImport/importCallExpressionNestedAMD.ts create mode 100644 tests/cases/conformance/dynamicImport/importCallExpressionNestedAMD2.ts create mode 100644 tests/cases/conformance/dynamicImport/importCallExpressionNestedCJS.ts create mode 100644 tests/cases/conformance/dynamicImport/importCallExpressionNestedCJS2.ts create mode 100644 tests/cases/conformance/dynamicImport/importCallExpressionNestedES2015.ts create mode 100644 tests/cases/conformance/dynamicImport/importCallExpressionNestedES20152.ts create mode 100644 tests/cases/conformance/dynamicImport/importCallExpressionNestedESNext.ts create mode 100644 tests/cases/conformance/dynamicImport/importCallExpressionNestedESNext2.ts create mode 100644 tests/cases/conformance/dynamicImport/importCallExpressionNestedSystem.ts create mode 100644 tests/cases/conformance/dynamicImport/importCallExpressionNestedSystem2.ts create mode 100644 tests/cases/conformance/dynamicImport/importCallExpressionNestedUMD.ts create mode 100644 tests/cases/conformance/dynamicImport/importCallExpressionNestedUMD2.ts diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 84ed997a70e..7ede62b1540 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -1112,7 +1112,7 @@ namespace ts { } function visitCallExpression(node: CallExpression) { - if (forEach(node.arguments, containsYield)) { + if (!isImportCall(node) && forEach(node.arguments, containsYield)) { // [source] // a.b(1, yield, 2); // @@ -1123,7 +1123,6 @@ namespace ts { // .yield resumeLabel // .mark resumeLabel // _b.apply(_a, _c.concat([%sent%, 2])); - const { target, thisArg } = createCallBinding(node.expression, hoistVariableDeclaration, languageVersion, /*cacheIdentifiers*/ true); return setOriginalNode( createFunctionApply( diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index ba262bf2c59..bd360fdffe4 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -21,7 +21,8 @@ namespace ts { const { startLexicalEnvironment, - endLexicalEnvironment + endLexicalEnvironment, + hoistVariableDeclaration } = context; const compilerOptions = context.getCompilerOptions(); @@ -519,18 +520,20 @@ namespace ts { } function visitImportCallExpression(node: ImportCall): Expression { + const argument = visitNode(firstOrUndefined(node.arguments), importCallExpressionVisitor); + const containsLexicalThis = !!(node.transformFlags & TransformFlags.ContainsLexicalThis); switch (compilerOptions.module) { case ModuleKind.AMD: - return transformImportCallExpressionAMD(node); + return createImportCallExpressionAMD(argument, containsLexicalThis); case ModuleKind.UMD: - return transformImportCallExpressionUMD(node); + return createImportCallExpressionUMD(argument, containsLexicalThis); case ModuleKind.CommonJS: default: - return transformImportCallExpressionCommonJS(node); + return createImportCallExpressionCommonJS(argument, containsLexicalThis); } } - function transformImportCallExpressionUMD(node: ImportCall): Expression { + function createImportCallExpressionUMD(arg: Expression | undefined, containsLexicalThis: boolean): Expression { // (function (factory) { // ... (regular UMD) // } @@ -545,14 +548,25 @@ namespace ts { // : new Promise(function (_a, _b) { require([x], _a, _b); }); /*Amd Require*/ // }); needUMDDynamicImportHelper = true; - return createConditional( - /*condition*/ createIdentifier("__syncRequire"), - /*whenTrue*/ transformImportCallExpressionCommonJS(node), - /*whenFalse*/ transformImportCallExpressionAMD(node) - ); + if (isSimpleCopiableExpression(arg)) { + const argClone = isGeneratedIdentifier(arg) ? arg : isStringLiteral(arg) ? createLiteral(arg) : setEmitFlags(setTextRange(getSynthesizedClone(arg), arg), EmitFlags.NoComments); + return createConditional( + /*condition*/ createIdentifier("__syncRequire"), + /*whenTrue*/ createImportCallExpressionCommonJS(arg, containsLexicalThis), + /*whenFalse*/ createImportCallExpressionAMD(argClone, containsLexicalThis) + ); + } + else { + const temp = createTempVariable(hoistVariableDeclaration); + return createComma(createAssignment(temp, arg), createConditional( + /*condition*/ createIdentifier("__syncRequire"), + /*whenTrue*/ createImportCallExpressionCommonJS(temp, containsLexicalThis), + /*whenFalse*/ createImportCallExpressionAMD(temp, containsLexicalThis) + )); + } } - function transformImportCallExpressionAMD(node: ImportCall): Expression { + function createImportCallExpressionAMD(arg: Expression | undefined, containsLexicalThis: boolean): Expression { // improt("./blah") // emit as // define(["require", "exports", "blah"], function (require, exports) { @@ -570,7 +584,7 @@ namespace ts { createCall( createIdentifier("require"), /*typeArguments*/ undefined, - [createArrayLiteral([firstOrUndefined(node.arguments) || createOmittedExpression()]), resolve, reject] + [createArrayLiteral([arg || createOmittedExpression()]), resolve, reject] ) ) ]); @@ -598,7 +612,7 @@ namespace ts { // if there is a lexical 'this' in the import call arguments, ensure we indicate // that this new function expression indicates it captures 'this' so that the // es2015 transformer will properly substitute 'this' with '_this'. - if (node.transformFlags & TransformFlags.ContainsLexicalThis) { + if (containsLexicalThis) { setEmitFlags(func, EmitFlags.CapturesThis); } } @@ -606,14 +620,14 @@ namespace ts { return createNew(createIdentifier("Promise"), /*typeArguments*/ undefined, [func]); } - function transformImportCallExpressionCommonJS(node: ImportCall): Expression { + function createImportCallExpressionCommonJS(arg: Expression | undefined, containsLexicalThis: boolean): Expression { // import("./blah") // emit as // Promise.resolve().then(function () { return require(x); }) /*CommonJs Require*/ // We have to wrap require in then callback so that require is done in asynchronously // if we simply do require in resolve callback in Promise constructor. We will execute the loading immediately const promiseResolveCall = createCall(createPropertyAccess(createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []); - const requireCall = createCall(createIdentifier("require"), /*typeArguments*/ undefined, node.arguments); + const requireCall = createCall(createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []); let func: FunctionExpression | ArrowFunction; if (languageVersion >= ScriptTarget.ES2015) { @@ -638,7 +652,7 @@ namespace ts { // if there is a lexical 'this' in the import call arguments, ensure we indicate // that this new function expression indicates it captures 'this' so that the // es2015 transformer will properly substitute 'this' with '_this'. - if (node.transformFlags & TransformFlags.ContainsLexicalThis) { + if (containsLexicalThis) { setEmitFlags(func, EmitFlags.CapturesThis); } } diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index af77c499e8d..ed943eb90ce 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -1495,7 +1495,7 @@ namespace ts { createIdentifier("import") ), /*typeArguments*/ undefined, - node.arguments + some(node.arguments) ? [visitNode(node.arguments[0], destructuringAndImportCallVisitor)] : [] ); } diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 00a0753eaa1..a012c9be7db 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -178,4 +178,17 @@ namespace ts { } return values; } + + /** + * Used in the module transformer to check if an expression is reasonably without sideeffect, + * and thus better to copy into multiple places rather than to cache in a temporary variable + * - this is mostly subjective beyond the requirement that the expression not be sideeffecting + */ + export function isSimpleCopiableExpression(expression: Expression) { + return expression.kind === SyntaxKind.StringLiteral || + expression.kind === SyntaxKind.NumericLiteral || + expression.kind === SyntaxKind.NoSubstitutionTemplateLiteral || + isKeyword(expression.kind) || + isIdentifier(expression); + } } \ No newline at end of file diff --git a/tests/baselines/reference/asyncImportNestedYield.js b/tests/baselines/reference/asyncImportNestedYield.js new file mode 100644 index 00000000000..0dd76a13ace --- /dev/null +++ b/tests/baselines/reference/asyncImportNestedYield.js @@ -0,0 +1,58 @@ +//// [asyncImportNestedYield.ts] +async function* foo() { + import((await import(yield "foo")).default); +} + +//// [asyncImportNestedYield.js] +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } +var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; + function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } +}; +function foo() { + return __asyncGenerator(this, arguments, function foo_1() { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, "foo"]; + case 1: return [4 /*yield*/, __await.apply(void 0, [Promise.resolve().then(function () { return require(_a.sent()); })])]; + case 2: + Promise.resolve().then(function () { return require((_a.sent())["default"]); }); + return [2 /*return*/]; + } + }); + }); +} diff --git a/tests/baselines/reference/asyncImportNestedYield.symbols b/tests/baselines/reference/asyncImportNestedYield.symbols new file mode 100644 index 00000000000..01107ba5bf6 --- /dev/null +++ b/tests/baselines/reference/asyncImportNestedYield.symbols @@ -0,0 +1,6 @@ +=== tests/cases/compiler/asyncImportNestedYield.ts === +async function* foo() { +>foo : Symbol(foo, Decl(asyncImportNestedYield.ts, 0, 0)) + + import((await import(yield "foo")).default); +} diff --git a/tests/baselines/reference/asyncImportNestedYield.types b/tests/baselines/reference/asyncImportNestedYield.types new file mode 100644 index 00000000000..872e3141500 --- /dev/null +++ b/tests/baselines/reference/asyncImportNestedYield.types @@ -0,0 +1,14 @@ +=== tests/cases/compiler/asyncImportNestedYield.ts === +async function* foo() { +>foo : () => AsyncIterableIterator<"foo"> + + import((await import(yield "foo")).default); +>import((await import(yield "foo")).default) : Promise +>(await import(yield "foo")).default : any +>(await import(yield "foo")) : any +>await import(yield "foo") : any +>import(yield "foo") : Promise +>yield "foo" : any +>"foo" : "foo" +>default : any +} diff --git a/tests/baselines/reference/dynamicImportWithNestedThis_es2015.js b/tests/baselines/reference/dynamicImportWithNestedThis_es2015.js index 86fba0c0b5d..4f79e0caec1 100644 --- a/tests/baselines/reference/dynamicImportWithNestedThis_es2015.js +++ b/tests/baselines/reference/dynamicImportWithNestedThis_es2015.js @@ -29,7 +29,8 @@ c.dynamic(); this._path = './other'; } dynamic() { - return __syncRequire ? Promise.resolve().then(() => require(this._path)) : new Promise((resolve_1, reject_1) => { require([this._path], resolve_1, reject_1); }); + return _a = this._path, __syncRequire ? Promise.resolve().then(() => require(_a)) : new Promise((resolve_1, reject_1) => { require([_a], resolve_1, reject_1); }); + var _a; } } const c = new C(); diff --git a/tests/baselines/reference/dynamicImportWithNestedThis_es5.js b/tests/baselines/reference/dynamicImportWithNestedThis_es5.js index cde1979b25b..fcfde9e9887 100644 --- a/tests/baselines/reference/dynamicImportWithNestedThis_es5.js +++ b/tests/baselines/reference/dynamicImportWithNestedThis_es5.js @@ -30,7 +30,8 @@ c.dynamic(); } C.prototype.dynamic = function () { var _this = this; - return __syncRequire ? Promise.resolve().then(function () { return require(_this._path); }) : new Promise(function (resolve_1, reject_1) { require([_this._path], resolve_1, reject_1); }); + return _a = this._path, __syncRequire ? Promise.resolve().then(function () { return require(_a); }) : new Promise(function (resolve_1, reject_1) { require([_a], resolve_1, reject_1); }); + var _a; }; return C; }()); diff --git a/tests/baselines/reference/importCallExpressionGrammarError.js b/tests/baselines/reference/importCallExpressionGrammarError.js index e2ffc55577d..435eab35d4e 100644 --- a/tests/baselines/reference/importCallExpressionGrammarError.js +++ b/tests/baselines/reference/importCallExpressionGrammarError.js @@ -16,4 +16,4 @@ Promise.resolve().then(() => require(...["PathModule"])); var p1 = Promise.resolve().then(() => require(...a)); const p2 = Promise.resolve().then(() => require()); const p3 = Promise.resolve().then(() => require()); -const p4 = Promise.resolve().then(() => require("pathToModule", "secondModule")); +const p4 = Promise.resolve().then(() => require("pathToModule")); diff --git a/tests/baselines/reference/importCallExpressionNestedAMD.js b/tests/baselines/reference/importCallExpressionNestedAMD.js new file mode 100644 index 00000000000..dc211d44003 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedAMD.js @@ -0,0 +1,33 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionNestedAMD.ts] //// + +//// [foo.ts] +export default "./foo"; + +//// [index.ts] +async function foo() { + return await import((await import("./foo")).default); +} + +//// [foo.js] +define(["require", "exports"], function (require, exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.default = "./foo"; +}); +//// [index.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +define(["require", "exports"], function (require, exports) { + "use strict"; + function foo() { + return __awaiter(this, void 0, void 0, function* () { + return yield new Promise((resolve_1, reject_1) => { require([(yield new Promise((resolve_2, reject_2) => { require(["./foo"], resolve_2, reject_2); })).default], resolve_1, reject_1); }); + }); + } +}); diff --git a/tests/baselines/reference/importCallExpressionNestedAMD.symbols b/tests/baselines/reference/importCallExpressionNestedAMD.symbols new file mode 100644 index 00000000000..67e2eabd6fd --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedAMD.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : Symbol(foo, Decl(index.ts, 0, 0)) + + return await import((await import("./foo")).default); +>(await import("./foo")).default : Symbol(default, Decl(foo.ts, 0, 0)) +>"./foo" : Symbol("tests/cases/conformance/dynamicImport/foo", Decl(foo.ts, 0, 0)) +>default : Symbol(default, Decl(foo.ts, 0, 0)) +} diff --git a/tests/baselines/reference/importCallExpressionNestedAMD.types b/tests/baselines/reference/importCallExpressionNestedAMD.types new file mode 100644 index 00000000000..2f74d78b6c8 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedAMD.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : () => Promise + + return await import((await import("./foo")).default); +>await import((await import("./foo")).default) : any +>import((await import("./foo")).default) : Promise +>(await import("./foo")).default : "./foo" +>(await import("./foo")) : typeof "tests/cases/conformance/dynamicImport/foo" +>await import("./foo") : typeof "tests/cases/conformance/dynamicImport/foo" +>import("./foo") : Promise +>"./foo" : "./foo" +>default : "./foo" +} diff --git a/tests/baselines/reference/importCallExpressionNestedAMD2.js b/tests/baselines/reference/importCallExpressionNestedAMD2.js new file mode 100644 index 00000000000..1e159af2180 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedAMD2.js @@ -0,0 +1,66 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionNestedAMD2.ts] //// + +//// [foo.ts] +export default "./foo"; + +//// [index.ts] +async function foo() { + return await import((await import("./foo")).default); +} + +//// [foo.js] +define(["require", "exports"], function (require, exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.default = "./foo"; +}); +//// [index.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +define(["require", "exports"], function (require, exports) { + "use strict"; + function foo() { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, new Promise(function (resolve_1, reject_1) { require(["./foo"], resolve_1, reject_1); })]; + case 1: return [4 /*yield*/, new Promise(function (resolve_2, reject_2) { require([(_a.sent()).default], resolve_2, reject_2); })]; + case 2: return [2 /*return*/, _a.sent()]; + } + }); + }); + } +}); diff --git a/tests/baselines/reference/importCallExpressionNestedAMD2.symbols b/tests/baselines/reference/importCallExpressionNestedAMD2.symbols new file mode 100644 index 00000000000..67e2eabd6fd --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedAMD2.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : Symbol(foo, Decl(index.ts, 0, 0)) + + return await import((await import("./foo")).default); +>(await import("./foo")).default : Symbol(default, Decl(foo.ts, 0, 0)) +>"./foo" : Symbol("tests/cases/conformance/dynamicImport/foo", Decl(foo.ts, 0, 0)) +>default : Symbol(default, Decl(foo.ts, 0, 0)) +} diff --git a/tests/baselines/reference/importCallExpressionNestedAMD2.types b/tests/baselines/reference/importCallExpressionNestedAMD2.types new file mode 100644 index 00000000000..2f74d78b6c8 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedAMD2.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : () => Promise + + return await import((await import("./foo")).default); +>await import((await import("./foo")).default) : any +>import((await import("./foo")).default) : Promise +>(await import("./foo")).default : "./foo" +>(await import("./foo")) : typeof "tests/cases/conformance/dynamicImport/foo" +>await import("./foo") : typeof "tests/cases/conformance/dynamicImport/foo" +>import("./foo") : Promise +>"./foo" : "./foo" +>default : "./foo" +} diff --git a/tests/baselines/reference/importCallExpressionNestedCJS.js b/tests/baselines/reference/importCallExpressionNestedCJS.js new file mode 100644 index 00000000000..07c0f234bf7 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedCJS.js @@ -0,0 +1,28 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionNestedCJS.ts] //// + +//// [foo.ts] +export default "./foo"; + +//// [index.ts] +async function foo() { + return await import((await import("./foo")).default); +} + +//// [foo.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = "./foo"; +//// [index.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +function foo() { + return __awaiter(this, void 0, void 0, function* () { + return yield Promise.resolve().then(() => require((yield Promise.resolve().then(() => require("./foo"))).default)); + }); +} diff --git a/tests/baselines/reference/importCallExpressionNestedCJS.symbols b/tests/baselines/reference/importCallExpressionNestedCJS.symbols new file mode 100644 index 00000000000..67e2eabd6fd --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedCJS.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : Symbol(foo, Decl(index.ts, 0, 0)) + + return await import((await import("./foo")).default); +>(await import("./foo")).default : Symbol(default, Decl(foo.ts, 0, 0)) +>"./foo" : Symbol("tests/cases/conformance/dynamicImport/foo", Decl(foo.ts, 0, 0)) +>default : Symbol(default, Decl(foo.ts, 0, 0)) +} diff --git a/tests/baselines/reference/importCallExpressionNestedCJS.types b/tests/baselines/reference/importCallExpressionNestedCJS.types new file mode 100644 index 00000000000..2f74d78b6c8 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedCJS.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : () => Promise + + return await import((await import("./foo")).default); +>await import((await import("./foo")).default) : any +>import((await import("./foo")).default) : Promise +>(await import("./foo")).default : "./foo" +>(await import("./foo")) : typeof "tests/cases/conformance/dynamicImport/foo" +>await import("./foo") : typeof "tests/cases/conformance/dynamicImport/foo" +>import("./foo") : Promise +>"./foo" : "./foo" +>default : "./foo" +} diff --git a/tests/baselines/reference/importCallExpressionNestedCJS2.js b/tests/baselines/reference/importCallExpressionNestedCJS2.js new file mode 100644 index 00000000000..c76044ec05c --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedCJS2.js @@ -0,0 +1,61 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionNestedCJS2.ts] //// + +//// [foo.ts] +export default "./foo"; + +//// [index.ts] +async function foo() { + return await import((await import("./foo")).default); +} + +//// [foo.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = "./foo"; +//// [index.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +function foo() { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, Promise.resolve().then(function () { return require("./foo"); })]; + case 1: return [4 /*yield*/, Promise.resolve().then(function () { return require((_a.sent()).default); })]; + case 2: return [2 /*return*/, _a.sent()]; + } + }); + }); +} diff --git a/tests/baselines/reference/importCallExpressionNestedCJS2.symbols b/tests/baselines/reference/importCallExpressionNestedCJS2.symbols new file mode 100644 index 00000000000..67e2eabd6fd --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedCJS2.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : Symbol(foo, Decl(index.ts, 0, 0)) + + return await import((await import("./foo")).default); +>(await import("./foo")).default : Symbol(default, Decl(foo.ts, 0, 0)) +>"./foo" : Symbol("tests/cases/conformance/dynamicImport/foo", Decl(foo.ts, 0, 0)) +>default : Symbol(default, Decl(foo.ts, 0, 0)) +} diff --git a/tests/baselines/reference/importCallExpressionNestedCJS2.types b/tests/baselines/reference/importCallExpressionNestedCJS2.types new file mode 100644 index 00000000000..2f74d78b6c8 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedCJS2.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : () => Promise + + return await import((await import("./foo")).default); +>await import((await import("./foo")).default) : any +>import((await import("./foo")).default) : Promise +>(await import("./foo")).default : "./foo" +>(await import("./foo")) : typeof "tests/cases/conformance/dynamicImport/foo" +>await import("./foo") : typeof "tests/cases/conformance/dynamicImport/foo" +>import("./foo") : Promise +>"./foo" : "./foo" +>default : "./foo" +} diff --git a/tests/baselines/reference/importCallExpressionNestedES2015.errors.txt b/tests/baselines/reference/importCallExpressionNestedES2015.errors.txt new file mode 100644 index 00000000000..1208dd0c709 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedES2015.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/dynamicImport/index.ts(2,18): error TS1323: Dynamic import cannot be used when targeting ECMAScript 2015 modules. +tests/cases/conformance/dynamicImport/index.ts(2,32): error TS1323: Dynamic import cannot be used when targeting ECMAScript 2015 modules. + + +==== tests/cases/conformance/dynamicImport/foo.ts (0 errors) ==== + export default "./foo"; + +==== tests/cases/conformance/dynamicImport/index.ts (2 errors) ==== + async function foo() { + return await import((await import("./foo")).default); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1323: Dynamic import cannot be used when targeting ECMAScript 2015 modules. + ~~~~~~~~~~~~~~~ +!!! error TS1323: Dynamic import cannot be used when targeting ECMAScript 2015 modules. + } \ No newline at end of file diff --git a/tests/baselines/reference/importCallExpressionNestedES2015.js b/tests/baselines/reference/importCallExpressionNestedES2015.js new file mode 100644 index 00000000000..5c8a6a9edb5 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedES2015.js @@ -0,0 +1,26 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionNestedES2015.ts] //// + +//// [foo.ts] +export default "./foo"; + +//// [index.ts] +async function foo() { + return await import((await import("./foo")).default); +} + +//// [foo.js] +export default "./foo"; +//// [index.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +function foo() { + return __awaiter(this, void 0, void 0, function* () { + return yield import((yield import("./foo")).default); + }); +} diff --git a/tests/baselines/reference/importCallExpressionNestedES2015.symbols b/tests/baselines/reference/importCallExpressionNestedES2015.symbols new file mode 100644 index 00000000000..67e2eabd6fd --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedES2015.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : Symbol(foo, Decl(index.ts, 0, 0)) + + return await import((await import("./foo")).default); +>(await import("./foo")).default : Symbol(default, Decl(foo.ts, 0, 0)) +>"./foo" : Symbol("tests/cases/conformance/dynamicImport/foo", Decl(foo.ts, 0, 0)) +>default : Symbol(default, Decl(foo.ts, 0, 0)) +} diff --git a/tests/baselines/reference/importCallExpressionNestedES2015.types b/tests/baselines/reference/importCallExpressionNestedES2015.types new file mode 100644 index 00000000000..2f74d78b6c8 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedES2015.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : () => Promise + + return await import((await import("./foo")).default); +>await import((await import("./foo")).default) : any +>import((await import("./foo")).default) : Promise +>(await import("./foo")).default : "./foo" +>(await import("./foo")) : typeof "tests/cases/conformance/dynamicImport/foo" +>await import("./foo") : typeof "tests/cases/conformance/dynamicImport/foo" +>import("./foo") : Promise +>"./foo" : "./foo" +>default : "./foo" +} diff --git a/tests/baselines/reference/importCallExpressionNestedES20152.errors.txt b/tests/baselines/reference/importCallExpressionNestedES20152.errors.txt new file mode 100644 index 00000000000..1208dd0c709 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedES20152.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/dynamicImport/index.ts(2,18): error TS1323: Dynamic import cannot be used when targeting ECMAScript 2015 modules. +tests/cases/conformance/dynamicImport/index.ts(2,32): error TS1323: Dynamic import cannot be used when targeting ECMAScript 2015 modules. + + +==== tests/cases/conformance/dynamicImport/foo.ts (0 errors) ==== + export default "./foo"; + +==== tests/cases/conformance/dynamicImport/index.ts (2 errors) ==== + async function foo() { + return await import((await import("./foo")).default); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1323: Dynamic import cannot be used when targeting ECMAScript 2015 modules. + ~~~~~~~~~~~~~~~ +!!! error TS1323: Dynamic import cannot be used when targeting ECMAScript 2015 modules. + } \ No newline at end of file diff --git a/tests/baselines/reference/importCallExpressionNestedES20152.js b/tests/baselines/reference/importCallExpressionNestedES20152.js new file mode 100644 index 00000000000..2496f43f84f --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedES20152.js @@ -0,0 +1,59 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionNestedES20152.ts] //// + +//// [foo.ts] +export default "./foo"; + +//// [index.ts] +async function foo() { + return await import((await import("./foo")).default); +} + +//// [foo.js] +export default "./foo"; +//// [index.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +function foo() { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, import("./foo")]; + case 1: return [4 /*yield*/, import((_a.sent()).default)]; + case 2: return [2 /*return*/, _a.sent()]; + } + }); + }); +} diff --git a/tests/baselines/reference/importCallExpressionNestedES20152.symbols b/tests/baselines/reference/importCallExpressionNestedES20152.symbols new file mode 100644 index 00000000000..67e2eabd6fd --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedES20152.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : Symbol(foo, Decl(index.ts, 0, 0)) + + return await import((await import("./foo")).default); +>(await import("./foo")).default : Symbol(default, Decl(foo.ts, 0, 0)) +>"./foo" : Symbol("tests/cases/conformance/dynamicImport/foo", Decl(foo.ts, 0, 0)) +>default : Symbol(default, Decl(foo.ts, 0, 0)) +} diff --git a/tests/baselines/reference/importCallExpressionNestedES20152.types b/tests/baselines/reference/importCallExpressionNestedES20152.types new file mode 100644 index 00000000000..2f74d78b6c8 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedES20152.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : () => Promise + + return await import((await import("./foo")).default); +>await import((await import("./foo")).default) : any +>import((await import("./foo")).default) : Promise +>(await import("./foo")).default : "./foo" +>(await import("./foo")) : typeof "tests/cases/conformance/dynamicImport/foo" +>await import("./foo") : typeof "tests/cases/conformance/dynamicImport/foo" +>import("./foo") : Promise +>"./foo" : "./foo" +>default : "./foo" +} diff --git a/tests/baselines/reference/importCallExpressionNestedESNext.js b/tests/baselines/reference/importCallExpressionNestedESNext.js new file mode 100644 index 00000000000..8ec9b988201 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedESNext.js @@ -0,0 +1,26 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionNestedESNext.ts] //// + +//// [foo.ts] +export default "./foo"; + +//// [index.ts] +async function foo() { + return await import((await import("./foo")).default); +} + +//// [foo.js] +export default "./foo"; +//// [index.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +function foo() { + return __awaiter(this, void 0, void 0, function* () { + return yield import((yield import("./foo")).default); + }); +} diff --git a/tests/baselines/reference/importCallExpressionNestedESNext.symbols b/tests/baselines/reference/importCallExpressionNestedESNext.symbols new file mode 100644 index 00000000000..67e2eabd6fd --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedESNext.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : Symbol(foo, Decl(index.ts, 0, 0)) + + return await import((await import("./foo")).default); +>(await import("./foo")).default : Symbol(default, Decl(foo.ts, 0, 0)) +>"./foo" : Symbol("tests/cases/conformance/dynamicImport/foo", Decl(foo.ts, 0, 0)) +>default : Symbol(default, Decl(foo.ts, 0, 0)) +} diff --git a/tests/baselines/reference/importCallExpressionNestedESNext.types b/tests/baselines/reference/importCallExpressionNestedESNext.types new file mode 100644 index 00000000000..2f74d78b6c8 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedESNext.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : () => Promise + + return await import((await import("./foo")).default); +>await import((await import("./foo")).default) : any +>import((await import("./foo")).default) : Promise +>(await import("./foo")).default : "./foo" +>(await import("./foo")) : typeof "tests/cases/conformance/dynamicImport/foo" +>await import("./foo") : typeof "tests/cases/conformance/dynamicImport/foo" +>import("./foo") : Promise +>"./foo" : "./foo" +>default : "./foo" +} diff --git a/tests/baselines/reference/importCallExpressionNestedESNext2.js b/tests/baselines/reference/importCallExpressionNestedESNext2.js new file mode 100644 index 00000000000..9a4d9f44f7a --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedESNext2.js @@ -0,0 +1,59 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionNestedESNext2.ts] //// + +//// [foo.ts] +export default "./foo"; + +//// [index.ts] +async function foo() { + return await import((await import("./foo")).default); +} + +//// [foo.js] +export default "./foo"; +//// [index.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +function foo() { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, import("./foo")]; + case 1: return [4 /*yield*/, import((_a.sent()).default)]; + case 2: return [2 /*return*/, _a.sent()]; + } + }); + }); +} diff --git a/tests/baselines/reference/importCallExpressionNestedESNext2.symbols b/tests/baselines/reference/importCallExpressionNestedESNext2.symbols new file mode 100644 index 00000000000..67e2eabd6fd --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedESNext2.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : Symbol(foo, Decl(index.ts, 0, 0)) + + return await import((await import("./foo")).default); +>(await import("./foo")).default : Symbol(default, Decl(foo.ts, 0, 0)) +>"./foo" : Symbol("tests/cases/conformance/dynamicImport/foo", Decl(foo.ts, 0, 0)) +>default : Symbol(default, Decl(foo.ts, 0, 0)) +} diff --git a/tests/baselines/reference/importCallExpressionNestedESNext2.types b/tests/baselines/reference/importCallExpressionNestedESNext2.types new file mode 100644 index 00000000000..2f74d78b6c8 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedESNext2.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : () => Promise + + return await import((await import("./foo")).default); +>await import((await import("./foo")).default) : any +>import((await import("./foo")).default) : Promise +>(await import("./foo")).default : "./foo" +>(await import("./foo")) : typeof "tests/cases/conformance/dynamicImport/foo" +>await import("./foo") : typeof "tests/cases/conformance/dynamicImport/foo" +>import("./foo") : Promise +>"./foo" : "./foo" +>default : "./foo" +} diff --git a/tests/baselines/reference/importCallExpressionNestedSystem.js b/tests/baselines/reference/importCallExpressionNestedSystem.js new file mode 100644 index 00000000000..839a3601e38 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedSystem.js @@ -0,0 +1,43 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionNestedSystem.ts] //// + +//// [foo.ts] +export default "./foo"; + +//// [index.ts] +async function foo() { + return await import((await import("./foo")).default); +} + +//// [foo.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + return { + setters: [], + execute: function () { + exports_1("default", "./foo"); + } + }; +}); +//// [index.js] +System.register([], function (exports_1, context_1) { + var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var __moduleName = context_1 && context_1.id; + function foo() { + return __awaiter(this, void 0, void 0, function* () { + return yield context_1.import((yield context_1.import("./foo")).default); + }); + } + return { + setters: [], + execute: function () { + } + }; +}); diff --git a/tests/baselines/reference/importCallExpressionNestedSystem.symbols b/tests/baselines/reference/importCallExpressionNestedSystem.symbols new file mode 100644 index 00000000000..67e2eabd6fd --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedSystem.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : Symbol(foo, Decl(index.ts, 0, 0)) + + return await import((await import("./foo")).default); +>(await import("./foo")).default : Symbol(default, Decl(foo.ts, 0, 0)) +>"./foo" : Symbol("tests/cases/conformance/dynamicImport/foo", Decl(foo.ts, 0, 0)) +>default : Symbol(default, Decl(foo.ts, 0, 0)) +} diff --git a/tests/baselines/reference/importCallExpressionNestedSystem.types b/tests/baselines/reference/importCallExpressionNestedSystem.types new file mode 100644 index 00000000000..2f74d78b6c8 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedSystem.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : () => Promise + + return await import((await import("./foo")).default); +>await import((await import("./foo")).default) : any +>import((await import("./foo")).default) : Promise +>(await import("./foo")).default : "./foo" +>(await import("./foo")) : typeof "tests/cases/conformance/dynamicImport/foo" +>await import("./foo") : typeof "tests/cases/conformance/dynamicImport/foo" +>import("./foo") : Promise +>"./foo" : "./foo" +>default : "./foo" +} diff --git a/tests/baselines/reference/importCallExpressionNestedSystem2.js b/tests/baselines/reference/importCallExpressionNestedSystem2.js new file mode 100644 index 00000000000..9b0fc20886d --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedSystem2.js @@ -0,0 +1,76 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionNestedSystem2.ts] //// + +//// [foo.ts] +export default "./foo"; + +//// [index.ts] +async function foo() { + return await import((await import("./foo")).default); +} + +//// [foo.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + return { + setters: [], + execute: function () { + exports_1("default", "./foo"); + } + }; +}); +//// [index.js] +System.register([], function (exports_1, context_1) { + var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } + }; + var __moduleName = context_1 && context_1.id; + function foo() { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, context_1.import("./foo")]; + case 1: return [4 /*yield*/, context_1.import((_a.sent()).default)]; + case 2: return [2 /*return*/, _a.sent()]; + } + }); + }); + } + return { + setters: [], + execute: function () { + } + }; +}); diff --git a/tests/baselines/reference/importCallExpressionNestedSystem2.symbols b/tests/baselines/reference/importCallExpressionNestedSystem2.symbols new file mode 100644 index 00000000000..67e2eabd6fd --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedSystem2.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : Symbol(foo, Decl(index.ts, 0, 0)) + + return await import((await import("./foo")).default); +>(await import("./foo")).default : Symbol(default, Decl(foo.ts, 0, 0)) +>"./foo" : Symbol("tests/cases/conformance/dynamicImport/foo", Decl(foo.ts, 0, 0)) +>default : Symbol(default, Decl(foo.ts, 0, 0)) +} diff --git a/tests/baselines/reference/importCallExpressionNestedSystem2.types b/tests/baselines/reference/importCallExpressionNestedSystem2.types new file mode 100644 index 00000000000..2f74d78b6c8 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedSystem2.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : () => Promise + + return await import((await import("./foo")).default); +>await import((await import("./foo")).default) : any +>import((await import("./foo")).default) : Promise +>(await import("./foo")).default : "./foo" +>(await import("./foo")) : typeof "tests/cases/conformance/dynamicImport/foo" +>await import("./foo") : typeof "tests/cases/conformance/dynamicImport/foo" +>import("./foo") : Promise +>"./foo" : "./foo" +>default : "./foo" +} diff --git a/tests/baselines/reference/importCallExpressionNestedUMD.js b/tests/baselines/reference/importCallExpressionNestedUMD.js new file mode 100644 index 00000000000..0b1d20af8a4 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedUMD.js @@ -0,0 +1,51 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionNestedUMD.ts] //// + +//// [foo.ts] +export default "./foo"; + +//// [index.ts] +async function foo() { + return await import((await import("./foo")).default); +} + +//// [foo.js] +(function (factory) { + if (typeof module === "object" && typeof module.exports === "object") { + var v = factory(require, exports); + if (v !== undefined) module.exports = v; + } + else if (typeof define === "function" && define.amd) { + define(["require", "exports"], factory); + } +})(function (require, exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.default = "./foo"; +}); +//// [index.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +(function (factory) { + if (typeof module === "object" && typeof module.exports === "object") { + var v = factory(require, exports); + if (v !== undefined) module.exports = v; + } + else if (typeof define === "function" && define.amd) { + define(["require", "exports"], factory); + } +})(function (require, exports) { + "use strict"; + var __syncRequire = typeof module === "object" && typeof module.exports === "object"; + function foo() { + return __awaiter(this, void 0, void 0, function* () { + return yield _a = (yield __syncRequire ? Promise.resolve().then(() => require("./foo")) : new Promise((resolve_1, reject_1) => { require(["./foo"], resolve_1, reject_1); })).default, __syncRequire ? Promise.resolve().then(() => require(_a)) : new Promise((resolve_2, reject_2) => { require([_a], resolve_2, reject_2); }); + var _a; + }); + } +}); diff --git a/tests/baselines/reference/importCallExpressionNestedUMD.symbols b/tests/baselines/reference/importCallExpressionNestedUMD.symbols new file mode 100644 index 00000000000..67e2eabd6fd --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedUMD.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : Symbol(foo, Decl(index.ts, 0, 0)) + + return await import((await import("./foo")).default); +>(await import("./foo")).default : Symbol(default, Decl(foo.ts, 0, 0)) +>"./foo" : Symbol("tests/cases/conformance/dynamicImport/foo", Decl(foo.ts, 0, 0)) +>default : Symbol(default, Decl(foo.ts, 0, 0)) +} diff --git a/tests/baselines/reference/importCallExpressionNestedUMD.types b/tests/baselines/reference/importCallExpressionNestedUMD.types new file mode 100644 index 00000000000..2f74d78b6c8 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedUMD.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : () => Promise + + return await import((await import("./foo")).default); +>await import((await import("./foo")).default) : any +>import((await import("./foo")).default) : Promise +>(await import("./foo")).default : "./foo" +>(await import("./foo")) : typeof "tests/cases/conformance/dynamicImport/foo" +>await import("./foo") : typeof "tests/cases/conformance/dynamicImport/foo" +>import("./foo") : Promise +>"./foo" : "./foo" +>default : "./foo" +} diff --git a/tests/baselines/reference/importCallExpressionNestedUMD2.js b/tests/baselines/reference/importCallExpressionNestedUMD2.js new file mode 100644 index 00000000000..86fd0bfa8f1 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedUMD2.js @@ -0,0 +1,84 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionNestedUMD2.ts] //// + +//// [foo.ts] +export default "./foo"; + +//// [index.ts] +async function foo() { + return await import((await import("./foo")).default); +} + +//// [foo.js] +(function (factory) { + if (typeof module === "object" && typeof module.exports === "object") { + var v = factory(require, exports); + if (v !== undefined) module.exports = v; + } + else if (typeof define === "function" && define.amd) { + define(["require", "exports"], factory); + } +})(function (require, exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.default = "./foo"; +}); +//// [index.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +(function (factory) { + if (typeof module === "object" && typeof module.exports === "object") { + var v = factory(require, exports); + if (v !== undefined) module.exports = v; + } + else if (typeof define === "function" && define.amd) { + define(["require", "exports"], factory); + } +})(function (require, exports) { + "use strict"; + var __syncRequire = typeof module === "object" && typeof module.exports === "object"; + function foo() { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, __syncRequire ? Promise.resolve().then(function () { return require("./foo"); }) : new Promise(function (resolve_1, reject_1) { require(["./foo"], resolve_1, reject_1); })]; + case 1: return [4 /*yield*/, (_b = (_a.sent()).default, __syncRequire ? Promise.resolve().then(function () { return require(_b); }) : new Promise(function (resolve_2, reject_2) { require([_b], resolve_2, reject_2); }))]; + case 2: return [2 /*return*/, _a.sent()]; + } + var _b; + }); + }); + } +}); diff --git a/tests/baselines/reference/importCallExpressionNestedUMD2.symbols b/tests/baselines/reference/importCallExpressionNestedUMD2.symbols new file mode 100644 index 00000000000..67e2eabd6fd --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedUMD2.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : Symbol(foo, Decl(index.ts, 0, 0)) + + return await import((await import("./foo")).default); +>(await import("./foo")).default : Symbol(default, Decl(foo.ts, 0, 0)) +>"./foo" : Symbol("tests/cases/conformance/dynamicImport/foo", Decl(foo.ts, 0, 0)) +>default : Symbol(default, Decl(foo.ts, 0, 0)) +} diff --git a/tests/baselines/reference/importCallExpressionNestedUMD2.types b/tests/baselines/reference/importCallExpressionNestedUMD2.types new file mode 100644 index 00000000000..2f74d78b6c8 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNestedUMD2.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/dynamicImport/foo.ts === +export default "./foo"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts === +async function foo() { +>foo : () => Promise + + return await import((await import("./foo")).default); +>await import((await import("./foo")).default) : any +>import((await import("./foo")).default) : Promise +>(await import("./foo")).default : "./foo" +>(await import("./foo")) : typeof "tests/cases/conformance/dynamicImport/foo" +>await import("./foo") : typeof "tests/cases/conformance/dynamicImport/foo" +>import("./foo") : Promise +>"./foo" : "./foo" +>default : "./foo" +} diff --git a/tests/cases/compiler/asyncImportNestedYield.ts b/tests/cases/compiler/asyncImportNestedYield.ts new file mode 100644 index 00000000000..78b022e0797 --- /dev/null +++ b/tests/cases/compiler/asyncImportNestedYield.ts @@ -0,0 +1,4 @@ +// @lib: esnext +async function* foo() { + import((await import(yield "foo")).default); +} \ No newline at end of file diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionNestedAMD.ts b/tests/cases/conformance/dynamicImport/importCallExpressionNestedAMD.ts new file mode 100644 index 00000000000..1dbde4e1956 --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionNestedAMD.ts @@ -0,0 +1,11 @@ +// @module: amd +// @target: es6 +// @skipLibCheck: true +// @lib: es6 +// @filename: foo.ts +export default "./foo"; + +// @filename: index.ts +async function foo() { + return await import((await import("./foo")).default); +} \ No newline at end of file diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionNestedAMD2.ts b/tests/cases/conformance/dynamicImport/importCallExpressionNestedAMD2.ts new file mode 100644 index 00000000000..79540087a58 --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionNestedAMD2.ts @@ -0,0 +1,11 @@ +// @module: amd +// @target: es5 +// @skipLibCheck: true +// @lib: es6 +// @filename: foo.ts +export default "./foo"; + +// @filename: index.ts +async function foo() { + return await import((await import("./foo")).default); +} \ No newline at end of file diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionNestedCJS.ts b/tests/cases/conformance/dynamicImport/importCallExpressionNestedCJS.ts new file mode 100644 index 00000000000..5c99e56ecda --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionNestedCJS.ts @@ -0,0 +1,11 @@ +// @module: commonjs +// @target: es6 +// @skipLibCheck: true +// @lib: es6 +// @filename: foo.ts +export default "./foo"; + +// @filename: index.ts +async function foo() { + return await import((await import("./foo")).default); +} \ No newline at end of file diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionNestedCJS2.ts b/tests/cases/conformance/dynamicImport/importCallExpressionNestedCJS2.ts new file mode 100644 index 00000000000..0776053d668 --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionNestedCJS2.ts @@ -0,0 +1,11 @@ +// @module: commonjs +// @target: es5 +// @skipLibCheck: true +// @lib: es6 +// @filename: foo.ts +export default "./foo"; + +// @filename: index.ts +async function foo() { + return await import((await import("./foo")).default); +} \ No newline at end of file diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionNestedES2015.ts b/tests/cases/conformance/dynamicImport/importCallExpressionNestedES2015.ts new file mode 100644 index 00000000000..9708f466f5e --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionNestedES2015.ts @@ -0,0 +1,11 @@ +// @module: es2015 +// @target: es6 +// @skipLibCheck: true +// @lib: es6 +// @filename: foo.ts +export default "./foo"; + +// @filename: index.ts +async function foo() { + return await import((await import("./foo")).default); +} \ No newline at end of file diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionNestedES20152.ts b/tests/cases/conformance/dynamicImport/importCallExpressionNestedES20152.ts new file mode 100644 index 00000000000..c78b38db193 --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionNestedES20152.ts @@ -0,0 +1,11 @@ +// @module: es2015 +// @target: es5 +// @skipLibCheck: true +// @lib: es6 +// @filename: foo.ts +export default "./foo"; + +// @filename: index.ts +async function foo() { + return await import((await import("./foo")).default); +} \ No newline at end of file diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionNestedESNext.ts b/tests/cases/conformance/dynamicImport/importCallExpressionNestedESNext.ts new file mode 100644 index 00000000000..fffc12a7726 --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionNestedESNext.ts @@ -0,0 +1,11 @@ +// @module: esnext +// @target: es6 +// @skipLibCheck: true +// @lib: es6 +// @filename: foo.ts +export default "./foo"; + +// @filename: index.ts +async function foo() { + return await import((await import("./foo")).default); +} \ No newline at end of file diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionNestedESNext2.ts b/tests/cases/conformance/dynamicImport/importCallExpressionNestedESNext2.ts new file mode 100644 index 00000000000..246e9d931f0 --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionNestedESNext2.ts @@ -0,0 +1,11 @@ +// @module: esnext +// @target: es5 +// @skipLibCheck: true +// @lib: es6 +// @filename: foo.ts +export default "./foo"; + +// @filename: index.ts +async function foo() { + return await import((await import("./foo")).default); +} \ No newline at end of file diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionNestedSystem.ts b/tests/cases/conformance/dynamicImport/importCallExpressionNestedSystem.ts new file mode 100644 index 00000000000..04a11ac8169 --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionNestedSystem.ts @@ -0,0 +1,11 @@ +// @module: system +// @target: es6 +// @skipLibCheck: true +// @lib: es6 +// @filename: foo.ts +export default "./foo"; + +// @filename: index.ts +async function foo() { + return await import((await import("./foo")).default); +} \ No newline at end of file diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionNestedSystem2.ts b/tests/cases/conformance/dynamicImport/importCallExpressionNestedSystem2.ts new file mode 100644 index 00000000000..f8b2d4513ee --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionNestedSystem2.ts @@ -0,0 +1,11 @@ +// @module: system +// @target: es5 +// @skipLibCheck: true +// @lib: es6 +// @filename: foo.ts +export default "./foo"; + +// @filename: index.ts +async function foo() { + return await import((await import("./foo")).default); +} \ No newline at end of file diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionNestedUMD.ts b/tests/cases/conformance/dynamicImport/importCallExpressionNestedUMD.ts new file mode 100644 index 00000000000..8b900a7dbd6 --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionNestedUMD.ts @@ -0,0 +1,11 @@ +// @module: umd +// @target: es6 +// @skipLibCheck: true +// @lib: es6 +// @filename: foo.ts +export default "./foo"; + +// @filename: index.ts +async function foo() { + return await import((await import("./foo")).default); +} \ No newline at end of file diff --git a/tests/cases/conformance/dynamicImport/importCallExpressionNestedUMD2.ts b/tests/cases/conformance/dynamicImport/importCallExpressionNestedUMD2.ts new file mode 100644 index 00000000000..e07dba0d2e5 --- /dev/null +++ b/tests/cases/conformance/dynamicImport/importCallExpressionNestedUMD2.ts @@ -0,0 +1,11 @@ +// @module: umd +// @target: es5 +// @skipLibCheck: true +// @lib: es6 +// @filename: foo.ts +export default "./foo"; + +// @filename: index.ts +async function foo() { + return await import((await import("./foo")).default); +} \ No newline at end of file From 6bfad5222522fbc614ba35b860f09c4736a535a4 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 12 Oct 2017 13:23:08 -0700 Subject: [PATCH 124/312] Update missed baseline --- src/harness/unittests/tsserverProjectSystem.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 716c36d1e5d..7dce256e388 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -4412,9 +4412,9 @@ namespace ts.projectSystem { fileName: "/a.ts", textChanges: [ { - start: { line: 2, offset: 1 }, - end: { line: 3, offset: 1 }, - newText: " newFunction();\n", + start: { line: 2, offset: 3 }, + end: { line: 2, offset: 5 }, + newText: "newFunction();", }, { start: { line: 3, offset: 2 }, From 2ea4cfe23bf0648c099a79a8a1d976febb2e2610 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 12 Oct 2017 11:37:31 -0700 Subject: [PATCH 125/312] Insert a line break before a function at EOF if needed This is a pre-existing issue that became more obvious after refining trivia handling. --- src/harness/unittests/tsserverProjectSystem.ts | 2 +- src/services/refactors/extractSymbol.ts | 5 ++++- .../baselines/reference/extractFunction/extractFunction1.ts | 1 + .../baselines/reference/extractFunction/extractFunction10.ts | 1 + .../baselines/reference/extractFunction/extractFunction11.ts | 1 + .../baselines/reference/extractFunction/extractFunction13.ts | 1 + .../baselines/reference/extractFunction/extractFunction14.ts | 1 + .../baselines/reference/extractFunction/extractFunction15.ts | 1 + .../baselines/reference/extractFunction/extractFunction16.ts | 1 + .../baselines/reference/extractFunction/extractFunction17.ts | 1 + .../baselines/reference/extractFunction/extractFunction18.ts | 1 + .../baselines/reference/extractFunction/extractFunction19.ts | 1 + .../baselines/reference/extractFunction/extractFunction2.ts | 1 + .../baselines/reference/extractFunction/extractFunction20.js | 1 + .../baselines/reference/extractFunction/extractFunction20.ts | 1 + .../baselines/reference/extractFunction/extractFunction21.js | 1 + .../baselines/reference/extractFunction/extractFunction21.ts | 1 + .../baselines/reference/extractFunction/extractFunction22.js | 1 + .../baselines/reference/extractFunction/extractFunction22.ts | 1 + .../baselines/reference/extractFunction/extractFunction23.ts | 1 + .../baselines/reference/extractFunction/extractFunction24.js | 1 + .../baselines/reference/extractFunction/extractFunction24.ts | 1 + .../baselines/reference/extractFunction/extractFunction26.js | 1 + .../baselines/reference/extractFunction/extractFunction26.ts | 1 + .../baselines/reference/extractFunction/extractFunction27.js | 1 + .../baselines/reference/extractFunction/extractFunction27.ts | 1 + .../baselines/reference/extractFunction/extractFunction28.js | 1 + .../baselines/reference/extractFunction/extractFunction28.ts | 1 + .../baselines/reference/extractFunction/extractFunction3.ts | 1 + .../baselines/reference/extractFunction/extractFunction30.ts | 1 + .../baselines/reference/extractFunction/extractFunction31.ts | 1 + .../baselines/reference/extractFunction/extractFunction32.ts | 1 + .../baselines/reference/extractFunction/extractFunction33.js | 1 + .../baselines/reference/extractFunction/extractFunction33.ts | 1 + .../baselines/reference/extractFunction/extractFunction4.ts | 1 + .../baselines/reference/extractFunction/extractFunction5.ts | 1 + .../baselines/reference/extractFunction/extractFunction6.ts | 1 + .../baselines/reference/extractFunction/extractFunction7.ts | 1 + .../baselines/reference/extractFunction/extractFunction9.ts | 1 + .../extractFunction/extractFunction_PreserveTrivia.js | 1 + .../extractFunction/extractFunction_PreserveTrivia.ts | 1 + .../extractFunction/extractFunction_RepeatedSubstitution.ts | 1 + .../extractFunction_VariableDeclaration_ShorthandProperty.js | 1 + .../extractFunction_VariableDeclaration_ShorthandProperty.ts | 1 + ...xtractFunction_VariableDeclaration_Writes_Const_NoType.js | 1 + ...xtractFunction_VariableDeclaration_Writes_Const_NoType.ts | 1 + .../extractFunction_VariableDeclaration_Writes_Const_Type.ts | 1 + ...ctFunction_VariableDeclaration_Writes_Let_LiteralType1.ts | 1 + ...ctFunction_VariableDeclaration_Writes_Let_LiteralType2.ts | 1 + .../extractFunction_VariableDeclaration_Writes_Let_NoType.js | 1 + .../extractFunction_VariableDeclaration_Writes_Let_NoType.ts | 1 + .../extractFunction_VariableDeclaration_Writes_Let_Type.ts | 1 + ...nction_VariableDeclaration_Writes_Let_TypeWithComments.ts | 1 + .../extractFunction_VariableDeclaration_Writes_Mixed1.js | 1 + .../extractFunction_VariableDeclaration_Writes_Mixed1.ts | 1 + .../extractFunction_VariableDeclaration_Writes_Mixed2.js | 1 + .../extractFunction_VariableDeclaration_Writes_Mixed2.ts | 1 + .../extractFunction_VariableDeclaration_Writes_Mixed3.ts | 1 + ...ractFunction_VariableDeclaration_Writes_UnionUndefined.ts | 1 + .../extractFunction_VariableDeclaration_Writes_Var.js | 1 + .../extractFunction_VariableDeclaration_Writes_Var.ts | 1 + tests/cases/fourslash/extract-method-empty-namespace.ts | 1 + tests/cases/fourslash/extract-method-formatting.ts | 1 + tests/cases/fourslash/extract-method-uniqueName.ts | 1 + tests/cases/fourslash/extract-method10.ts | 1 + tests/cases/fourslash/extract-method14.ts | 1 + tests/cases/fourslash/extract-method15.ts | 1 + tests/cases/fourslash/extract-method18.ts | 1 + tests/cases/fourslash/extract-method2.ts | 1 + tests/cases/fourslash/extract-method24.ts | 1 + tests/cases/fourslash/extract-method7.ts | 1 + 71 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 40be5e02eea..4929cbfbaa5 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -4526,7 +4526,7 @@ namespace ts.projectSystem { { start: { line: 3, offset: 2 }, end: { line: 3, offset: 2 }, - newText: "\nfunction newFunction() {\n 1;\n}\n", + newText: "\n\nfunction newFunction() {\n 1;\n}\n", }, ] } diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 715b42b6bc8..ebe0cb4fa44 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -785,7 +785,10 @@ namespace ts.refactor.extractSymbol { changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newFunction, { suffix: context.newLineCharacter + context.newLineCharacter }); } else { - changeTracker.insertNodeBefore(context.file, scope.getLastToken(), newFunction, { prefix: context.newLineCharacter, suffix: context.newLineCharacter }); + changeTracker.insertNodeBefore(context.file, scope.getLastToken(), newFunction, { + prefix: isLineBreak(file.text.charCodeAt(scope.getLastToken().pos)) ? context.newLineCharacter : context.newLineCharacter + context.newLineCharacter, + suffix: context.newLineCharacter + }); } const newNodes: Node[] = []; diff --git a/tests/baselines/reference/extractFunction/extractFunction1.ts b/tests/baselines/reference/extractFunction/extractFunction1.ts index 8243644e1ef..4b0b7dd9f2e 100644 --- a/tests/baselines/reference/extractFunction/extractFunction1.ts +++ b/tests/baselines/reference/extractFunction/extractFunction1.ts @@ -89,6 +89,7 @@ namespace A { } } } + function newFunction(x: number, a: number, foo: () => void) { let y = 5; let z = x; diff --git a/tests/baselines/reference/extractFunction/extractFunction10.ts b/tests/baselines/reference/extractFunction/extractFunction10.ts index a15381c1a18..99651f03e88 100644 --- a/tests/baselines/reference/extractFunction/extractFunction10.ts +++ b/tests/baselines/reference/extractFunction/extractFunction10.ts @@ -49,6 +49,7 @@ namespace A { } } } + function newFunction() { let a1: A.I = { x: 1 }; return a1.x + 10; diff --git a/tests/baselines/reference/extractFunction/extractFunction11.ts b/tests/baselines/reference/extractFunction/extractFunction11.ts index 4bb88123a2f..baca3914b03 100644 --- a/tests/baselines/reference/extractFunction/extractFunction11.ts +++ b/tests/baselines/reference/extractFunction/extractFunction11.ts @@ -61,6 +61,7 @@ namespace A { } } } + function newFunction(y: number, z: number) { let a1 = { x: 1 }; y = 10; diff --git a/tests/baselines/reference/extractFunction/extractFunction13.ts b/tests/baselines/reference/extractFunction/extractFunction13.ts index 662701ebf41..e39476160c5 100644 --- a/tests/baselines/reference/extractFunction/extractFunction13.ts +++ b/tests/baselines/reference/extractFunction/extractFunction13.ts @@ -66,6 +66,7 @@ } } } + function newFunction(t1a: T1a, t2a: T2a, u1a: U1a, u2a: U2a, u3a: U3a) { t1a.toString(); t2a.toString(); diff --git a/tests/baselines/reference/extractFunction/extractFunction14.ts b/tests/baselines/reference/extractFunction/extractFunction14.ts index 53cabbe600f..86f8c9b5b63 100644 --- a/tests/baselines/reference/extractFunction/extractFunction14.ts +++ b/tests/baselines/reference/extractFunction/extractFunction14.ts @@ -33,6 +33,7 @@ function F(t1: T) { /*RENAME*/newFunction(t1, t2); } } + function newFunction(t1: T, t2: T) { t1.toString(); t2.toString(); diff --git a/tests/baselines/reference/extractFunction/extractFunction15.ts b/tests/baselines/reference/extractFunction/extractFunction15.ts index a09383282aa..3b291f4d86c 100644 --- a/tests/baselines/reference/extractFunction/extractFunction15.ts +++ b/tests/baselines/reference/extractFunction/extractFunction15.ts @@ -30,6 +30,7 @@ function F(t1: T) { /*RENAME*/newFunction(t2); } } + function newFunction(t2: U) { t2.toString(); } diff --git a/tests/baselines/reference/extractFunction/extractFunction16.ts b/tests/baselines/reference/extractFunction/extractFunction16.ts index 79c72f31198..5800fa6945b 100644 --- a/tests/baselines/reference/extractFunction/extractFunction16.ts +++ b/tests/baselines/reference/extractFunction/extractFunction16.ts @@ -14,6 +14,7 @@ function F() { function F() { const array: T[] = /*RENAME*/newFunction(); } + function newFunction(): T[] { return []; } diff --git a/tests/baselines/reference/extractFunction/extractFunction17.ts b/tests/baselines/reference/extractFunction/extractFunction17.ts index 733b1b27623..45d9953fb95 100644 --- a/tests/baselines/reference/extractFunction/extractFunction17.ts +++ b/tests/baselines/reference/extractFunction/extractFunction17.ts @@ -20,6 +20,7 @@ class C { /*RENAME*/newFunction(t1); } } + function newFunction(t1: T1) { t1.toString(); } diff --git a/tests/baselines/reference/extractFunction/extractFunction18.ts b/tests/baselines/reference/extractFunction/extractFunction18.ts index 8c44de12981..bdfcce6bbdc 100644 --- a/tests/baselines/reference/extractFunction/extractFunction18.ts +++ b/tests/baselines/reference/extractFunction/extractFunction18.ts @@ -20,6 +20,7 @@ class C { /*RENAME*/newFunction(t1); } } + function newFunction(t1: T1) { t1.toString(); } diff --git a/tests/baselines/reference/extractFunction/extractFunction19.ts b/tests/baselines/reference/extractFunction/extractFunction19.ts index 3a2723513f4..0b3192a49fb 100644 --- a/tests/baselines/reference/extractFunction/extractFunction19.ts +++ b/tests/baselines/reference/extractFunction/extractFunction19.ts @@ -14,6 +14,7 @@ function F(v: V) { function F(v: V) { /*RENAME*/newFunction(v); } + function newFunction(v: V) { v.toString(); } diff --git a/tests/baselines/reference/extractFunction/extractFunction2.ts b/tests/baselines/reference/extractFunction/extractFunction2.ts index 3872812b312..be72a7fd52f 100644 --- a/tests/baselines/reference/extractFunction/extractFunction2.ts +++ b/tests/baselines/reference/extractFunction/extractFunction2.ts @@ -78,6 +78,7 @@ namespace A { } } } + function newFunction(x: number, foo: () => void) { let y = 5; let z = x; diff --git a/tests/baselines/reference/extractFunction/extractFunction20.js b/tests/baselines/reference/extractFunction/extractFunction20.js index b65d3dae5da..17bef1c6044 100644 --- a/tests/baselines/reference/extractFunction/extractFunction20.js +++ b/tests/baselines/reference/extractFunction/extractFunction20.js @@ -22,6 +22,7 @@ const _ = class { return /*RENAME*/newFunction(); } } + function newFunction() { let a1 = { x: 1 }; return a1.x + 10; diff --git a/tests/baselines/reference/extractFunction/extractFunction20.ts b/tests/baselines/reference/extractFunction/extractFunction20.ts index 1fe72020ad7..ce09d4457d3 100644 --- a/tests/baselines/reference/extractFunction/extractFunction20.ts +++ b/tests/baselines/reference/extractFunction/extractFunction20.ts @@ -22,6 +22,7 @@ const _ = class { return /*RENAME*/newFunction(); } } + function newFunction() { let a1 = { x: 1 }; return a1.x + 10; diff --git a/tests/baselines/reference/extractFunction/extractFunction21.js b/tests/baselines/reference/extractFunction/extractFunction21.js index 4454f36ac62..08c4512fee7 100644 --- a/tests/baselines/reference/extractFunction/extractFunction21.js +++ b/tests/baselines/reference/extractFunction/extractFunction21.js @@ -20,6 +20,7 @@ function foo() { x = /*RENAME*/newFunction(x); return; } + function newFunction(x) { x++; return x; diff --git a/tests/baselines/reference/extractFunction/extractFunction21.ts b/tests/baselines/reference/extractFunction/extractFunction21.ts index 530a10bea95..4adb05f3bf1 100644 --- a/tests/baselines/reference/extractFunction/extractFunction21.ts +++ b/tests/baselines/reference/extractFunction/extractFunction21.ts @@ -20,6 +20,7 @@ function foo() { x = /*RENAME*/newFunction(x); return; } + function newFunction(x: number) { x++; return x; diff --git a/tests/baselines/reference/extractFunction/extractFunction22.js b/tests/baselines/reference/extractFunction/extractFunction22.js index 60891105c6e..0fb69c87b04 100644 --- a/tests/baselines/reference/extractFunction/extractFunction22.js +++ b/tests/baselines/reference/extractFunction/extractFunction22.js @@ -26,6 +26,7 @@ function test() { return /*RENAME*/newFunction(); } } + function newFunction() { return 1; } diff --git a/tests/baselines/reference/extractFunction/extractFunction22.ts b/tests/baselines/reference/extractFunction/extractFunction22.ts index 60891105c6e..0fb69c87b04 100644 --- a/tests/baselines/reference/extractFunction/extractFunction22.ts +++ b/tests/baselines/reference/extractFunction/extractFunction22.ts @@ -26,6 +26,7 @@ function test() { return /*RENAME*/newFunction(); } } + function newFunction() { return 1; } diff --git a/tests/baselines/reference/extractFunction/extractFunction23.ts b/tests/baselines/reference/extractFunction/extractFunction23.ts index 3092d6490ba..b3730a5b54f 100644 --- a/tests/baselines/reference/extractFunction/extractFunction23.ts +++ b/tests/baselines/reference/extractFunction/extractFunction23.ts @@ -38,6 +38,7 @@ namespace NS { } function M3() { } } + function newFunction() { return 1; } diff --git a/tests/baselines/reference/extractFunction/extractFunction24.js b/tests/baselines/reference/extractFunction/extractFunction24.js index dbac567afc6..2c1d353f51a 100644 --- a/tests/baselines/reference/extractFunction/extractFunction24.js +++ b/tests/baselines/reference/extractFunction/extractFunction24.js @@ -38,6 +38,7 @@ function Outer() { } function M3() { } } + function newFunction() { return 1; } diff --git a/tests/baselines/reference/extractFunction/extractFunction24.ts b/tests/baselines/reference/extractFunction/extractFunction24.ts index dbac567afc6..2c1d353f51a 100644 --- a/tests/baselines/reference/extractFunction/extractFunction24.ts +++ b/tests/baselines/reference/extractFunction/extractFunction24.ts @@ -38,6 +38,7 @@ function Outer() { } function M3() { } } + function newFunction() { return 1; } diff --git a/tests/baselines/reference/extractFunction/extractFunction26.js b/tests/baselines/reference/extractFunction/extractFunction26.js index c05af641d4b..2c821c05ad1 100644 --- a/tests/baselines/reference/extractFunction/extractFunction26.js +++ b/tests/baselines/reference/extractFunction/extractFunction26.js @@ -26,6 +26,7 @@ class C { } M3() { } } + function newFunction() { return 1; } diff --git a/tests/baselines/reference/extractFunction/extractFunction26.ts b/tests/baselines/reference/extractFunction/extractFunction26.ts index 37eba24bfde..300686c12ab 100644 --- a/tests/baselines/reference/extractFunction/extractFunction26.ts +++ b/tests/baselines/reference/extractFunction/extractFunction26.ts @@ -26,6 +26,7 @@ class C { } M3() { } } + function newFunction() { return 1; } diff --git a/tests/baselines/reference/extractFunction/extractFunction27.js b/tests/baselines/reference/extractFunction/extractFunction27.js index 96bca6b24c5..702127b9d76 100644 --- a/tests/baselines/reference/extractFunction/extractFunction27.js +++ b/tests/baselines/reference/extractFunction/extractFunction27.js @@ -29,6 +29,7 @@ class C { constructor() { } M3() { } } + function newFunction() { return 1; } diff --git a/tests/baselines/reference/extractFunction/extractFunction27.ts b/tests/baselines/reference/extractFunction/extractFunction27.ts index 335d74e002d..1acbe67707a 100644 --- a/tests/baselines/reference/extractFunction/extractFunction27.ts +++ b/tests/baselines/reference/extractFunction/extractFunction27.ts @@ -29,6 +29,7 @@ class C { constructor() { } M3() { } } + function newFunction() { return 1; } diff --git a/tests/baselines/reference/extractFunction/extractFunction28.js b/tests/baselines/reference/extractFunction/extractFunction28.js index a82b864448d..cf0742626dd 100644 --- a/tests/baselines/reference/extractFunction/extractFunction28.js +++ b/tests/baselines/reference/extractFunction/extractFunction28.js @@ -29,6 +29,7 @@ class C { M3() { } constructor() { } } + function newFunction() { return 1; } diff --git a/tests/baselines/reference/extractFunction/extractFunction28.ts b/tests/baselines/reference/extractFunction/extractFunction28.ts index bde2661f934..f15d7956f1c 100644 --- a/tests/baselines/reference/extractFunction/extractFunction28.ts +++ b/tests/baselines/reference/extractFunction/extractFunction28.ts @@ -29,6 +29,7 @@ class C { M3() { } constructor() { } } + function newFunction() { return 1; } diff --git a/tests/baselines/reference/extractFunction/extractFunction3.ts b/tests/baselines/reference/extractFunction/extractFunction3.ts index 9c4c1aaa9d7..7a481e76cfa 100644 --- a/tests/baselines/reference/extractFunction/extractFunction3.ts +++ b/tests/baselines/reference/extractFunction/extractFunction3.ts @@ -73,6 +73,7 @@ namespace A { } } } + function* newFunction(z: number, foo: () => void) { let y = 5; yield z; diff --git a/tests/baselines/reference/extractFunction/extractFunction30.ts b/tests/baselines/reference/extractFunction/extractFunction30.ts index b57b48c30a9..f90548c333c 100644 --- a/tests/baselines/reference/extractFunction/extractFunction30.ts +++ b/tests/baselines/reference/extractFunction/extractFunction30.ts @@ -14,6 +14,7 @@ function F() { function F() { /*RENAME*/newFunction(); } + function newFunction() { let t: T; } diff --git a/tests/baselines/reference/extractFunction/extractFunction31.ts b/tests/baselines/reference/extractFunction/extractFunction31.ts index d7252a14011..2dea17689b6 100644 --- a/tests/baselines/reference/extractFunction/extractFunction31.ts +++ b/tests/baselines/reference/extractFunction/extractFunction31.ts @@ -37,6 +37,7 @@ namespace N { f = /*RENAME*/newFunction(f); } } + function newFunction(f: () => number) { f = function(): number { return N.value; diff --git a/tests/baselines/reference/extractFunction/extractFunction32.ts b/tests/baselines/reference/extractFunction/extractFunction32.ts index 4070763b79f..720d0b227b0 100644 --- a/tests/baselines/reference/extractFunction/extractFunction32.ts +++ b/tests/baselines/reference/extractFunction/extractFunction32.ts @@ -37,6 +37,7 @@ namespace N { /*RENAME*/newFunction(); } } + function newFunction() { var c = class { M() { diff --git a/tests/baselines/reference/extractFunction/extractFunction33.js b/tests/baselines/reference/extractFunction/extractFunction33.js index 46c0f176b56..cc027a14b6c 100644 --- a/tests/baselines/reference/extractFunction/extractFunction33.js +++ b/tests/baselines/reference/extractFunction/extractFunction33.js @@ -14,6 +14,7 @@ function F() { function F() { /*RENAME*/newFunction(); } + function newFunction() { function G() { } } diff --git a/tests/baselines/reference/extractFunction/extractFunction33.ts b/tests/baselines/reference/extractFunction/extractFunction33.ts index 46c0f176b56..cc027a14b6c 100644 --- a/tests/baselines/reference/extractFunction/extractFunction33.ts +++ b/tests/baselines/reference/extractFunction/extractFunction33.ts @@ -14,6 +14,7 @@ function F() { function F() { /*RENAME*/newFunction(); } + function newFunction() { function G() { } } diff --git a/tests/baselines/reference/extractFunction/extractFunction4.ts b/tests/baselines/reference/extractFunction/extractFunction4.ts index 4108976b6b3..46aad65c68c 100644 --- a/tests/baselines/reference/extractFunction/extractFunction4.ts +++ b/tests/baselines/reference/extractFunction/extractFunction4.ts @@ -81,6 +81,7 @@ namespace A { } } } + async function newFunction(z: number, z1: any, foo: () => void) { let y = 5; if (z) { diff --git a/tests/baselines/reference/extractFunction/extractFunction5.ts b/tests/baselines/reference/extractFunction/extractFunction5.ts index 3122ba24553..085a73fdf93 100644 --- a/tests/baselines/reference/extractFunction/extractFunction5.ts +++ b/tests/baselines/reference/extractFunction/extractFunction5.ts @@ -89,6 +89,7 @@ namespace A { } } } + function newFunction(x: number, a: number) { let y = 5; let z = x; diff --git a/tests/baselines/reference/extractFunction/extractFunction6.ts b/tests/baselines/reference/extractFunction/extractFunction6.ts index a01cb25e061..613635c658a 100644 --- a/tests/baselines/reference/extractFunction/extractFunction6.ts +++ b/tests/baselines/reference/extractFunction/extractFunction6.ts @@ -93,6 +93,7 @@ namespace A { } } } + function newFunction(x: number, a: number) { let y = 5; let z = x; diff --git a/tests/baselines/reference/extractFunction/extractFunction7.ts b/tests/baselines/reference/extractFunction/extractFunction7.ts index 4111558904c..0f57a0cfba8 100644 --- a/tests/baselines/reference/extractFunction/extractFunction7.ts +++ b/tests/baselines/reference/extractFunction/extractFunction7.ts @@ -103,6 +103,7 @@ namespace A { } } } + function newFunction(x: number, a: number) { let y = 5; let z = x; diff --git a/tests/baselines/reference/extractFunction/extractFunction9.ts b/tests/baselines/reference/extractFunction/extractFunction9.ts index 7db12096cbc..3df391c1fae 100644 --- a/tests/baselines/reference/extractFunction/extractFunction9.ts +++ b/tests/baselines/reference/extractFunction/extractFunction9.ts @@ -59,6 +59,7 @@ namespace A { } } } + function newFunction() { let a1: A.I = { x: 1 }; return a1.x + 10; diff --git a/tests/baselines/reference/extractFunction/extractFunction_PreserveTrivia.js b/tests/baselines/reference/extractFunction/extractFunction_PreserveTrivia.js index b5e4bc76c6e..b10a04e9ef0 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_PreserveTrivia.js +++ b/tests/baselines/reference/extractFunction/extractFunction_PreserveTrivia.js @@ -12,6 +12,7 @@ var q = /*b*/ //c var q = /*b*/ //c /*d*/ /*RENAME*/newFunction() /*k*/ //l /*m*/; /*n*/ //o + function newFunction() { return 1 /*e*/ //f /*g*/ + /*h*/ //i diff --git a/tests/baselines/reference/extractFunction/extractFunction_PreserveTrivia.ts b/tests/baselines/reference/extractFunction/extractFunction_PreserveTrivia.ts index b5e4bc76c6e..b10a04e9ef0 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_PreserveTrivia.ts +++ b/tests/baselines/reference/extractFunction/extractFunction_PreserveTrivia.ts @@ -12,6 +12,7 @@ var q = /*b*/ //c var q = /*b*/ //c /*d*/ /*RENAME*/newFunction() /*k*/ //l /*m*/; /*n*/ //o + function newFunction() { return 1 /*e*/ //f /*g*/ + /*h*/ //i diff --git a/tests/baselines/reference/extractFunction/extractFunction_RepeatedSubstitution.ts b/tests/baselines/reference/extractFunction/extractFunction_RepeatedSubstitution.ts index 68cc7d2248a..52ccce68059 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_RepeatedSubstitution.ts +++ b/tests/baselines/reference/extractFunction/extractFunction_RepeatedSubstitution.ts @@ -17,6 +17,7 @@ namespace X { export const j = 10; export const y = /*RENAME*/newFunction(); } + function newFunction() { return X.j * X.j; } diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ShorthandProperty.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ShorthandProperty.js index 67b4f64290c..e8250613625 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ShorthandProperty.js +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ShorthandProperty.js @@ -21,6 +21,7 @@ function f() { let x = /*RENAME*/newFunction(); return { x }; } + function newFunction() { let x; return x; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ShorthandProperty.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ShorthandProperty.ts index 67b4f64290c..e8250613625 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ShorthandProperty.ts +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_ShorthandProperty.ts @@ -21,6 +21,7 @@ function f() { let x = /*RENAME*/newFunction(); return { x }; } + function newFunction() { let x; return x; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_NoType.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_NoType.js index 1da5a568333..a8629d2907c 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_NoType.js +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_NoType.js @@ -27,6 +27,7 @@ function f() { ({ x, a } = /*RENAME*/newFunction(a)); a; x; } + function newFunction(a) { const x = 1; a++; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_NoType.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_NoType.ts index f93f43ceebf..c70dbe95c7b 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_NoType.ts +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_NoType.ts @@ -27,6 +27,7 @@ function f() { ({ x, a } = /*RENAME*/newFunction(a)); a; x; } + function newFunction(a: number) { const x = 1; a++; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_Type.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_Type.ts index ec846f7f288..3c0912061aa 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_Type.ts +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Const_Type.ts @@ -27,6 +27,7 @@ function f() { ({ x, a } = /*RENAME*/newFunction(a)); a; x; } + function newFunction(a: number) { const x: number = 1; a++; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_LiteralType1.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_LiteralType1.ts index 50bad34efce..06de0fd4f36 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_LiteralType1.ts +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_LiteralType1.ts @@ -27,6 +27,7 @@ function f() { ({ x, a } = /*RENAME*/newFunction(a)); a; x; } + function newFunction(a: number) { let x: 0o10 | 10 | 0b10 = 10; a++; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_LiteralType2.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_LiteralType2.ts index 2df8ab67e9f..4679b89f068 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_LiteralType2.ts +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_LiteralType2.ts @@ -27,6 +27,7 @@ function f() { ({ x, a } = /*RENAME*/newFunction(a)); a; x; } + function newFunction(a: number) { let x: "a" | 'b' = 'a'; a++; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_NoType.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_NoType.js index 2f298c8719f..a86870d72a3 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_NoType.js +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_NoType.js @@ -27,6 +27,7 @@ function f() { ({ x, a } = /*RENAME*/newFunction(a)); a; x; } + function newFunction(a) { let x = 1; a++; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_NoType.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_NoType.ts index e4afefa9da6..9b711765c95 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_NoType.ts +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_NoType.ts @@ -27,6 +27,7 @@ function f() { ({ x, a } = /*RENAME*/newFunction(a)); a; x; } + function newFunction(a: number) { let x = 1; a++; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_Type.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_Type.ts index 795effbeb7e..652faab4890 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_Type.ts +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_Type.ts @@ -27,6 +27,7 @@ function f() { ({ x, a } = /*RENAME*/newFunction(a)); a; x; } + function newFunction(a: number) { let x: number = 1; a++; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_TypeWithComments.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_TypeWithComments.ts index 53599c26d08..71c4d9b79ff 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_TypeWithComments.ts +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Let_TypeWithComments.ts @@ -27,6 +27,7 @@ function f() { ({ x, a } = /*RENAME*/newFunction(a)); a; x; } + function newFunction(a: number) { let x: /*A*/ "a" /*B*/ | /*C*/ 'b' /*D*/ = 'a'; a++; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed1.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed1.js index c36557847f7..5de10b2cf76 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed1.js +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed1.js @@ -30,6 +30,7 @@ function f() { ({ x, y, a } = /*RENAME*/newFunction(a)); a; x; y; } + function newFunction(a) { const x = 1; let y = 2; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed1.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed1.ts index eaeb781bc48..d4da8ffca7b 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed1.ts +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed1.ts @@ -30,6 +30,7 @@ function f() { ({ x, y, a } = /*RENAME*/newFunction(a)); a; x; y; } + function newFunction(a: number) { const x = 1; let y = 2; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed2.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed2.js index 2d1151a549c..e1526a77ffd 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed2.js +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed2.js @@ -30,6 +30,7 @@ function f() { ({ x, y, a } = /*RENAME*/newFunction(a)); a; x; y; } + function newFunction(a) { var x = 1; let y = 2; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed2.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed2.ts index 9466b5dc37f..ec3d62c039b 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed2.ts +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed2.ts @@ -30,6 +30,7 @@ function f() { ({ x, y, a } = /*RENAME*/newFunction(a)); a; x; y; } + function newFunction(a: number) { var x = 1; let y = 2; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed3.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed3.ts index 604d2a33c43..b2c53e3f160 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed3.ts +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Mixed3.ts @@ -30,6 +30,7 @@ function f() { ({ x, y, a } = /*RENAME*/newFunction(a)); a; x; y; } + function newFunction(a: number) { let x: number = 1; let y = 2; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_UnionUndefined.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_UnionUndefined.ts index 0cf71e45e28..b76bf6c4999 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_UnionUndefined.ts +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_UnionUndefined.ts @@ -33,6 +33,7 @@ function f() { ({ x, y, z, a } = /*RENAME*/newFunction(a)); a; x; y; z; } + function newFunction(a: number) { let x: number | undefined = 1; let y: undefined | number = 2; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Var.js b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Var.js index 25e910713d8..6a7b821e5b1 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Var.js +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Var.js @@ -27,6 +27,7 @@ function f() { ({ x, a } = /*RENAME*/newFunction(a)); a; x; } + function newFunction(a) { var x = 1; a++; diff --git a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Var.ts b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Var.ts index e215e3d0978..e9cbe7ad345 100644 --- a/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Var.ts +++ b/tests/baselines/reference/extractFunction/extractFunction_VariableDeclaration_Writes_Var.ts @@ -27,6 +27,7 @@ function f() { ({ x, a } = /*RENAME*/newFunction(a)); a; x; } + function newFunction(a: number) { var x = 1; a++; diff --git a/tests/cases/fourslash/extract-method-empty-namespace.ts b/tests/cases/fourslash/extract-method-empty-namespace.ts index bef4cdd12fe..1655efccbb8 100644 --- a/tests/cases/fourslash/extract-method-empty-namespace.ts +++ b/tests/cases/fourslash/extract-method-empty-namespace.ts @@ -12,6 +12,7 @@ edit.applyRefactor({ newContent: `function f() { /*RENAME*/newFunction(); } + function newFunction() { namespace N { } } diff --git a/tests/cases/fourslash/extract-method-formatting.ts b/tests/cases/fourslash/extract-method-formatting.ts index d4c2836e815..d1f550f794e 100644 --- a/tests/cases/fourslash/extract-method-formatting.ts +++ b/tests/cases/fourslash/extract-method-formatting.ts @@ -13,6 +13,7 @@ edit.applyRefactor({ newContent: `function f(x: number): number { return /*RENAME*/newFunction(x); } + function newFunction(x: number) { switch (x) { case 0: diff --git a/tests/cases/fourslash/extract-method-uniqueName.ts b/tests/cases/fourslash/extract-method-uniqueName.ts index da4c68cfb7e..a02b2c5ec96 100644 --- a/tests/cases/fourslash/extract-method-uniqueName.ts +++ b/tests/cases/fourslash/extract-method-uniqueName.ts @@ -13,6 +13,7 @@ edit.applyRefactor({ newContent: `// newFunction /*RENAME*/newFunction_1(); + function newFunction_1() { 1 + 1; } diff --git a/tests/cases/fourslash/extract-method10.ts b/tests/cases/fourslash/extract-method10.ts index ed92e6b06ac..d2b9aeb0123 100644 --- a/tests/cases/fourslash/extract-method10.ts +++ b/tests/cases/fourslash/extract-method10.ts @@ -11,6 +11,7 @@ edit.applyRefactor({ newContent: `export {}; // Make this a module (x => x)(/*RENAME*/newFunction())(1); + function newFunction(): (x: any) => any { return x => x; } diff --git a/tests/cases/fourslash/extract-method14.ts b/tests/cases/fourslash/extract-method14.ts index ddfd8cbcbd6..11ea1f1b3fd 100644 --- a/tests/cases/fourslash/extract-method14.ts +++ b/tests/cases/fourslash/extract-method14.ts @@ -22,6 +22,7 @@ edit.applyRefactor({ ({ __return, i } = /*RENAME*/newFunction(i)); return __return; } + function newFunction(i) { return { __return: i++, i }; } diff --git a/tests/cases/fourslash/extract-method15.ts b/tests/cases/fourslash/extract-method15.ts index e46ff39ad6a..1b33a46b9a4 100644 --- a/tests/cases/fourslash/extract-method15.ts +++ b/tests/cases/fourslash/extract-method15.ts @@ -18,6 +18,7 @@ edit.applyRefactor({ var i = 10; i = /*RENAME*/newFunction(i); } + function newFunction(i: number) { i++; return i; diff --git a/tests/cases/fourslash/extract-method18.ts b/tests/cases/fourslash/extract-method18.ts index d53e79f4930..0a488a04106 100644 --- a/tests/cases/fourslash/extract-method18.ts +++ b/tests/cases/fourslash/extract-method18.ts @@ -18,6 +18,7 @@ edit.applyRefactor({ const x = { m: 1 }; /*RENAME*/newFunction(x); } + function newFunction(x: { m: number; }) { x.m = 3; } diff --git a/tests/cases/fourslash/extract-method2.ts b/tests/cases/fourslash/extract-method2.ts index 7f197d4775b..419d6379075 100644 --- a/tests/cases/fourslash/extract-method2.ts +++ b/tests/cases/fourslash/extract-method2.ts @@ -24,6 +24,7 @@ edit.applyRefactor({ } } } + function newFunction(m: number, j: string, k: { x: string; }) { return m + j + k; } diff --git a/tests/cases/fourslash/extract-method24.ts b/tests/cases/fourslash/extract-method24.ts index 8c750edd9f9..66ca5ecb227 100644 --- a/tests/cases/fourslash/extract-method24.ts +++ b/tests/cases/fourslash/extract-method24.ts @@ -17,6 +17,7 @@ edit.applyRefactor({ let x = 0; console.log(/*RENAME*/newFunction(a, x)); } + function newFunction(a: number[], x: number): any { return a[x]; } diff --git a/tests/cases/fourslash/extract-method7.ts b/tests/cases/fourslash/extract-method7.ts index 2998b6bbee3..38bc86cb5dc 100644 --- a/tests/cases/fourslash/extract-method7.ts +++ b/tests/cases/fourslash/extract-method7.ts @@ -14,6 +14,7 @@ edit.applyRefactor({ newContent: `function fn(x = /*RENAME*/newFunction()) { } + function newFunction() { return 3; } From f35764d4ecf69e5c6be292fa7018fdc6f27f70c9 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 12 Oct 2017 14:28:34 -0700 Subject: [PATCH 126/312] Fix duplicated JSDoc comments Incorporate suppressLeadingAndTrailingTrivia just added by @amcasey. --- src/services/refactors/annotateWithTypeFromJSDoc.ts | 10 +++++++--- tests/cases/fourslash/annotateWithTypeFromJSDoc12.ts | 3 --- tests/cases/fourslash/annotateWithTypeFromJSDoc5.ts | 1 - tests/cases/fourslash/annotateWithTypeFromJSDoc6.ts | 1 - 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/services/refactors/annotateWithTypeFromJSDoc.ts b/src/services/refactors/annotateWithTypeFromJSDoc.ts index bc6dcd073bf..1e32df4a51a 100644 --- a/src/services/refactors/annotateWithTypeFromJSDoc.ts +++ b/src/services/refactors/annotateWithTypeFromJSDoc.ts @@ -62,14 +62,16 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { const sourceFile = context.file; const token = getTokenAtPosition(sourceFile, context.startPosition, /*includeJsDocComment*/ false); const decl = findAncestor(token, isDeclarationWithType); - const jsdocType = getJSDocReturnType(decl) || getJSDocType(decl); + const jsdocType = getJSDocType(decl); if (!decl || !jsdocType || decl.type) { Debug.fail(`!decl || !jsdocType || decl.type: !${decl} || !${jsdocType} || ${decl.type}`); return undefined; } const changeTracker = textChanges.ChangeTracker.fromContext(context); - changeTracker.replaceRange(sourceFile, { pos: decl.getStart(), end: decl.end }, addType(decl, transformJSDocType(jsdocType) as TypeNode)); + const declarationWithType = addType(decl, transformJSDocType(jsdocType) as TypeNode); + suppressLeadingAndTrailingTrivia(declarationWithType); + changeTracker.replaceRange(sourceFile, { pos: decl.getStart(), end: decl.end }, declarationWithType); return { edits: changeTracker.getChanges(), renameFilename: undefined, @@ -87,7 +89,9 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { const token = getTokenAtPosition(sourceFile, context.startPosition, /*includeJsDocComment*/ false); const decl = findAncestor(token, isFunctionLikeDeclaration); const changeTracker = textChanges.ChangeTracker.fromContext(context); - changeTracker.replaceRange(sourceFile, { pos: decl.getStart(), end: decl.end }, addTypesToFunctionLike(decl)); + const functionWithType = addTypesToFunctionLike(decl); + suppressLeadingAndTrailingTrivia(functionWithType); + changeTracker.replaceRange(sourceFile, { pos: decl.getStart(), end: decl.end }, functionWithType); return { edits: changeTracker.getChanges(), renameFilename: undefined, diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc12.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc12.ts index c3c1aad5a90..e541bad4e4f 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc12.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc12.ts @@ -10,9 +10,6 @@ verify.applicableRefactorAvailableAtMarker('1'); verify.fileAfterApplyingRefactorAtMarker('1', `class C { - /** - * @return {...*} - */ /** * @return {...*} */ diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc5.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc5.ts index 1f15bf59924..83e0888ddf5 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc5.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc5.ts @@ -9,7 +9,6 @@ verify.applicableRefactorAvailableAtMarker('1'); verify.fileAfterApplyingRefactorAtMarker('1', `class C { - /** @type {number | null} */ /** @type {number | null} */ p: number | null = null; }`, 'Annotate with type from JSDoc', 'annotate'); diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc6.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc6.ts index 91bc1523ea3..f6fce6c449f 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc6.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc6.ts @@ -9,7 +9,6 @@ verify.applicableRefactorAvailableAtMarker('1'); verify.fileAfterApplyingRefactorAtMarker('1', `declare class C { - /** @type {number | null} */ /** @type {number | null} */ p: number | null; }`, 'Annotate with type from JSDoc', 'annotate'); From de0e475c64a5dbba72d22c0edf6ce5552a5a0ebe Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 12 Oct 2017 15:05:04 -0700 Subject: [PATCH 127/312] Recreate old decorator metadata behavior (#19089) * Emulate pre 2.4 metadata behavior of eliding null and undefined from unions without strictNullChecks * Accept baseline * Update comment * Update for second old baseline * Respect strict --- src/compiler/transformers/ts.ts | 14 ++++++-- .../decoratorMetadataNoStrictNull.js | 32 +++++++++++++++++++ .../decoratorMetadataNoStrictNull.symbols | 18 +++++++++++ .../decoratorMetadataNoStrictNull.types | 20 ++++++++++++ .../reference/metadataOfClassFromAlias.js | 2 +- .../reference/metadataOfUnionWithNull.js | 16 +++++----- .../compiler/decoratorMetadataNoStrictNull.ts | 8 +++++ 7 files changed, 99 insertions(+), 11 deletions(-) create mode 100644 tests/baselines/reference/decoratorMetadataNoStrictNull.js create mode 100644 tests/baselines/reference/decoratorMetadataNoStrictNull.symbols create mode 100644 tests/baselines/reference/decoratorMetadataNoStrictNull.types create mode 100644 tests/cases/compiler/decoratorMetadataNoStrictNull.ts diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index e67918fd696..ba4b5fcdf52 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -45,6 +45,7 @@ namespace ts { const resolver = context.getEmitResolver(); const compilerOptions = context.getCompilerOptions(); + const strictNullChecks = typeof compilerOptions.strictNullChecks === "undefined" ? compilerOptions.strict : compilerOptions.strictNullChecks; const languageVersion = getEmitScriptTarget(compilerOptions); const moduleKind = getEmitModuleKind(compilerOptions); @@ -1869,7 +1870,16 @@ namespace ts { // Note when updating logic here also update getEntityNameForDecoratorMetadata // so that aliases can be marked as referenced let serializedUnion: SerializedTypeNode; - for (const typeNode of node.types) { + for (let typeNode of node.types) { + while (typeNode.kind === SyntaxKind.ParenthesizedType) { + typeNode = (typeNode as ParenthesizedTypeNode).type; // Skip parens if need be + } + if (typeNode.kind === SyntaxKind.NeverKeyword) { + continue; // Always elide `never` from the union/intersection if possible + } + if (!strictNullChecks && (typeNode.kind === SyntaxKind.NullKeyword || typeNode.kind === SyntaxKind.UndefinedKeyword)) { + continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks + } const serializedIndividual = serializeTypeNode(typeNode); if (isIdentifier(serializedIndividual) && serializedIndividual.escapedText === "Object") { @@ -1893,7 +1903,7 @@ namespace ts { } // If we were able to find common type, use it - return serializedUnion; + return serializedUnion || createVoidZero(); // Fallback is only hit if all union constituients are null/undefined/never } /** diff --git a/tests/baselines/reference/decoratorMetadataNoStrictNull.js b/tests/baselines/reference/decoratorMetadataNoStrictNull.js new file mode 100644 index 00000000000..dada68f0960 --- /dev/null +++ b/tests/baselines/reference/decoratorMetadataNoStrictNull.js @@ -0,0 +1,32 @@ +//// [decoratorMetadataNoStrictNull.ts] +const dec = (obj: {}, prop: string) => undefined + +class Foo { + @dec public foo: string | null; + @dec public bar: string; +} + +//// [decoratorMetadataNoStrictNull.js] +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var dec = function (obj, prop) { return undefined; }; +var Foo = /** @class */ (function () { + function Foo() { + } + __decorate([ + dec, + __metadata("design:type", String) + ], Foo.prototype, "foo"); + __decorate([ + dec, + __metadata("design:type", String) + ], Foo.prototype, "bar"); + return Foo; +}()); diff --git a/tests/baselines/reference/decoratorMetadataNoStrictNull.symbols b/tests/baselines/reference/decoratorMetadataNoStrictNull.symbols new file mode 100644 index 00000000000..32a6d08f024 --- /dev/null +++ b/tests/baselines/reference/decoratorMetadataNoStrictNull.symbols @@ -0,0 +1,18 @@ +=== tests/cases/compiler/decoratorMetadataNoStrictNull.ts === +const dec = (obj: {}, prop: string) => undefined +>dec : Symbol(dec, Decl(decoratorMetadataNoStrictNull.ts, 0, 5)) +>obj : Symbol(obj, Decl(decoratorMetadataNoStrictNull.ts, 0, 13)) +>prop : Symbol(prop, Decl(decoratorMetadataNoStrictNull.ts, 0, 21)) +>undefined : Symbol(undefined) + +class Foo { +>Foo : Symbol(Foo, Decl(decoratorMetadataNoStrictNull.ts, 0, 48)) + + @dec public foo: string | null; +>dec : Symbol(dec, Decl(decoratorMetadataNoStrictNull.ts, 0, 5)) +>foo : Symbol(Foo.foo, Decl(decoratorMetadataNoStrictNull.ts, 2, 11)) + + @dec public bar: string; +>dec : Symbol(dec, Decl(decoratorMetadataNoStrictNull.ts, 0, 5)) +>bar : Symbol(Foo.bar, Decl(decoratorMetadataNoStrictNull.ts, 3, 33)) +} diff --git a/tests/baselines/reference/decoratorMetadataNoStrictNull.types b/tests/baselines/reference/decoratorMetadataNoStrictNull.types new file mode 100644 index 00000000000..981efe6e50b --- /dev/null +++ b/tests/baselines/reference/decoratorMetadataNoStrictNull.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/decoratorMetadataNoStrictNull.ts === +const dec = (obj: {}, prop: string) => undefined +>dec : (obj: {}, prop: string) => any +>(obj: {}, prop: string) => undefined : (obj: {}, prop: string) => any +>obj : {} +>prop : string +>undefined : undefined + +class Foo { +>Foo : Foo + + @dec public foo: string | null; +>dec : (obj: {}, prop: string) => any +>foo : string +>null : null + + @dec public bar: string; +>dec : (obj: {}, prop: string) => any +>bar : string +} diff --git a/tests/baselines/reference/metadataOfClassFromAlias.js b/tests/baselines/reference/metadataOfClassFromAlias.js index 307702cd7bf..77ae5c33898 100644 --- a/tests/baselines/reference/metadataOfClassFromAlias.js +++ b/tests/baselines/reference/metadataOfClassFromAlias.js @@ -43,7 +43,7 @@ var ClassA = /** @class */ (function () { } __decorate([ annotation(), - __metadata("design:type", Object) + __metadata("design:type", auxiliry_1.SomeClass) ], ClassA.prototype, "array", void 0); return ClassA; }()); diff --git a/tests/baselines/reference/metadataOfUnionWithNull.js b/tests/baselines/reference/metadataOfUnionWithNull.js index 80d24709b73..7bf9aeb8650 100644 --- a/tests/baselines/reference/metadataOfUnionWithNull.js +++ b/tests/baselines/reference/metadataOfUnionWithNull.js @@ -63,15 +63,15 @@ var B = /** @class */ (function () { } __decorate([ PropDeco, - __metadata("design:type", Object) + __metadata("design:type", String) ], B.prototype, "x"); __decorate([ PropDeco, - __metadata("design:type", Object) + __metadata("design:type", Boolean) ], B.prototype, "y"); __decorate([ PropDeco, - __metadata("design:type", Object) + __metadata("design:type", String) ], B.prototype, "z"); __decorate([ PropDeco, @@ -87,11 +87,11 @@ var B = /** @class */ (function () { ], B.prototype, "c"); __decorate([ PropDeco, - __metadata("design:type", Object) + __metadata("design:type", void 0) ], B.prototype, "d"); __decorate([ PropDeco, - __metadata("design:type", Object) + __metadata("design:type", typeof Symbol === "function" ? Symbol : Object) ], B.prototype, "e"); __decorate([ PropDeco, @@ -99,15 +99,15 @@ var B = /** @class */ (function () { ], B.prototype, "f"); __decorate([ PropDeco, - __metadata("design:type", Object) + __metadata("design:type", A) ], B.prototype, "g"); __decorate([ PropDeco, - __metadata("design:type", Object) + __metadata("design:type", B) ], B.prototype, "h"); __decorate([ PropDeco, - __metadata("design:type", Object) + __metadata("design:type", typeof Symbol === "function" ? Symbol : Object) ], B.prototype, "j"); return B; }()); diff --git a/tests/cases/compiler/decoratorMetadataNoStrictNull.ts b/tests/cases/compiler/decoratorMetadataNoStrictNull.ts new file mode 100644 index 00000000000..4ac608ebd74 --- /dev/null +++ b/tests/cases/compiler/decoratorMetadataNoStrictNull.ts @@ -0,0 +1,8 @@ +// @experimentalDecorators: true +// @emitDecoratorMetadata: true +const dec = (obj: {}, prop: string) => undefined + +class Foo { + @dec public foo: string | null; + @dec public bar: string; +} \ No newline at end of file From 6099b09a6ebf73dbd6ce9c10ef6f1e6b70c0e9b1 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 13 Oct 2017 07:17:17 -0700 Subject: [PATCH 128/312] Create source files lazily in tests (#19143) --- src/harness/harness.ts | 10 +++++++--- src/harness/unittests/moduleResolution.ts | 5 ++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index a0fb88213ed..a3789eb9ebf 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -844,9 +844,7 @@ namespace Harness { export const es2015DefaultLibFileName = "lib.es2015.d.ts"; // Cache of lib files from "built/local" - const libFileNameSourceFileMap = ts.createMapFromTemplate({ - [defaultLibFileName]: createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.es5.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest) - }); + let libFileNameSourceFileMap: ts.Map | undefined; // Cache of lib files from "tests/lib/" const testLibFileNameSourceFileMap = ts.createMap(); @@ -857,6 +855,12 @@ namespace Harness { return undefined; } + if (!libFileNameSourceFileMap) { + libFileNameSourceFileMap = ts.createMapFromTemplate({ + [defaultLibFileName]: createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.es5.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest) + }); + } + let sourceFile = libFileNameSourceFileMap.get(fileName); if (!sourceFile) { libFileNameSourceFileMap.set(fileName, sourceFile = createSourceFileAndAssertInvariants(fileName, IO.readFile(libFolder + fileName), ts.ScriptTarget.Latest)); diff --git a/src/harness/unittests/moduleResolution.ts b/src/harness/unittests/moduleResolution.ts index 0acbe9450bb..32301d6dccf 100644 --- a/src/harness/unittests/moduleResolution.ts +++ b/src/harness/unittests/moduleResolution.ts @@ -392,7 +392,7 @@ export = C; }); describe("Files with different casing", () => { - const library = createSourceFile("lib.d.ts", "", ScriptTarget.ES5); + let library: SourceFile; function test(files: Map, options: CompilerOptions, currentDirectory: string, useCaseSensitiveFileNames: boolean, rootFiles: string[], diagnosticCodes: number[]): void { const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames); if (!useCaseSensitiveFileNames) { @@ -406,6 +406,9 @@ export = C; const host: CompilerHost = { getSourceFile: (fileName: string, languageVersion: ScriptTarget) => { if (fileName === "lib.d.ts") { + if (!library) { + library = createSourceFile("lib.d.ts", "", ScriptTarget.ES5); + } return library; } const path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName))); From c3a2dc3f44e47a70f01c91fc4b29876bd7fa43d1 Mon Sep 17 00:00:00 2001 From: csigs Date: Fri, 13 Oct 2017 16:10:06 +0000 Subject: [PATCH 129/312] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 17108 ++++++++-------- .../diagnosticMessages.generated.json.lcl | 17108 ++++++++-------- 2 files changed, 17186 insertions(+), 17030 deletions(-) diff --git a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl index ccfe22a59ff..3c83950d4f3 100644 --- a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,8516 +1,8594 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - 或 <语言>-<区域> 形式。例如“{0}”或“{1}”。]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - 类型。]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()"。]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + 或 <语言>-<区域> 形式。例如“{0}”或“{1}”。]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + 类型。]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()"。]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl index 0db33b6bbe9..c25043edfa5 100644 --- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,8516 +1,8594 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - 또는 - 형식이어야 합니다. 예를 들어 '{0}' 또는 '{1}'입니다.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - 형식이어야 합니다.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()'를 사용하세요.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + 또는 - 형식이어야 합니다. 예를 들어 '{0}' 또는 '{1}'입니다.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + 형식이어야 합니다.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()'를 사용하세요.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From c83daa64811c7705318de6c35d23f76a9c24c744 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 13 Oct 2017 09:38:01 -0700 Subject: [PATCH 130/312] JSDoc->type refactor:Renames+improve never handling --- .../refactors/annotateWithTypeFromJSDoc.ts | 66 +++++++++---------- .../fourslash/annotateWithTypeFromJSDoc5.ts | 1 - .../fourslash/annotateWithTypeFromJSDoc6.ts | 1 - 3 files changed, 33 insertions(+), 35 deletions(-) diff --git a/src/services/refactors/annotateWithTypeFromJSDoc.ts b/src/services/refactors/annotateWithTypeFromJSDoc.ts index 1e32df4a51a..52d3fe30e8d 100644 --- a/src/services/refactors/annotateWithTypeFromJSDoc.ts +++ b/src/services/refactors/annotateWithTypeFromJSDoc.ts @@ -32,24 +32,25 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { const node = getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false); const decl = findAncestor(node, isDeclarationWithType); - if (decl && !decl.type) { - const type = getJSDocType(decl); - const isFunctionWithJSDoc = isFunctionLikeDeclaration(decl) && (getJSDocReturnType(decl) || decl.parameters.some(p => !!getJSDocType(p))); - const annotate = (isFunctionWithJSDoc || type && decl.kind === SyntaxKind.Parameter) ? annotateFunctionFromJSDoc : - type ? annotateTypeFromJSDoc : - undefined; - if (annotate) { - return [{ - name: annotate.name, - description: annotate.description, - actions: [ - { - description: annotate.description, - name: actionName - } - ] - }]; - } + if (!decl || decl.type) { + return undefined; + } + const jsdocType = getJSDocType(decl); + const isFunctionWithJSDoc = isFunctionLikeDeclaration(decl) && (getJSDocReturnType(decl) || decl.parameters.some(p => !!getJSDocType(p))); + const refactor = (isFunctionWithJSDoc || jsdocType && decl.kind === SyntaxKind.Parameter) ? annotateFunctionFromJSDoc : + jsdocType ? annotateTypeFromJSDoc : + undefined; + if (refactor) { + return [{ + name: refactor.name, + description: refactor.description, + actions: [ + { + description: refactor.description, + name: actionName + } + ] + }]; } } @@ -64,8 +65,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { const decl = findAncestor(token, isDeclarationWithType); const jsdocType = getJSDocType(decl); if (!decl || !jsdocType || decl.type) { - Debug.fail(`!decl || !jsdocType || decl.type: !${decl} || !${jsdocType} || ${decl.type}`); - return undefined; + return Debug.fail(`!decl || !jsdocType || decl.type: !${decl} || !${jsdocType} || ${decl.type}`); } const changeTracker = textChanges.ChangeTracker.fromContext(context); @@ -128,7 +128,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { case SyntaxKind.SetAccessor: return createSetAccessor(decl.decorators, decl.modifiers, decl.name, parameters, decl.body); default: - return Debug.fail(`Unexpected SyntaxKind: ${(decl as any).kind}`); + return Debug.assertNever(decl,`Unexpected SyntaxKind: ${(decl as any).kind}`); } } @@ -155,42 +155,42 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { case SyntaxKind.JSDocUnknownType: return createTypeReferenceNode("any", emptyArray); case SyntaxKind.JSDocOptionalType: - return visitJSDocOptionalType(node as JSDocOptionalType); + return transformJSDocOptionalType(node as JSDocOptionalType); case SyntaxKind.JSDocNonNullableType: return transformJSDocType((node as JSDocNonNullableType).type); case SyntaxKind.JSDocNullableType: - return visitJSDocNullableType(node as JSDocNullableType); + return transformJSDocNullableType(node as JSDocNullableType); case SyntaxKind.JSDocVariadicType: - return visitJSDocVariadicType(node as JSDocVariadicType); + return transformJSDocVariadicType(node as JSDocVariadicType); case SyntaxKind.JSDocFunctionType: - return visitJSDocFunctionType(node as JSDocFunctionType); + return transformJSDocFunctionType(node as JSDocFunctionType); case SyntaxKind.Parameter: - return visitJSDocParameter(node as ParameterDeclaration); + return transformJSDocParameter(node as ParameterDeclaration); case SyntaxKind.TypeReference: - return visitJSDocTypeReference(node as TypeReferenceNode); + return transformJSDocTypeReference(node as TypeReferenceNode); default: return visitEachChild(node, transformJSDocType, /*context*/ undefined) as TypeNode; } } - function visitJSDocOptionalType(node: JSDocOptionalType) { + function transformJSDocOptionalType(node: JSDocOptionalType) { return createUnionTypeNode([visitNode(node.type, transformJSDocType), createTypeReferenceNode("undefined", emptyArray)]); } - function visitJSDocNullableType(node: JSDocNullableType) { + function transformJSDocNullableType(node: JSDocNullableType) { return createUnionTypeNode([visitNode(node.type, transformJSDocType), createTypeReferenceNode("null", emptyArray)]); } - function visitJSDocVariadicType(node: JSDocVariadicType) { + function transformJSDocVariadicType(node: JSDocVariadicType) { return createArrayTypeNode(visitNode(node.type, transformJSDocType)); } - function visitJSDocFunctionType(node: JSDocFunctionType) { + function transformJSDocFunctionType(node: JSDocFunctionType) { const parameters = node.parameters && node.parameters.map(transformJSDocType); return createFunctionTypeNode(emptyArray, parameters as ParameterDeclaration[], node.type); } - function visitJSDocParameter(node: ParameterDeclaration) { + function transformJSDocParameter(node: ParameterDeclaration) { const index = node.parent.parameters.indexOf(node); const isRest = node.type.kind === SyntaxKind.JSDocVariadicType && index === node.parent.parameters.length - 1; const name = node.name || (isRest ? "rest" : "arg" + index); @@ -198,7 +198,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { return createParameter(node.decorators, node.modifiers, dotdotdot, name, node.questionToken, visitNode(node.type, transformJSDocType), node.initializer); } - function visitJSDocTypeReference(node: TypeReferenceNode) { + function transformJSDocTypeReference(node: TypeReferenceNode) { let name = node.typeName; let args = node.typeArguments; if (isIdentifier(node.typeName)) { diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc5.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc5.ts index 83e0888ddf5..1ae2949ef3c 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc5.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc5.ts @@ -5,7 +5,6 @@ //// /*1*/p = null ////} -// NOTE: The duplicated comment is unintentional but needs a serious fix in trivia handling verify.applicableRefactorAvailableAtMarker('1'); verify.fileAfterApplyingRefactorAtMarker('1', `class C { diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc6.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc6.ts index f6fce6c449f..53e8170533d 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc6.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc6.ts @@ -5,7 +5,6 @@ //// /*1*/p; ////} -// NOTE: The duplicated comment is unintentional but needs a serious fix in trivia handling verify.applicableRefactorAvailableAtMarker('1'); verify.fileAfterApplyingRefactorAtMarker('1', `declare class C { From 84e3507151a80334e1e1ecfefe6141f77e3e3b6e Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 13 Oct 2017 09:45:41 -0700 Subject: [PATCH 131/312] return more Debug.fails instead of undefined. --- src/services/refactors/annotateWithTypeFromJSDoc.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/services/refactors/annotateWithTypeFromJSDoc.ts b/src/services/refactors/annotateWithTypeFromJSDoc.ts index 52d3fe30e8d..17d910b3091 100644 --- a/src/services/refactors/annotateWithTypeFromJSDoc.ts +++ b/src/services/refactors/annotateWithTypeFromJSDoc.ts @@ -56,8 +56,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { function getEditsForAnnotation(context: RefactorContext, action: string): RefactorEditInfo | undefined { if (actionName !== action) { - Debug.fail(`actionName !== action: ${actionName} !== ${action}`); - return undefined; + return Debug.fail(`actionName !== action: ${actionName} !== ${action}`); } const sourceFile = context.file; @@ -81,8 +80,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { function getEditsForFunctionAnnotation(context: RefactorContext, action: string): RefactorEditInfo | undefined { if (actionName !== action) { - Debug.fail(`actionName !== action: ${actionName} !== ${action}`); - return undefined; + return Debug.fail(`actionName !== action: ${actionName} !== ${action}`); } const sourceFile = context.file; @@ -141,8 +139,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { case SyntaxKind.PropertyDeclaration: return createProperty(decl.decorators, decl.modifiers, decl.name, decl.questionToken, jsdocType, decl.initializer); default: - Debug.fail(`Unexpected SyntaxKind: ${decl.kind}`); - return undefined; + return Debug.fail(`Unexpected SyntaxKind: ${decl.kind}`); } } From 4cf06bbb02a2835021542571ddadfc0cf68cb3f6 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 13 Oct 2017 10:02:04 -0700 Subject: [PATCH 132/312] Fix spacing lint --- src/services/refactors/annotateWithTypeFromJSDoc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/refactors/annotateWithTypeFromJSDoc.ts b/src/services/refactors/annotateWithTypeFromJSDoc.ts index 17d910b3091..60c0517f681 100644 --- a/src/services/refactors/annotateWithTypeFromJSDoc.ts +++ b/src/services/refactors/annotateWithTypeFromJSDoc.ts @@ -126,7 +126,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc { case SyntaxKind.SetAccessor: return createSetAccessor(decl.decorators, decl.modifiers, decl.name, parameters, decl.body); default: - return Debug.assertNever(decl,`Unexpected SyntaxKind: ${(decl as any).kind}`); + return Debug.assertNever(decl, `Unexpected SyntaxKind: ${(decl as any).kind}`); } } From 769d202d4caaa7036f004c5ce27f961f0d70b12a Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 13 Oct 2017 14:53:52 -0700 Subject: [PATCH 133/312] In getContextuallyTypedParameterType, skip a `this` parameter when counting parameter index (#19155) --- src/compiler/checker.ts | 9 +++++++-- .../fourslash/quickInfoParameter_skipThisParameter.ts | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/quickInfoParameter_skipThisParameter.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9347329e624..4f144f3ff9b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13182,7 +13182,7 @@ namespace ts { } // Return contextual type of parameter or undefined if no contextual type is available - function getContextuallyTypedParameterType(parameter: ParameterDeclaration): Type { + function getContextuallyTypedParameterType(parameter: ParameterDeclaration): Type | undefined { const func = parameter.parent; if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) { const iife = getImmediatelyInvokedFunctionExpression(func); @@ -13208,7 +13208,12 @@ namespace ts { if (contextualSignature) { const funcHasRestParameters = hasRestParameter(func); const len = func.parameters.length - (funcHasRestParameters ? 1 : 0); - const indexOfParameter = indexOf(func.parameters, parameter); + let indexOfParameter = indexOf(func.parameters, parameter); + if (getThisParameter(func) !== undefined && !contextualSignature.thisParameter) { + Debug.assert(indexOfParameter !== 0); // Otherwise we should not have called `getContextuallyTypedParameterType`. + indexOfParameter -= 1; + } + if (indexOfParameter < len) { return getTypeAtPosition(contextualSignature, indexOfParameter); } diff --git a/tests/cases/fourslash/quickInfoParameter_skipThisParameter.ts b/tests/cases/fourslash/quickInfoParameter_skipThisParameter.ts new file mode 100644 index 00000000000..15e28aca0b5 --- /dev/null +++ b/tests/cases/fourslash/quickInfoParameter_skipThisParameter.ts @@ -0,0 +1,6 @@ +/// + +////function f(cb: (x: number) => void) {} +////f(function(this: any, /**/x) {}); + +verify.quickInfoAt("", "(parameter) x: number"); From fadf4914bbfe184b37cdd0a923782730ab8b99c4 Mon Sep 17 00:00:00 2001 From: csigs Date: Fri, 13 Oct 2017 22:10:24 +0000 Subject: [PATCH 134/312] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 17126 ++++++++-------- .../diagnosticMessages.generated.json.lcl | 17126 ++++++++-------- .../diagnosticMessages.generated.json.lcl | 17108 +++++++-------- .../diagnosticMessages.generated.json.lcl | 17034 +++++++-------- .../diagnosticMessages.generated.json.lcl | 17106 +++++++-------- 5 files changed, 42945 insertions(+), 42555 deletions(-) diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index 6a727b8b8e8..075923ea438 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,8525 +1,8603 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - nebo . Třeba {0} nebo {1}.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - .]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ().]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + nebo . Třeba {0} nebo {1}.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + .]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ().]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl index 9e8be1a2bfa..026f10b37be 100644 --- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,8525 +1,8603 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - ou -. Par exemple, '{0}' ou '{1}'.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - global.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()' à la place.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + ou -. Par exemple, '{0}' ou '{1}'.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + global.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()' à la place.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index 6bb0ed245b9..b978802c564 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,8516 +1,8594 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - o -, ad esempio, '{0}' o '{1}'.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - .]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()'.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + o -, ad esempio, '{0}' o '{1}'.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + .]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()'.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index c75652ece47..3a8512e54b2 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,8479 +1,8557 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - lub -. Na przykład „{0}” lub „{1}”.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - .]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()”.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + lub -. Na przykład „{0}” lub „{1}”.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + .]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()”.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index 780f933d28b..aac4d18cd67 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,8515 +1,8593 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - или <язык>–<территория>. Например, "{0}" или "{1}".]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - .]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()".]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + или <язык>–<территория>. Например, "{0}" или "{1}".]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + .]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()".]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 16f7f6f2e94c489780efed8227adeffc37d22769 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 13 Oct 2017 14:33:53 -0700 Subject: [PATCH 135/312] Added test case. --- .../compiler/taggedTemplatesInDifferentScopes.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/cases/compiler/taggedTemplatesInDifferentScopes.ts diff --git a/tests/cases/compiler/taggedTemplatesInDifferentScopes.ts b/tests/cases/compiler/taggedTemplatesInDifferentScopes.ts new file mode 100644 index 00000000000..836a3535029 --- /dev/null +++ b/tests/cases/compiler/taggedTemplatesInDifferentScopes.ts @@ -0,0 +1,15 @@ +export function tag(parts: TemplateStringsArray, ...values: any[]) { + return parts[0]; +} +function foo() { + tag `foo`; + tag `foo2`; +} + +function bar() { + tag `bar`; + tag `bar2`; +} + +foo(); +bar(); From 50085bab27b9b154a0ba3d618950c15eb01b8c3e Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 13 Oct 2017 15:25:04 -0700 Subject: [PATCH 136/312] Create truly unique names for tagged template strings. --- src/compiler/transformers/es2015.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index d5ce2bdc3a4..a1e52480172 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -3676,7 +3676,8 @@ namespace ts { // Do not do this in the global scope, as any variable we currently generate could conflict with // variables from outside of the current compilation. In the future, we can revisit this behavior. if (isExternalModule(currentSourceFile)) { - const tempVar = createTempVariable(recordTaggedTemplateString); + const tempVar = createUniqueName("templateObject"); + recordTaggedTemplateString(tempVar); templateArguments[0] = createLogicalOr( tempVar, createAssignment( From 258c4e0bccc13741b3b52677984dabffeb6282b2 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 13 Oct 2017 15:27:16 -0700 Subject: [PATCH 137/312] Accepted baselines. --- tests/baselines/reference/importHelpers.js | 4 +- .../taggedTemplateWithoutDeclaredHelper.js | 4 +- .../taggedTemplatesInDifferentScopes.js | 44 +++++++++++++++++ .../taggedTemplatesInDifferentScopes.symbols | 36 ++++++++++++++ .../taggedTemplatesInDifferentScopes.types | 48 +++++++++++++++++++ .../taggedTemplatesInModuleAndGlobal.js | 4 +- 6 files changed, 134 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/taggedTemplatesInDifferentScopes.js create mode 100644 tests/baselines/reference/taggedTemplatesInDifferentScopes.symbols create mode 100644 tests/baselines/reference/taggedTemplatesInDifferentScopes.types diff --git a/tests/baselines/reference/importHelpers.js b/tests/baselines/reference/importHelpers.js index 7bdd660a9ae..cf427400ab1 100644 --- a/tests/baselines/reference/importHelpers.js +++ b/tests/baselines/reference/importHelpers.js @@ -83,8 +83,8 @@ var C = /** @class */ (function () { function id(x) { return x; } -exports.result = id(_a || (_a = tslib_1.__makeTemplateObject(["hello world"], ["hello world"]))); -var _a; +exports.result = id(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["hello world"], ["hello world"]))); +var templateObject_1; //// [script.js] var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || diff --git a/tests/baselines/reference/taggedTemplateWithoutDeclaredHelper.js b/tests/baselines/reference/taggedTemplateWithoutDeclaredHelper.js index 453b35d98ba..19006f93b3e 100755 --- a/tests/baselines/reference/taggedTemplateWithoutDeclaredHelper.js +++ b/tests/baselines/reference/taggedTemplateWithoutDeclaredHelper.js @@ -18,5 +18,5 @@ var tslib_1 = require("tslib"); function id(x) { return x; } -exports.result = id(_a || (_a = tslib_1.__makeTemplateObject(["hello world"], ["hello world"]))); -var _a; +exports.result = id(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["hello world"], ["hello world"]))); +var templateObject_1; diff --git a/tests/baselines/reference/taggedTemplatesInDifferentScopes.js b/tests/baselines/reference/taggedTemplatesInDifferentScopes.js new file mode 100644 index 00000000000..e43c9a1e5e2 --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesInDifferentScopes.js @@ -0,0 +1,44 @@ +//// [taggedTemplatesInDifferentScopes.ts] +export function tag(parts: TemplateStringsArray, ...values: any[]) { + return parts[0]; +} +function foo() { + tag `foo`; + tag `foo2`; +} + +function bar() { + tag `bar`; + tag `bar2`; +} + +foo(); +bar(); + + +//// [taggedTemplatesInDifferentScopes.js] +"use strict"; +var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) { + if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } + return cooked; +}; +exports.__esModule = true; +function tag(parts) { + var values = []; + for (var _i = 1; _i < arguments.length; _i++) { + values[_i - 1] = arguments[_i]; + } + return parts[0]; +} +exports.tag = tag; +function foo() { + tag(templateObject_1 || (templateObject_1 = __makeTemplateObject(["foo"], ["foo"]))); + tag(templateObject_2 || (templateObject_2 = __makeTemplateObject(["foo2"], ["foo2"]))); +} +function bar() { + tag(templateObject_3 || (templateObject_3 = __makeTemplateObject(["bar"], ["bar"]))); + tag(templateObject_4 || (templateObject_4 = __makeTemplateObject(["bar2"], ["bar2"]))); +} +foo(); +bar(); +var templateObject_1, templateObject_2, templateObject_3, templateObject_4; diff --git a/tests/baselines/reference/taggedTemplatesInDifferentScopes.symbols b/tests/baselines/reference/taggedTemplatesInDifferentScopes.symbols new file mode 100644 index 00000000000..071616b85f1 --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesInDifferentScopes.symbols @@ -0,0 +1,36 @@ +=== tests/cases/compiler/taggedTemplatesInDifferentScopes.ts === +export function tag(parts: TemplateStringsArray, ...values: any[]) { +>tag : Symbol(tag, Decl(taggedTemplatesInDifferentScopes.ts, 0, 0)) +>parts : Symbol(parts, Decl(taggedTemplatesInDifferentScopes.ts, 0, 20)) +>TemplateStringsArray : Symbol(TemplateStringsArray, Decl(lib.d.ts, --, --)) +>values : Symbol(values, Decl(taggedTemplatesInDifferentScopes.ts, 0, 48)) + + return parts[0]; +>parts : Symbol(parts, Decl(taggedTemplatesInDifferentScopes.ts, 0, 20)) +} +function foo() { +>foo : Symbol(foo, Decl(taggedTemplatesInDifferentScopes.ts, 2, 1)) + + tag `foo`; +>tag : Symbol(tag, Decl(taggedTemplatesInDifferentScopes.ts, 0, 0)) + + tag `foo2`; +>tag : Symbol(tag, Decl(taggedTemplatesInDifferentScopes.ts, 0, 0)) +} + +function bar() { +>bar : Symbol(bar, Decl(taggedTemplatesInDifferentScopes.ts, 6, 1)) + + tag `bar`; +>tag : Symbol(tag, Decl(taggedTemplatesInDifferentScopes.ts, 0, 0)) + + tag `bar2`; +>tag : Symbol(tag, Decl(taggedTemplatesInDifferentScopes.ts, 0, 0)) +} + +foo(); +>foo : Symbol(foo, Decl(taggedTemplatesInDifferentScopes.ts, 2, 1)) + +bar(); +>bar : Symbol(bar, Decl(taggedTemplatesInDifferentScopes.ts, 6, 1)) + diff --git a/tests/baselines/reference/taggedTemplatesInDifferentScopes.types b/tests/baselines/reference/taggedTemplatesInDifferentScopes.types new file mode 100644 index 00000000000..ea1faeacef4 --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesInDifferentScopes.types @@ -0,0 +1,48 @@ +=== tests/cases/compiler/taggedTemplatesInDifferentScopes.ts === +export function tag(parts: TemplateStringsArray, ...values: any[]) { +>tag : (parts: TemplateStringsArray, ...values: any[]) => string +>parts : TemplateStringsArray +>TemplateStringsArray : TemplateStringsArray +>values : any[] + + return parts[0]; +>parts[0] : string +>parts : TemplateStringsArray +>0 : 0 +} +function foo() { +>foo : () => void + + tag `foo`; +>tag `foo` : string +>tag : (parts: TemplateStringsArray, ...values: any[]) => string +>`foo` : "foo" + + tag `foo2`; +>tag `foo2` : string +>tag : (parts: TemplateStringsArray, ...values: any[]) => string +>`foo2` : "foo2" +} + +function bar() { +>bar : () => void + + tag `bar`; +>tag `bar` : string +>tag : (parts: TemplateStringsArray, ...values: any[]) => string +>`bar` : "bar" + + tag `bar2`; +>tag `bar2` : string +>tag : (parts: TemplateStringsArray, ...values: any[]) => string +>`bar2` : "bar2" +} + +foo(); +>foo() : void +>foo : () => void + +bar(); +>bar() : void +>bar : () => void + diff --git a/tests/baselines/reference/taggedTemplatesInModuleAndGlobal.js b/tests/baselines/reference/taggedTemplatesInModuleAndGlobal.js index 737bdec55dc..e8f5104ae74 100644 --- a/tests/baselines/reference/taggedTemplatesInModuleAndGlobal.js +++ b/tests/baselines/reference/taggedTemplatesInModuleAndGlobal.js @@ -49,7 +49,7 @@ function id(x) { return x; } function templateObjectFactory() { - return id(_a || (_a = __makeTemplateObject(["hello world"], ["hello world"]))); + return id(templateObject_1 || (templateObject_1 = __makeTemplateObject(["hello world"], ["hello world"]))); } var result = templateObjectFactory() === templateObjectFactory(); -var _a; +var templateObject_1; From faa04a2402288654fddf36f08e969492bea9ef7c Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 13 Oct 2017 16:47:40 -0700 Subject: [PATCH 138/312] Update generated files (#19177) --- src/lib/dom.generated.d.ts | 12 +++++------- src/lib/webworker.generated.d.ts | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index 420be2f0f5d..c7534fbd829 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -4833,6 +4833,7 @@ interface HTMLFormElement extends HTMLElement { * Fires when a FORM is about to be submitted. */ submit(): void; + reportValidity(): boolean; addEventListener(type: K, listener: (this: HTMLFormElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; [name: string]: any; @@ -4961,9 +4962,6 @@ interface HTMLFrameSetElement extends HTMLElement { onafterprint: (this: HTMLFrameSetElement, ev: Event) => any; onbeforeprint: (this: HTMLFrameSetElement, ev: Event) => any; onbeforeunload: (this: HTMLFrameSetElement, ev: BeforeUnloadEvent) => any; - /** - * Fires when the object receives focus. - */ onhashchange: (this: HTMLFrameSetElement, ev: HashChangeEvent) => any; onmessage: (this: HTMLFrameSetElement, ev: MessageEvent) => any; onoffline: (this: HTMLFrameSetElement, ev: Event) => any; @@ -5108,7 +5106,6 @@ interface HTMLIFrameElement extends HTMLElement, GetSVGDocument { * Sets or retrieves whether the user can resize the frame. */ noResize: boolean; - readonly sandbox: DOMSettableTokenList; /** * Sets or retrieves whether the frame can be scrolled. @@ -8205,6 +8202,7 @@ interface Navigator extends Object, NavigatorID, NavigatorOnLine, NavigatorConte readonly pointerEnabled: boolean; readonly serviceWorker: ServiceWorkerContainer; readonly webdriver: boolean; + readonly doNotTrack: string | null; readonly hardwareConcurrency: number; readonly languages: string[]; getGamepads(): Gamepad[]; @@ -13257,7 +13255,7 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window moveBy(x?: number, y?: number): void; moveTo(x?: number, y?: number): void; msWriteProfilerMark(profilerMarkName: string): void; - open(url?: string, target?: string, features?: string, replace?: boolean): Window; + open(url?: string, target?: string, features?: string, replace?: boolean): Window | null; postMessage(message: any, targetOrigin: string, transfer?: any[]): void; print(): void; prompt(message?: string, _default?: string): string | null; @@ -14006,7 +14004,7 @@ interface EcKeyAlgorithm extends KeyAlgorithm { typedCurve: string; } -interface EcKeyImportParams { +interface EcKeyImportParams extends Algorithm { namedCurve: string; } @@ -14657,7 +14655,7 @@ declare function matchMedia(mediaQuery: string): MediaQueryList; declare function moveBy(x?: number, y?: number): void; declare function moveTo(x?: number, y?: number): void; declare function msWriteProfilerMark(profilerMarkName: string): void; -declare function open(url?: string, target?: string, features?: string, replace?: boolean): Window; +declare function open(url?: string, target?: string, features?: string, replace?: boolean): Window | null; declare function postMessage(message: any, targetOrigin: string, transfer?: any[]): void; declare function print(): void; declare function prompt(message?: string, _default?: string): string | null; diff --git a/src/lib/webworker.generated.d.ts b/src/lib/webworker.generated.d.ts index 821a7edd886..3416df4955a 100644 --- a/src/lib/webworker.generated.d.ts +++ b/src/lib/webworker.generated.d.ts @@ -1642,7 +1642,7 @@ interface EcKeyAlgorithm extends KeyAlgorithm { typedCurve: string; } -interface EcKeyImportParams { +interface EcKeyImportParams extends Algorithm { namedCurve: string; } From 07ff0fdb818623f6bc096dc140f4ae0015530ebf Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 13 Oct 2017 16:54:57 -0700 Subject: [PATCH 139/312] Properly handle mapped types with 'keyof any' --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9347329e624..f8f63bfe0f7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5777,7 +5777,7 @@ namespace ts { for (const propertySymbol of getPropertiesOfType(modifiersType)) { addMemberForKeyType(getLiteralTypeFromPropertyName(propertySymbol), propertySymbol); } - if (getIndexInfoOfType(modifiersType, IndexKind.String)) { + if (modifiersType.flags & TypeFlags.Any || getIndexInfoOfType(modifiersType, IndexKind.String)) { addMemberForKeyType(stringType); } } @@ -8386,7 +8386,7 @@ namespace ts { } function isMappableType(type: Type) { - return type.flags & (TypeFlags.TypeParameter | TypeFlags.Object | TypeFlags.Intersection | TypeFlags.IndexedAccess); + return type.flags & (TypeFlags.Any | TypeFlags.TypeParameter | TypeFlags.Object | TypeFlags.Intersection | TypeFlags.IndexedAccess); } function instantiateAnonymousType(type: AnonymousType, mapper: TypeMapper): AnonymousType { From 40cb9656f96fc6565a695e9c9ba6a4631da22f35 Mon Sep 17 00:00:00 2001 From: csigs Date: Sat, 14 Oct 2017 04:10:04 +0000 Subject: [PATCH 140/312] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 17034 ++++++++-------- 1 file changed, 8556 insertions(+), 8478 deletions(-) diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index a895cdec898..603345e63b2 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,8479 +1,8557 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - ou -. Por exemplo '{0}' ou '{1}'.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - Promessa global.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()' em vez disso.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + ou -. Por exemplo '{0}' ou '{1}'.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + Promessa global.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()' em vez disso.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From fa65bd20621536e6c7272e05dad9af5a7f36aeeb Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 14 Oct 2017 09:53:51 -0700 Subject: [PATCH 141/312] Mapped type { [P in any]: T } should yield { [x: string]: T } --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f8f63bfe0f7..9f4e3a60eb1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5821,7 +5821,7 @@ namespace ts { prop.syntheticLiteralTypeOrigin = t as StringLiteralType; members.set(propName, prop); } - else if (t.flags & TypeFlags.String) { + else if (t.flags & (TypeFlags.Any | TypeFlags.String)) { stringIndexInfo = createIndexInfo(propType, templateReadonly); } } From ee0715a0736a0aa453b5020432790f07e0eb205f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 14 Oct 2017 11:13:40 -0700 Subject: [PATCH 142/312] Add tests --- .../types/mapped/mappedTypeWithAny.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 tests/cases/conformance/types/mapped/mappedTypeWithAny.ts diff --git a/tests/cases/conformance/types/mapped/mappedTypeWithAny.ts b/tests/cases/conformance/types/mapped/mappedTypeWithAny.ts new file mode 100644 index 00000000000..f8b6f8a39b7 --- /dev/null +++ b/tests/cases/conformance/types/mapped/mappedTypeWithAny.ts @@ -0,0 +1,27 @@ +// @strict: true +// @declaration: true + +type Item = { value: string }; +type ItemMap = { [P in keyof T]: Item }; + +declare let x0: keyof any; +declare let x1: { [P in any]: Item }; +declare let x2: { [P in string]: Item }; +declare let x3: { [P in keyof any]: Item }; +declare let x4: ItemMap; + +// Repro from #19152 + +type Data = { + value: string; +} + +type StrictDataMap = { + [P in keyof T]: Data +} + +declare let z: StrictDataMap; +for (let id in z) { + let data = z[id]; + let x = data.notAValue; // Error +} From 8e47c18636da814117071a2640ccf87c5f16fcfd Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 14 Oct 2017 11:13:52 -0700 Subject: [PATCH 143/312] Accept new baselines --- .../reference/mappedTypeWithAny.errors.txt | 31 ++++++++ .../baselines/reference/mappedTypeWithAny.js | 60 +++++++++++++++ .../reference/mappedTypeWithAny.symbols | 71 ++++++++++++++++++ .../reference/mappedTypeWithAny.types | 74 +++++++++++++++++++ 4 files changed, 236 insertions(+) create mode 100644 tests/baselines/reference/mappedTypeWithAny.errors.txt create mode 100644 tests/baselines/reference/mappedTypeWithAny.js create mode 100644 tests/baselines/reference/mappedTypeWithAny.symbols create mode 100644 tests/baselines/reference/mappedTypeWithAny.types diff --git a/tests/baselines/reference/mappedTypeWithAny.errors.txt b/tests/baselines/reference/mappedTypeWithAny.errors.txt new file mode 100644 index 00000000000..0ce53e5044d --- /dev/null +++ b/tests/baselines/reference/mappedTypeWithAny.errors.txt @@ -0,0 +1,31 @@ +tests/cases/conformance/types/mapped/mappedTypeWithAny.ts(23,16): error TS2339: Property 'notAValue' does not exist on type 'Data'. + + +==== tests/cases/conformance/types/mapped/mappedTypeWithAny.ts (1 errors) ==== + type Item = { value: string }; + type ItemMap = { [P in keyof T]: Item }; + + declare let x0: keyof any; + declare let x1: { [P in any]: Item }; + declare let x2: { [P in string]: Item }; + declare let x3: { [P in keyof any]: Item }; + declare let x4: ItemMap; + + // Repro from #19152 + + type Data = { + value: string; + } + + type StrictDataMap = { + [P in keyof T]: Data + } + + declare let z: StrictDataMap; + for (let id in z) { + let data = z[id]; + let x = data.notAValue; // Error + ~~~~~~~~~ +!!! error TS2339: Property 'notAValue' does not exist on type 'Data'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/mappedTypeWithAny.js b/tests/baselines/reference/mappedTypeWithAny.js new file mode 100644 index 00000000000..1e5c662310c --- /dev/null +++ b/tests/baselines/reference/mappedTypeWithAny.js @@ -0,0 +1,60 @@ +//// [mappedTypeWithAny.ts] +type Item = { value: string }; +type ItemMap = { [P in keyof T]: Item }; + +declare let x0: keyof any; +declare let x1: { [P in any]: Item }; +declare let x2: { [P in string]: Item }; +declare let x3: { [P in keyof any]: Item }; +declare let x4: ItemMap; + +// Repro from #19152 + +type Data = { + value: string; +} + +type StrictDataMap = { + [P in keyof T]: Data +} + +declare let z: StrictDataMap; +for (let id in z) { + let data = z[id]; + let x = data.notAValue; // Error +} + + +//// [mappedTypeWithAny.js] +"use strict"; +for (var id in z) { + var data = z[id]; + var x = data.notAValue; // Error +} + + +//// [mappedTypeWithAny.d.ts] +declare type Item = { + value: string; +}; +declare type ItemMap = { + [P in keyof T]: Item; +}; +declare let x0: keyof any; +declare let x1: { + [P in any]: Item; +}; +declare let x2: { + [P in string]: Item; +}; +declare let x3: { + [P in keyof any]: Item; +}; +declare let x4: ItemMap; +declare type Data = { + value: string; +}; +declare type StrictDataMap = { + [P in keyof T]: Data; +}; +declare let z: StrictDataMap; diff --git a/tests/baselines/reference/mappedTypeWithAny.symbols b/tests/baselines/reference/mappedTypeWithAny.symbols new file mode 100644 index 00000000000..2c204d4b1ef --- /dev/null +++ b/tests/baselines/reference/mappedTypeWithAny.symbols @@ -0,0 +1,71 @@ +=== tests/cases/conformance/types/mapped/mappedTypeWithAny.ts === +type Item = { value: string }; +>Item : Symbol(Item, Decl(mappedTypeWithAny.ts, 0, 0)) +>value : Symbol(value, Decl(mappedTypeWithAny.ts, 0, 13)) + +type ItemMap = { [P in keyof T]: Item }; +>ItemMap : Symbol(ItemMap, Decl(mappedTypeWithAny.ts, 0, 30)) +>T : Symbol(T, Decl(mappedTypeWithAny.ts, 1, 13)) +>P : Symbol(P, Decl(mappedTypeWithAny.ts, 1, 21)) +>T : Symbol(T, Decl(mappedTypeWithAny.ts, 1, 13)) +>Item : Symbol(Item, Decl(mappedTypeWithAny.ts, 0, 0)) + +declare let x0: keyof any; +>x0 : Symbol(x0, Decl(mappedTypeWithAny.ts, 3, 11)) + +declare let x1: { [P in any]: Item }; +>x1 : Symbol(x1, Decl(mappedTypeWithAny.ts, 4, 11)) +>P : Symbol(P, Decl(mappedTypeWithAny.ts, 4, 19)) +>Item : Symbol(Item, Decl(mappedTypeWithAny.ts, 0, 0)) + +declare let x2: { [P in string]: Item }; +>x2 : Symbol(x2, Decl(mappedTypeWithAny.ts, 5, 11)) +>P : Symbol(P, Decl(mappedTypeWithAny.ts, 5, 19)) +>Item : Symbol(Item, Decl(mappedTypeWithAny.ts, 0, 0)) + +declare let x3: { [P in keyof any]: Item }; +>x3 : Symbol(x3, Decl(mappedTypeWithAny.ts, 6, 11)) +>P : Symbol(P, Decl(mappedTypeWithAny.ts, 6, 19)) +>Item : Symbol(Item, Decl(mappedTypeWithAny.ts, 0, 0)) + +declare let x4: ItemMap; +>x4 : Symbol(x4, Decl(mappedTypeWithAny.ts, 7, 11)) +>ItemMap : Symbol(ItemMap, Decl(mappedTypeWithAny.ts, 0, 30)) + +// Repro from #19152 + +type Data = { +>Data : Symbol(Data, Decl(mappedTypeWithAny.ts, 7, 29)) + + value: string; +>value : Symbol(value, Decl(mappedTypeWithAny.ts, 11, 13)) +} + +type StrictDataMap = { +>StrictDataMap : Symbol(StrictDataMap, Decl(mappedTypeWithAny.ts, 13, 1)) +>T : Symbol(T, Decl(mappedTypeWithAny.ts, 15, 19)) + + [P in keyof T]: Data +>P : Symbol(P, Decl(mappedTypeWithAny.ts, 16, 3)) +>T : Symbol(T, Decl(mappedTypeWithAny.ts, 15, 19)) +>Data : Symbol(Data, Decl(mappedTypeWithAny.ts, 7, 29)) +} + +declare let z: StrictDataMap; +>z : Symbol(z, Decl(mappedTypeWithAny.ts, 19, 11)) +>StrictDataMap : Symbol(StrictDataMap, Decl(mappedTypeWithAny.ts, 13, 1)) + +for (let id in z) { +>id : Symbol(id, Decl(mappedTypeWithAny.ts, 20, 8)) +>z : Symbol(z, Decl(mappedTypeWithAny.ts, 19, 11)) + + let data = z[id]; +>data : Symbol(data, Decl(mappedTypeWithAny.ts, 21, 5)) +>z : Symbol(z, Decl(mappedTypeWithAny.ts, 19, 11)) +>id : Symbol(id, Decl(mappedTypeWithAny.ts, 20, 8)) + + let x = data.notAValue; // Error +>x : Symbol(x, Decl(mappedTypeWithAny.ts, 22, 5)) +>data : Symbol(data, Decl(mappedTypeWithAny.ts, 21, 5)) +} + diff --git a/tests/baselines/reference/mappedTypeWithAny.types b/tests/baselines/reference/mappedTypeWithAny.types new file mode 100644 index 00000000000..36fad9140cc --- /dev/null +++ b/tests/baselines/reference/mappedTypeWithAny.types @@ -0,0 +1,74 @@ +=== tests/cases/conformance/types/mapped/mappedTypeWithAny.ts === +type Item = { value: string }; +>Item : Item +>value : string + +type ItemMap = { [P in keyof T]: Item }; +>ItemMap : ItemMap +>T : T +>P : P +>T : T +>Item : Item + +declare let x0: keyof any; +>x0 : string + +declare let x1: { [P in any]: Item }; +>x1 : { [x: string]: Item; } +>P : P +>Item : Item + +declare let x2: { [P in string]: Item }; +>x2 : { [x: string]: Item; } +>P : P +>Item : Item + +declare let x3: { [P in keyof any]: Item }; +>x3 : { [x: string]: Item; } +>P : P +>Item : Item + +declare let x4: ItemMap; +>x4 : ItemMap +>ItemMap : ItemMap + +// Repro from #19152 + +type Data = { +>Data : Data + + value: string; +>value : string +} + +type StrictDataMap = { +>StrictDataMap : StrictDataMap +>T : T + + [P in keyof T]: Data +>P : P +>T : T +>Data : Data +} + +declare let z: StrictDataMap; +>z : StrictDataMap +>StrictDataMap : StrictDataMap + +for (let id in z) { +>id : string +>z : StrictDataMap + + let data = z[id]; +>data : Data +>z[id] : Data +>z : StrictDataMap +>id : string + + let x = data.notAValue; // Error +>x : any +>data.notAValue : any +>data : Data +>notAValue : any +} + From 30c51ed3249a1701c5d1faeb169717ff009d6ad5 Mon Sep 17 00:00:00 2001 From: kingwl <805037171@163.com> Date: Mon, 16 Oct 2017 10:39:55 +0800 Subject: [PATCH 144/312] fix super call from class that has no basetype but with same symbol interface (#19068) --- src/compiler/checker.ts | 8 +++++--- ...aseTypeButWithSameSymbolInterface.errors.txt | 14 ++++++++++++++ ...atHasNoBaseTypeButWithSameSymbolInterface.js | 17 +++++++++++++++++ ...NoBaseTypeButWithSameSymbolInterface.symbols | 13 +++++++++++++ ...asNoBaseTypeButWithSameSymbolInterface.types | 15 +++++++++++++++ ...atHasNoBaseTypeButWithSameSymbolInterface.ts | 7 +++++++ 6 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.errors.txt create mode 100644 tests/baselines/reference/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.js create mode 100644 tests/baselines/reference/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.symbols create mode 100644 tests/baselines/reference/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.types create mode 100644 tests/cases/conformance/es6/classDeclaration/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 32086157552..bd97a49fa45 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13043,12 +13043,14 @@ namespace ts { // at this point the only legal case for parent is ClassLikeDeclaration const classLikeDeclaration = container.parent; + if (!getClassExtendsHeritageClauseElement(classLikeDeclaration)) { + error(node, Diagnostics.super_can_only_be_referenced_in_a_derived_class); + return unknownType; + } + const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classLikeDeclaration)); const baseClassType = classType && getBaseTypes(classType)[0]; if (!baseClassType) { - if (!getClassExtendsHeritageClauseElement(classLikeDeclaration)) { - error(node, Diagnostics.super_can_only_be_referenced_in_a_derived_class); - } return unknownType; } diff --git a/tests/baselines/reference/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.errors.txt b/tests/baselines/reference/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.errors.txt new file mode 100644 index 00000000000..44963f797ea --- /dev/null +++ b/tests/baselines/reference/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/es6/classDeclaration/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.ts(5,9): error TS2335: 'super' can only be referenced in a derived class. + + +==== tests/cases/conformance/es6/classDeclaration/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.ts (1 errors) ==== + interface Foo extends Array {} + + class Foo { + constructor() { + super(); // error + ~~~~~ +!!! error TS2335: 'super' can only be referenced in a derived class. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.js b/tests/baselines/reference/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.js new file mode 100644 index 00000000000..e933ec9daa2 --- /dev/null +++ b/tests/baselines/reference/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.js @@ -0,0 +1,17 @@ +//// [superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.ts] +interface Foo extends Array {} + +class Foo { + constructor() { + super(); // error + } +} + + +//// [superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.js] +var Foo = /** @class */ (function () { + function Foo() { + _this = _super.call(this) || this; // error + } + return Foo; +}()); diff --git a/tests/baselines/reference/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.symbols b/tests/baselines/reference/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.symbols new file mode 100644 index 00000000000..a8ff0f10b4f --- /dev/null +++ b/tests/baselines/reference/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.symbols @@ -0,0 +1,13 @@ +=== tests/cases/conformance/es6/classDeclaration/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.ts === +interface Foo extends Array {} +>Foo : Symbol(Foo, Decl(superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.ts, 0, 0), Decl(superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.ts, 0, 38)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +class Foo { +>Foo : Symbol(Foo, Decl(superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.ts, 0, 0), Decl(superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.ts, 0, 38)) + + constructor() { + super(); // error + } +} + diff --git a/tests/baselines/reference/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.types b/tests/baselines/reference/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.types new file mode 100644 index 00000000000..f2e5ad17063 --- /dev/null +++ b/tests/baselines/reference/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.types @@ -0,0 +1,15 @@ +=== tests/cases/conformance/es6/classDeclaration/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.ts === +interface Foo extends Array {} +>Foo : Foo +>Array : T[] + +class Foo { +>Foo : Foo + + constructor() { + super(); // error +>super() : void +>super : any + } +} + diff --git a/tests/cases/conformance/es6/classDeclaration/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.ts b/tests/cases/conformance/es6/classDeclaration/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.ts new file mode 100644 index 00000000000..3afd8275941 --- /dev/null +++ b/tests/cases/conformance/es6/classDeclaration/superCallFromClassThatHasNoBaseTypeButWithSameSymbolInterface.ts @@ -0,0 +1,7 @@ +interface Foo extends Array {} + +class Foo { + constructor() { + super(); // error + } +} From 9306543431bb4c97dff8b6f193c02becd12c6bfb Mon Sep 17 00:00:00 2001 From: csigs Date: Mon, 16 Oct 2017 16:10:13 +0000 Subject: [PATCH 145/312] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 17108 +++++++-------- .../diagnosticMessages.generated.json.lcl | 17120 ++++++++-------- .../diagnosticMessages.generated.json.lcl | 17105 +++++++-------- 3 files changed, 25782 insertions(+), 25551 deletions(-) diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index bed8ce927b8..16310396458 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,8516 +1,8594 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - 或 <語言>-<國家/地區>。例如 '{0}' 或 '{1}'。]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - 類型。]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()'。]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + 或 <語言>-<國家/地區>。例如 '{0}' 或 '{1}'。]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + 類型。]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()'。]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl index bbf200457e9..a2963d878f6 100644 --- a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,8525 +1,8597 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - o -. Por ejemplo, '{0}' o '{1}'.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - global.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()" en su lugar.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + o -. Por ejemplo, '{0}' o '{1}'.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + global.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()" en su lugar.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl index a7248df81af..de906e32915 100644 --- a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,8513 +1,8594 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - または - の形式で指定する必要があります (例: '{0}'、'{1}')。]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - 型である必要があります。]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()' を使用してください。]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + または - の形式で指定する必要があります (例: '{0}'、'{1}')。]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + 型である必要があります。]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()' を使用してください。]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 5e7bfad2a7c8e44c66b4599c187a738834d7dc4d Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 16 Oct 2017 09:19:46 -0700 Subject: [PATCH 146/312] Check own-constructor in abstract prop access error --- src/compiler/checker.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 32086157552..549b759b225 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14906,12 +14906,11 @@ namespace ts { } } - // Referencing Abstract Properties within Constructors is not allowed + // Referencing abstract properties within their own constructors is not allowed if ((flags & ModifierFlags.Abstract) && symbolHasNonMethodDeclaration(prop)) { const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)); - - if (declaringClassDeclaration && isNodeWithinConstructor(node, declaringClassDeclaration)) { - error(errorNode, Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), typeToString(getDeclaringClass(prop))); + if (declaringClassDeclaration && isNodeWithinConstructorOfClass(node, declaringClassDeclaration)) { + error(errorNode, Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), getTextOfIdentifierOrLiteral(declaringClassDeclaration.name)); return false; } } @@ -23227,9 +23226,9 @@ namespace ts { return result; } - function isNodeWithinConstructor(node: Node, classDeclaration: ClassLikeDeclaration) { + function isNodeWithinConstructorOfClass(node: Node, classDeclaration: ClassLikeDeclaration) { return findAncestor(node, element => { - if (isConstructorDeclaration(element) && nodeIsPresent(element.body)) { + if (isConstructorDeclaration(element) && nodeIsPresent(element.body) && element.parent === classDeclaration) { return true; } else if (element === classDeclaration || isFunctionLikeDeclaration(element)) { From fb45b49afcbc1182f4524703221f8bfe573a5de9 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 16 Oct 2017 09:20:28 -0700 Subject: [PATCH 147/312] Test:abstract prop access in non-declaring ctor --- .../abstractPropertyInConstructor.errors.txt | 9 +++++ .../abstractPropertyInConstructor.js | 18 ++++++++++ .../abstractPropertyInConstructor.symbols | 29 ++++++++++++++++ .../abstractPropertyInConstructor.types | 34 +++++++++++++++++++ .../compiler/abstractPropertyInConstructor.ts | 9 +++++ 5 files changed, 99 insertions(+) diff --git a/tests/baselines/reference/abstractPropertyInConstructor.errors.txt b/tests/baselines/reference/abstractPropertyInConstructor.errors.txt index 461dd713d3b..63636b35725 100644 --- a/tests/baselines/reference/abstractPropertyInConstructor.errors.txt +++ b/tests/baselines/reference/abstractPropertyInConstructor.errors.txt @@ -34,4 +34,13 @@ tests/cases/compiler/abstractPropertyInConstructor.ts(9,14): error TS2715: Abstr this.prop = this.prop + "!"; } } + + class User { + constructor(a: AbstractClass) { + a.prop; + a.cb("hi"); + a.method(12); + a.method2(); + } + } \ No newline at end of file diff --git a/tests/baselines/reference/abstractPropertyInConstructor.js b/tests/baselines/reference/abstractPropertyInConstructor.js index 18a2937a191..5bf9726b283 100644 --- a/tests/baselines/reference/abstractPropertyInConstructor.js +++ b/tests/baselines/reference/abstractPropertyInConstructor.js @@ -23,6 +23,15 @@ abstract class AbstractClass { this.prop = this.prop + "!"; } } + +class User { + constructor(a: AbstractClass) { + a.prop; + a.cb("hi"); + a.method(12); + a.method2(); + } +} //// [abstractPropertyInConstructor.js] @@ -44,3 +53,12 @@ var AbstractClass = /** @class */ (function () { }; return AbstractClass; }()); +var User = /** @class */ (function () { + function User(a) { + a.prop; + a.cb("hi"); + a.method(12); + a.method2(); + } + return User; +}()); diff --git a/tests/baselines/reference/abstractPropertyInConstructor.symbols b/tests/baselines/reference/abstractPropertyInConstructor.symbols index 0d542ffb0a8..f6e29a58487 100644 --- a/tests/baselines/reference/abstractPropertyInConstructor.symbols +++ b/tests/baselines/reference/abstractPropertyInConstructor.symbols @@ -68,3 +68,32 @@ abstract class AbstractClass { } } +class User { +>User : Symbol(User, Decl(abstractPropertyInConstructor.ts, 23, 1)) + + constructor(a: AbstractClass) { +>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 26, 16)) +>AbstractClass : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) + + a.prop; +>a.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) +>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 26, 16)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) + + a.cb("hi"); +>a.cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 15, 26)) +>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 26, 16)) +>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 15, 26)) + + a.method(12); +>a.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 16, 37)) +>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 26, 16)) +>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 16, 37)) + + a.method2(); +>a.method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 18, 39)) +>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 26, 16)) +>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 18, 39)) + } +} + diff --git a/tests/baselines/reference/abstractPropertyInConstructor.types b/tests/baselines/reference/abstractPropertyInConstructor.types index 0ffb5f1bdfd..a44403c1091 100644 --- a/tests/baselines/reference/abstractPropertyInConstructor.types +++ b/tests/baselines/reference/abstractPropertyInConstructor.types @@ -79,3 +79,37 @@ abstract class AbstractClass { } } +class User { +>User : User + + constructor(a: AbstractClass) { +>a : AbstractClass +>AbstractClass : AbstractClass + + a.prop; +>a.prop : string +>a : AbstractClass +>prop : string + + a.cb("hi"); +>a.cb("hi") : void +>a.cb : (s: string) => void +>a : AbstractClass +>cb : (s: string) => void +>"hi" : "hi" + + a.method(12); +>a.method(12) : void +>a.method : (num: number) => void +>a : AbstractClass +>method : (num: number) => void +>12 : 12 + + a.method2(); +>a.method2() : void +>a.method2 : () => void +>a : AbstractClass +>method2 : () => void + } +} + diff --git a/tests/cases/compiler/abstractPropertyInConstructor.ts b/tests/cases/compiler/abstractPropertyInConstructor.ts index 457fdb473b1..e58e052f8db 100644 --- a/tests/cases/compiler/abstractPropertyInConstructor.ts +++ b/tests/cases/compiler/abstractPropertyInConstructor.ts @@ -22,3 +22,12 @@ abstract class AbstractClass { this.prop = this.prop + "!"; } } + +class User { + constructor(a: AbstractClass) { + a.prop; + a.cb("hi"); + a.method(12); + a.method2(); + } +} From 49beac919cdaa6167653722e454e5acd2c041a87 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 16 Oct 2017 09:43:49 -0700 Subject: [PATCH 148/312] Abstract property access error only on this access --- src/compiler/checker.ts | 2 +- src/compiler/utilities.ts | 13 ++- .../abstractPropertyInConstructor.errors.txt | 6 +- .../abstractPropertyInConstructor.js | 11 ++- .../abstractPropertyInConstructor.symbols | 84 +++++++++++-------- .../abstractPropertyInConstructor.types | 15 +++- .../compiler/abstractPropertyInConstructor.ts | 6 +- 7 files changed, 93 insertions(+), 44 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 549b759b225..3c36a85e5d2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14907,7 +14907,7 @@ namespace ts { } // Referencing abstract properties within their own constructors is not allowed - if ((flags & ModifierFlags.Abstract) && symbolHasNonMethodDeclaration(prop)) { + if ((flags & ModifierFlags.Abstract) && isThisProperty(node) && symbolHasNonMethodDeclaration(prop)) { const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)); if (declaringClassDeclaration && isNodeWithinConstructorOfClass(node, declaringClassDeclaration)) { error(errorNode, Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), getTextOfIdentifierOrLiteral(declaringClassDeclaration.name)); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index c4d3de453ba..c29c6c45c89 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1121,7 +1121,7 @@ namespace ts { } /** - * Determines whether a node is a property or element access expression for super. + * Determines whether a node is a property or element access expression for `super`. */ export function isSuperProperty(node: Node): node is SuperProperty { const kind = node.kind; @@ -1129,7 +1129,16 @@ namespace ts { && (node).expression.kind === SyntaxKind.SuperKeyword; } - export function getEntityNameFromTypeNode(node: TypeNode): EntityNameOrEntityNameExpression { + /** + * Determines whether a node is a property or element access expression for `this`. + */ + export function isThisProperty(node: Node): boolean { + const kind = node.kind; + return (kind === SyntaxKind.PropertyAccessExpression || kind === SyntaxKind.ElementAccessExpression) + && (node).expression.kind === SyntaxKind.ThisKeyword; + } + + export function getEntityNameFromTypeNode(node: TypeNode): EntityNameOrEntityNameExpression { switch (node.kind) { case SyntaxKind.TypeReference: return (node).typeName; diff --git a/tests/baselines/reference/abstractPropertyInConstructor.errors.txt b/tests/baselines/reference/abstractPropertyInConstructor.errors.txt index 63636b35725..0798d91ce78 100644 --- a/tests/baselines/reference/abstractPropertyInConstructor.errors.txt +++ b/tests/baselines/reference/abstractPropertyInConstructor.errors.txt @@ -5,7 +5,7 @@ tests/cases/compiler/abstractPropertyInConstructor.ts(9,14): error TS2715: Abstr ==== tests/cases/compiler/abstractPropertyInConstructor.ts (3 errors) ==== abstract class AbstractClass { - constructor(str: string) { + constructor(str: string, other: AbstractClass) { this.method(parseInt(str)); let val = this.prop.toLowerCase(); ~~~~ @@ -20,9 +20,13 @@ tests/cases/compiler/abstractPropertyInConstructor.ts(9,14): error TS2715: Abstr ~~ !!! error TS2715: Abstract property 'cb' in class 'AbstractClass' cannot be accessed in the constructor. + // OK, reference is inside function const innerFunction = () => { return this.prop; } + + // OK, references are to another instance + other.cb(other.prop); } abstract prop: string; diff --git a/tests/baselines/reference/abstractPropertyInConstructor.js b/tests/baselines/reference/abstractPropertyInConstructor.js index 5bf9726b283..5a4feda110f 100644 --- a/tests/baselines/reference/abstractPropertyInConstructor.js +++ b/tests/baselines/reference/abstractPropertyInConstructor.js @@ -1,6 +1,6 @@ //// [abstractPropertyInConstructor.ts] abstract class AbstractClass { - constructor(str: string) { + constructor(str: string, other: AbstractClass) { this.method(parseInt(str)); let val = this.prop.toLowerCase(); @@ -9,9 +9,13 @@ abstract class AbstractClass { } this.cb(str); + // OK, reference is inside function const innerFunction = () => { return this.prop; } + + // OK, references are to another instance + other.cb(other.prop); } abstract prop: string; @@ -36,7 +40,7 @@ class User { //// [abstractPropertyInConstructor.js] var AbstractClass = /** @class */ (function () { - function AbstractClass(str) { + function AbstractClass(str, other) { var _this = this; this.method(parseInt(str)); var val = this.prop.toLowerCase(); @@ -44,9 +48,12 @@ var AbstractClass = /** @class */ (function () { this.prop = "Hello World"; } this.cb(str); + // OK, reference is inside function var innerFunction = function () { return _this.prop; }; + // OK, references are to another instance + other.cb(other.prop); } AbstractClass.prototype.method2 = function () { this.prop = this.prop + "!"; diff --git a/tests/baselines/reference/abstractPropertyInConstructor.symbols b/tests/baselines/reference/abstractPropertyInConstructor.symbols index f6e29a58487..42cd3bb6827 100644 --- a/tests/baselines/reference/abstractPropertyInConstructor.symbols +++ b/tests/baselines/reference/abstractPropertyInConstructor.symbols @@ -2,98 +2,110 @@ abstract class AbstractClass { >AbstractClass : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) - constructor(str: string) { + constructor(str: string, other: AbstractClass) { >str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16)) +>other : Symbol(other, Decl(abstractPropertyInConstructor.ts, 1, 28)) +>AbstractClass : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) this.method(parseInt(str)); ->this.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 16, 37)) +>this.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37)) >this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) ->method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 16, 37)) +>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37)) >parseInt : Symbol(parseInt, Decl(lib.d.ts, --, --)) >str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16)) let val = this.prop.toLowerCase(); >val : Symbol(val, Decl(abstractPropertyInConstructor.ts, 3, 11)) >this.prop.toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --)) ->this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) +>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) >this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) ->prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) >toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --)) if (!str) { >str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16)) this.prop = "Hello World"; ->this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) +>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) >this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) ->prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) } this.cb(str); ->this.cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 15, 26)) +>this.cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26)) >this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) ->cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 15, 26)) +>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26)) >str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 1, 16)) + // OK, reference is inside function const innerFunction = () => { ->innerFunction : Symbol(innerFunction, Decl(abstractPropertyInConstructor.ts, 10, 13)) +>innerFunction : Symbol(innerFunction, Decl(abstractPropertyInConstructor.ts, 11, 13)) return this.prop; ->this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) +>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) >this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) ->prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) } + + // OK, references are to another instance + other.cb(other.prop); +>other.cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26)) +>other : Symbol(other, Decl(abstractPropertyInConstructor.ts, 1, 28)) +>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26)) +>other.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) +>other : Symbol(other, Decl(abstractPropertyInConstructor.ts, 1, 28)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) } abstract prop: string; ->prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) abstract cb: (s: string) => void; ->cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 15, 26)) ->s : Symbol(s, Decl(abstractPropertyInConstructor.ts, 16, 18)) +>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26)) +>s : Symbol(s, Decl(abstractPropertyInConstructor.ts, 20, 18)) abstract method(num: number): void; ->method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 16, 37)) ->num : Symbol(num, Decl(abstractPropertyInConstructor.ts, 18, 20)) +>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37)) +>num : Symbol(num, Decl(abstractPropertyInConstructor.ts, 22, 20)) method2() { ->method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 18, 39)) +>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 22, 39)) this.prop = this.prop + "!"; ->this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) +>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) >this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) ->prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) ->this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) +>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) >this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) ->prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) } } class User { ->User : Symbol(User, Decl(abstractPropertyInConstructor.ts, 23, 1)) +>User : Symbol(User, Decl(abstractPropertyInConstructor.ts, 27, 1)) constructor(a: AbstractClass) { ->a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 26, 16)) +>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16)) >AbstractClass : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) a.prop; ->a.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) ->a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 26, 16)) ->prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 13, 5)) +>a.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) +>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) a.cb("hi"); ->a.cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 15, 26)) ->a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 26, 16)) ->cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 15, 26)) +>a.cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26)) +>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16)) +>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26)) a.method(12); ->a.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 16, 37)) ->a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 26, 16)) ->method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 16, 37)) +>a.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37)) +>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16)) +>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37)) a.method2(); ->a.method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 18, 39)) ->a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 26, 16)) ->method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 18, 39)) +>a.method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 22, 39)) +>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16)) +>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 22, 39)) } } diff --git a/tests/baselines/reference/abstractPropertyInConstructor.types b/tests/baselines/reference/abstractPropertyInConstructor.types index a44403c1091..6f8970a7702 100644 --- a/tests/baselines/reference/abstractPropertyInConstructor.types +++ b/tests/baselines/reference/abstractPropertyInConstructor.types @@ -2,8 +2,10 @@ abstract class AbstractClass { >AbstractClass : AbstractClass - constructor(str: string) { + constructor(str: string, other: AbstractClass) { >str : string +>other : AbstractClass +>AbstractClass : AbstractClass this.method(parseInt(str)); >this.method(parseInt(str)) : void @@ -41,6 +43,7 @@ abstract class AbstractClass { >cb : (s: string) => void >str : string + // OK, reference is inside function const innerFunction = () => { >innerFunction : () => string >() => { return this.prop; } : () => string @@ -50,6 +53,16 @@ abstract class AbstractClass { >this : this >prop : string } + + // OK, references are to another instance + other.cb(other.prop); +>other.cb(other.prop) : void +>other.cb : (s: string) => void +>other : AbstractClass +>cb : (s: string) => void +>other.prop : string +>other : AbstractClass +>prop : string } abstract prop: string; diff --git a/tests/cases/compiler/abstractPropertyInConstructor.ts b/tests/cases/compiler/abstractPropertyInConstructor.ts index e58e052f8db..b8386f56e1e 100644 --- a/tests/cases/compiler/abstractPropertyInConstructor.ts +++ b/tests/cases/compiler/abstractPropertyInConstructor.ts @@ -1,5 +1,5 @@ abstract class AbstractClass { - constructor(str: string) { + constructor(str: string, other: AbstractClass) { this.method(parseInt(str)); let val = this.prop.toLowerCase(); @@ -8,9 +8,13 @@ abstract class AbstractClass { } this.cb(str); + // OK, reference is inside function const innerFunction = () => { return this.prop; } + + // OK, references are to another instance + other.cb(other.prop); } abstract prop: string; From 3c27e782da3b2242c42eb0e883cb0a58444b3dcf Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 16 Oct 2017 11:22:49 -0700 Subject: [PATCH 149/312] Add getCompilerOptions method to project Fixes #19218 --- src/server/project.ts | 4 ++++ tests/baselines/reference/api/tsserverlibrary.d.ts | 1 + 2 files changed, 5 insertions(+) diff --git a/src/server/project.ts b/src/server/project.ts index 7653fbf93cf..ca6e82ec4be 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -246,6 +246,10 @@ namespace ts.server { return this.compilerOptions; } + getCompilerOptions() { + return this.compilerOptions; + } + getNewLine() { return this.directoryStructureHost.newLine; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 151c948602d..e983ac73b15 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7109,6 +7109,7 @@ declare namespace ts.server { getCachedUnresolvedImportsPerFile_TestOnly(): UnresolvedImportsMap; static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {}; getCompilationSettings(): CompilerOptions; + getCompilerOptions(): CompilerOptions; getNewLine(): string; getProjectVersion(): string; getScriptFileNames(): string[]; From bac30fc1a2ab3d99c5f22891da8110d47c16e242 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 16 Oct 2017 11:41:35 -0700 Subject: [PATCH 150/312] In convertFunctionToEs6Class.ts, share code for getting symbol (#19160) --- .../refactors/convertFunctionToEs6Class.ts | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/services/refactors/convertFunctionToEs6Class.ts b/src/services/refactors/convertFunctionToEs6Class.ts index e9f229fa0d7..f5951bd26e4 100644 --- a/src/services/refactors/convertFunctionToEs6Class.ts +++ b/src/services/refactors/convertFunctionToEs6Class.ts @@ -17,16 +17,16 @@ namespace ts.refactor.convertFunctionToES6Class { return undefined; } - const start = context.startPosition; - const node = getTokenAtPosition(context.file, start, /*includeJsDocComment*/ false); - const checker = context.program.getTypeChecker(); - let symbol = checker.getSymbolAtLocation(node); + let symbol = getConstructorSymbol(context); + if (!symbol) { + return undefined; + } - if (symbol && isDeclarationOfFunctionOrClassExpression(symbol)) { + if (isDeclarationOfFunctionOrClassExpression(symbol)) { symbol = (symbol.valueDeclaration as VariableDeclaration).initializer.symbol; } - if (symbol && (symbol.flags & SymbolFlags.Function) && symbol.members && (symbol.members.size > 0)) { + if ((symbol.flags & SymbolFlags.Function) && symbol.members && (symbol.members.size > 0)) { return [ { name: convertFunctionToES6Class.name, @@ -48,11 +48,8 @@ namespace ts.refactor.convertFunctionToES6Class { return undefined; } - const start = context.startPosition; - const sourceFile = context.file; - const checker = context.program.getTypeChecker(); - const token = getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); - const ctorSymbol = checker.getSymbolAtLocation(token); + const { file: sourceFile } = context; + const ctorSymbol = getConstructorSymbol(context); const newLine = context.rulesProvider.getFormatOptions().newLineCharacter; const deletedNodes: Node[] = []; @@ -269,4 +266,10 @@ namespace ts.refactor.convertFunctionToES6Class { return filter(source.modifiers, modifier => modifier.kind === kind); } } -} + + function getConstructorSymbol({ startPosition, file, program }: RefactorContext): Symbol { + const checker = program.getTypeChecker(); + const token = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); + return checker.getSymbolAtLocation(token); + } +} \ No newline at end of file From 40222d1a77a32ae412df8bda49f7ff20cfd8c3ba Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 16 Oct 2017 12:57:23 -0700 Subject: [PATCH 151/312] Fix for-in emit under systemjs (#19223) --- src/compiler/transformers/module/system.ts | 5 ++++- .../reference/systemJsForInNoException.js | 19 ++++++++++++++++++ .../systemJsForInNoException.symbols | 16 +++++++++++++++ .../reference/systemJsForInNoException.types | 20 +++++++++++++++++++ .../compiler/systemJsForInNoException.ts | 5 +++++ 5 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/systemJsForInNoException.js create mode 100644 tests/baselines/reference/systemJsForInNoException.symbols create mode 100644 tests/baselines/reference/systemJsForInNoException.types create mode 100644 tests/cases/compiler/systemJsForInNoException.ts diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index ed943eb90ce..d674546efb9 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -826,7 +826,7 @@ namespace ts { /*needsValue*/ false, createAssignment ) - : createAssignment(node.name, visitNode(node.initializer, destructuringAndImportCallVisitor, isExpression)); + : node.initializer ? createAssignment(node.name, visitNode(node.initializer, destructuringAndImportCallVisitor, isExpression)) : node.name; } /** @@ -1296,6 +1296,9 @@ namespace ts { let expressions: Expression[]; for (const variable of node.declarations) { expressions = append(expressions, transformInitializedVariable(variable, /*isExportedDeclaration*/ false)); + if (!variable.initializer) { + hoistBindingElement(variable); + } } return expressions ? inlineExpressions(expressions) : createOmittedExpression(); diff --git a/tests/baselines/reference/systemJsForInNoException.js b/tests/baselines/reference/systemJsForInNoException.js new file mode 100644 index 00000000000..2ac31e18416 --- /dev/null +++ b/tests/baselines/reference/systemJsForInNoException.js @@ -0,0 +1,19 @@ +//// [systemJsForInNoException.ts] +export const obj = { a: 1 }; +for (var key in obj) + console.log(obj[key]); + +//// [systemJsForInNoException.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + var obj, key; + return { + setters: [], + execute: function () { + exports_1("obj", obj = { a: 1 }); + for (key in obj) + console.log(obj[key]); + } + }; +}); diff --git a/tests/baselines/reference/systemJsForInNoException.symbols b/tests/baselines/reference/systemJsForInNoException.symbols new file mode 100644 index 00000000000..4d4d2e0206c --- /dev/null +++ b/tests/baselines/reference/systemJsForInNoException.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/systemJsForInNoException.ts === +export const obj = { a: 1 }; +>obj : Symbol(obj, Decl(systemJsForInNoException.ts, 0, 12)) +>a : Symbol(a, Decl(systemJsForInNoException.ts, 0, 20)) + +for (var key in obj) +>key : Symbol(key, Decl(systemJsForInNoException.ts, 1, 8)) +>obj : Symbol(obj, Decl(systemJsForInNoException.ts, 0, 12)) + + console.log(obj[key]); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>obj : Symbol(obj, Decl(systemJsForInNoException.ts, 0, 12)) +>key : Symbol(key, Decl(systemJsForInNoException.ts, 1, 8)) + diff --git a/tests/baselines/reference/systemJsForInNoException.types b/tests/baselines/reference/systemJsForInNoException.types new file mode 100644 index 00000000000..6d9dbbb6e7b --- /dev/null +++ b/tests/baselines/reference/systemJsForInNoException.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/systemJsForInNoException.ts === +export const obj = { a: 1 }; +>obj : { a: number; } +>{ a: 1 } : { a: number; } +>a : number +>1 : 1 + +for (var key in obj) +>key : string +>obj : { a: number; } + + console.log(obj[key]); +>console.log(obj[key]) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>obj[key] : any +>obj : { a: number; } +>key : string + diff --git a/tests/cases/compiler/systemJsForInNoException.ts b/tests/cases/compiler/systemJsForInNoException.ts new file mode 100644 index 00000000000..e35c3aa24a3 --- /dev/null +++ b/tests/cases/compiler/systemJsForInNoException.ts @@ -0,0 +1,5 @@ +// @module: system +// @lib: es6,dom +export const obj = { a: 1 }; +for (var key in obj) + console.log(obj[key]); \ No newline at end of file From 2cb0403e2d6165e1eb3731173164f307f556ef0a Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 16 Oct 2017 13:02:15 -0700 Subject: [PATCH 152/312] Support 'package.json' not in package root (#19133) * Support 'package.json' not in package root * Test "foo/@bar" * More tests, and don't use "types" from the root package.json if not loading the root module --- src/compiler/moduleNameResolver.ts | 40 +++++++++++++------ ...Resolution_packageJson_notAtPackageRoot.js | 20 ++++++++++ ...ution_packageJson_notAtPackageRoot.symbols | 8 ++++ ...on_packageJson_notAtPackageRoot.trace.json | 14 +++++++ ...olution_packageJson_notAtPackageRoot.types | 8 ++++ ...Json_notAtPackageRoot_fakeScopedPackage.js | 20 ++++++++++ ...notAtPackageRoot_fakeScopedPackage.symbols | 8 ++++ ...AtPackageRoot_fakeScopedPackage.trace.json | 14 +++++++ ...n_notAtPackageRoot_fakeScopedPackage.types | 8 ++++ ...Resolution_packageJson_yesAtPackageRoot.js | 18 +++++++++ ...ution_packageJson_yesAtPackageRoot.symbols | 4 ++ ...on_packageJson_yesAtPackageRoot.trace.json | 22 ++++++++++ ...olution_packageJson_yesAtPackageRoot.types | 4 ++ ...Json_yesAtPackageRoot_fakeScopedPackage.js | 20 ++++++++++ ...yesAtPackageRoot_fakeScopedPackage.symbols | 4 ++ ...AtPackageRoot_fakeScopedPackage.trace.json | 22 ++++++++++ ...n_yesAtPackageRoot_fakeScopedPackage.types | 4 ++ ...Resolution_packageJson_notAtPackageRoot.ts | 16 ++++++++ ...Json_notAtPackageRoot_fakeScopedPackage.ts | 16 ++++++++ ...Resolution_packageJson_yesAtPackageRoot.ts | 14 +++++++ ...Json_yesAtPackageRoot_fakeScopedPackage.ts | 16 ++++++++ 21 files changed, 288 insertions(+), 12 deletions(-) create mode 100644 tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.js create mode 100644 tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.symbols create mode 100644 tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.trace.json create mode 100644 tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.types create mode 100644 tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.js create mode 100644 tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.symbols create mode 100644 tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.trace.json create mode 100644 tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.types create mode 100644 tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.js create mode 100644 tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.symbols create mode 100644 tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json create mode 100644 tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.types create mode 100644 tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.js create mode 100644 tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.symbols create mode 100644 tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json create mode 100644 tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.types create mode 100644 tests/cases/compiler/moduleResolution_packageJson_notAtPackageRoot.ts create mode 100644 tests/cases/compiler/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.ts create mode 100644 tests/cases/compiler/moduleResolution_packageJson_yesAtPackageRoot.ts create mode 100644 tests/cases/compiler/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.ts diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index ac83dd41311..08178d3d16a 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -77,16 +77,20 @@ namespace ts { traceEnabled: boolean; } - interface PackageJson { - name?: string; - version?: string; + /** Just the fields that we use for module resolution. */ + interface PackageJsonPathFields { typings?: string; types?: string; main?: string; } + interface PackageJson extends PackageJsonPathFields { + name?: string; + version?: string; + } + /** Reads from "main" or "types"/"typings" depending on `extensions`. */ - function tryReadPackageJsonFields(readTypes: boolean, jsonContent: PackageJson, baseDirectory: string, state: ModuleResolutionState): string | undefined { + function tryReadPackageJsonFields(readTypes: boolean, jsonContent: PackageJsonPathFields, baseDirectory: string, state: ModuleResolutionState): string | undefined { return readTypes ? tryReadFromField("typings") || tryReadFromField("types") : tryReadFromField("main"); function tryReadFromField(fieldName: "typings" | "types" | "main"): string | undefined { @@ -886,7 +890,7 @@ namespace ts { return withPackageId(packageId, loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, packageJsonContent)); } - function loadNodeModuleFromDirectoryWorker(extensions: Extensions, candidate: string, failedLookupLocations: Push, onlyRecordFailures: boolean, state: ModuleResolutionState, packageJsonContent: PackageJson | undefined): PathAndExtension | undefined { + function loadNodeModuleFromDirectoryWorker(extensions: Extensions, candidate: string, failedLookupLocations: Push, onlyRecordFailures: boolean, state: ModuleResolutionState, packageJsonContent: PackageJsonPathFields | undefined): PathAndExtension | undefined { const fromPackageJson = packageJsonContent && loadModuleFromPackageJson(packageJsonContent, extensions, candidate, failedLookupLocations, state); if (fromPackageJson) { return fromPackageJson; @@ -901,7 +905,7 @@ namespace ts { failedLookupLocations: Push, onlyRecordFailures: boolean, { host, traceEnabled }: ModuleResolutionState, - ): { packageJsonContent: PackageJson | undefined, packageId: PackageId | undefined } { + ): { found: boolean, packageJsonContent: PackageJsonPathFields | undefined, packageId: PackageId | undefined } { const directoryExists = !onlyRecordFailures && directoryProbablyExists(nodeModuleDirectory, host); const packageJsonPath = pathToPackageJson(nodeModuleDirectory); if (directoryExists && host.fileExists(packageJsonPath)) { @@ -912,7 +916,7 @@ namespace ts { const packageId: PackageId = typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string" ? { name: packageJsonContent.name, subModuleName, version: packageJsonContent.version } : undefined; - return { packageJsonContent, packageId }; + return { found: true, packageJsonContent, packageId }; } else { if (directoryExists && traceEnabled) { @@ -920,11 +924,11 @@ namespace ts { } // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results failedLookupLocations.push(packageJsonPath); - return { packageJsonContent: undefined, packageId: undefined }; + return { found: false, packageJsonContent: undefined, packageId: undefined }; } } - function loadModuleFromPackageJson(jsonContent: PackageJson, extensions: Extensions, candidate: string, failedLookupLocations: Push, state: ModuleResolutionState): PathAndExtension | undefined { + function loadModuleFromPackageJson(jsonContent: PackageJsonPathFields, extensions: Extensions, candidate: string, failedLookupLocations: Push, state: ModuleResolutionState): PathAndExtension | undefined { const file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, jsonContent, candidate, state); if (!file) { return undefined; @@ -976,10 +980,22 @@ namespace ts { } function loadModuleFromNodeModulesFolder(extensions: Extensions, moduleName: string, nodeModulesFolder: string, nodeModulesFolderExists: boolean, failedLookupLocations: Push, state: ModuleResolutionState): Resolved | undefined { - const { packageName, rest } = getPackageName(moduleName); - const packageRootPath = combinePaths(nodeModulesFolder, packageName); - const { packageJsonContent, packageId } = getPackageJsonInfo(packageRootPath, rest, failedLookupLocations, !nodeModulesFolderExists, state); const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName)); + // First look for a nested package.json, as in `node_modules/foo/bar/package.json`. + let packageJsonContent: PackageJsonPathFields | undefined; + let packageId: PackageId | undefined; + const packageInfo = getPackageJsonInfo(candidate, "", failedLookupLocations, /*onlyRecordFailures*/ !nodeModulesFolderExists, state); + if (packageInfo.found) { + ({ packageJsonContent, packageId } = packageInfo); + } + else { + const { packageName, rest } = getPackageName(moduleName); + if (rest !== "") { // If "rest" is empty, we just did this search above. + const packageRootPath = combinePaths(nodeModulesFolder, packageName); + // Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId. + packageId = getPackageJsonInfo(packageRootPath, rest, failedLookupLocations, !nodeModulesFolderExists, state).packageId; + } + } const pathAndExtension = loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) || loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state, packageJsonContent); return withPackageId(packageId, pathAndExtension); diff --git a/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.js b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.js new file mode 100644 index 00000000000..941774f4d35 --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.js @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/moduleResolution_packageJson_notAtPackageRoot.ts] //// + +//// [package.json] +// Loads from a "fake" nested package.json, not from the one at the root. + +{ "types": "types.d.ts" } + +//// [package.json] +{} + +//// [types.d.ts] +export const x: number; + +//// [a.ts] +import { x } from "foo/bar"; + + +//// [a.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.symbols b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.symbols new file mode 100644 index 00000000000..57aaa9a96ef --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.symbols @@ -0,0 +1,8 @@ +=== /a.ts === +import { x } from "foo/bar"; +>x : Symbol(x, Decl(a.ts, 0, 8)) + +=== /node_modules/foo/bar/types.d.ts === +export const x: number; +>x : Symbol(x, Decl(types.d.ts, 0, 12)) + diff --git a/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.trace.json b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.trace.json new file mode 100644 index 00000000000..bf5f0b0bbef --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.trace.json @@ -0,0 +1,14 @@ +[ + "======== Resolving module 'foo/bar' from '/a.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/foo/bar/package.json'.", + "File '/node_modules/foo/bar.ts' does not exist.", + "File '/node_modules/foo/bar.tsx' does not exist.", + "File '/node_modules/foo/bar.d.ts' does not exist.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'types.d.ts' that references '/node_modules/foo/bar/types.d.ts'.", + "File '/node_modules/foo/bar/types.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/foo/bar/types.d.ts', result '/node_modules/foo/bar/types.d.ts'.", + "======== Module name 'foo/bar' was successfully resolved to '/node_modules/foo/bar/types.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.types b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.types new file mode 100644 index 00000000000..68a1585d768 --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot.types @@ -0,0 +1,8 @@ +=== /a.ts === +import { x } from "foo/bar"; +>x : number + +=== /node_modules/foo/bar/types.d.ts === +export const x: number; +>x : number + diff --git a/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.js b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.js new file mode 100644 index 00000000000..45398289241 --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.js @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.ts] //// + +//// [package.json] +// Copy of `moduleResolution_packageJson_notAtPackageRoot` with `foo/@bar` instead of `foo/bar`. Should behave identically. + +{ "types": "types.d.ts" } + +//// [package.json] +{} + +//// [types.d.ts] +export const x: number; + +//// [a.ts] +import { x } from "foo/@bar"; + + +//// [a.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.symbols b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.symbols new file mode 100644 index 00000000000..de21d67b629 --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.symbols @@ -0,0 +1,8 @@ +=== /a.ts === +import { x } from "foo/@bar"; +>x : Symbol(x, Decl(a.ts, 0, 8)) + +=== /node_modules/foo/@bar/types.d.ts === +export const x: number; +>x : Symbol(x, Decl(types.d.ts, 0, 12)) + diff --git a/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.trace.json b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.trace.json new file mode 100644 index 00000000000..72d413d0b2c --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.trace.json @@ -0,0 +1,14 @@ +[ + "======== Resolving module 'foo/@bar' from '/a.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'foo/@bar' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/foo/@bar/package.json'.", + "File '/node_modules/foo/@bar.ts' does not exist.", + "File '/node_modules/foo/@bar.tsx' does not exist.", + "File '/node_modules/foo/@bar.d.ts' does not exist.", + "'package.json' does not have a 'typings' field.", + "'package.json' has 'types' field 'types.d.ts' that references '/node_modules/foo/@bar/types.d.ts'.", + "File '/node_modules/foo/@bar/types.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/foo/@bar/types.d.ts', result '/node_modules/foo/@bar/types.d.ts'.", + "======== Module name 'foo/@bar' was successfully resolved to '/node_modules/foo/@bar/types.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.types b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.types new file mode 100644 index 00000000000..6d8894ebce1 --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.types @@ -0,0 +1,8 @@ +=== /a.ts === +import { x } from "foo/@bar"; +>x : number + +=== /node_modules/foo/@bar/types.d.ts === +export const x: number; +>x : number + diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.js b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.js new file mode 100644 index 00000000000..ed006b0e62d --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.js @@ -0,0 +1,18 @@ +//// [tests/cases/compiler/moduleResolution_packageJson_yesAtPackageRoot.ts] //// + +//// [index.js] +not read + +//// [package.json] +{ "name": "foo", "version": "1.2.3", "types": "types.d.ts" } + +//// [types.d.ts] +export const x = 0; + +//// [a.ts] +import { x } from "foo/bar"; + + +//// [a.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.symbols b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.symbols new file mode 100644 index 00000000000..c037bb343b0 --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.symbols @@ -0,0 +1,4 @@ +=== /a.ts === +import { x } from "foo/bar"; +>x : Symbol(x, Decl(a.ts, 0, 8)) + diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json new file mode 100644 index 00000000000..3a87769891b --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json @@ -0,0 +1,22 @@ +[ + "======== Resolving module 'foo/bar' from '/a.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", + "File '/node_modules/foo/bar/package.json' does not exist.", + "Found 'package.json' at '/node_modules/foo/package.json'.", + "File '/node_modules/foo/bar.ts' does not exist.", + "File '/node_modules/foo/bar.tsx' does not exist.", + "File '/node_modules/foo/bar.d.ts' does not exist.", + "File '/node_modules/foo/bar/index.ts' does not exist.", + "File '/node_modules/foo/bar/index.tsx' does not exist.", + "File '/node_modules/foo/bar/index.d.ts' does not exist.", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Loading module 'foo/bar' from 'node_modules' folder, target file type 'JavaScript'.", + "File '/node_modules/foo/bar/package.json' does not exist.", + "Found 'package.json' at '/node_modules/foo/package.json'.", + "File '/node_modules/foo/bar.js' does not exist.", + "File '/node_modules/foo/bar.jsx' does not exist.", + "File '/node_modules/foo/bar/index.js' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/foo/bar/index.js', result '/node_modules/foo/bar/index.js'.", + "======== Module name 'foo/bar' was successfully resolved to '/node_modules/foo/bar/index.js'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.types b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.types new file mode 100644 index 00000000000..460aa4b8f05 --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.types @@ -0,0 +1,4 @@ +=== /a.ts === +import { x } from "foo/bar"; +>x : any + diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.js b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.js new file mode 100644 index 00000000000..129feb6060f --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.js @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.ts] //// + +//// [index.js] +// Copy of `moduleResolution_packageJson_notAtPackageRoot` with `foo/@bar` instead of `foo/bar`. Should behave identically. + +not read + +//// [package.json] +{ "name": "foo", "version": "1.2.3", "types": "types.d.ts" } + +//// [types.d.ts] +export const x = 0; + +//// [a.ts] +import { x } from "foo/@bar"; + + +//// [a.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.symbols b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.symbols new file mode 100644 index 00000000000..d1c3839b87b --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.symbols @@ -0,0 +1,4 @@ +=== /a.ts === +import { x } from "foo/@bar"; +>x : Symbol(x, Decl(a.ts, 0, 8)) + diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json new file mode 100644 index 00000000000..c28189a1f7d --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json @@ -0,0 +1,22 @@ +[ + "======== Resolving module 'foo/@bar' from '/a.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'foo/@bar' from 'node_modules' folder, target file type 'TypeScript'.", + "File '/node_modules/foo/@bar/package.json' does not exist.", + "Found 'package.json' at '/node_modules/foo/package.json'.", + "File '/node_modules/foo/@bar.ts' does not exist.", + "File '/node_modules/foo/@bar.tsx' does not exist.", + "File '/node_modules/foo/@bar.d.ts' does not exist.", + "File '/node_modules/foo/@bar/index.ts' does not exist.", + "File '/node_modules/foo/@bar/index.tsx' does not exist.", + "File '/node_modules/foo/@bar/index.d.ts' does not exist.", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Loading module 'foo/@bar' from 'node_modules' folder, target file type 'JavaScript'.", + "File '/node_modules/foo/@bar/package.json' does not exist.", + "Found 'package.json' at '/node_modules/foo/package.json'.", + "File '/node_modules/foo/@bar.js' does not exist.", + "File '/node_modules/foo/@bar.jsx' does not exist.", + "File '/node_modules/foo/@bar/index.js' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/foo/@bar/index.js', result '/node_modules/foo/@bar/index.js'.", + "======== Module name 'foo/@bar' was successfully resolved to '/node_modules/foo/@bar/index.js'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.types b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.types new file mode 100644 index 00000000000..47b12eea7a1 --- /dev/null +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.types @@ -0,0 +1,4 @@ +=== /a.ts === +import { x } from "foo/@bar"; +>x : any + diff --git a/tests/cases/compiler/moduleResolution_packageJson_notAtPackageRoot.ts b/tests/cases/compiler/moduleResolution_packageJson_notAtPackageRoot.ts new file mode 100644 index 00000000000..a93ea832b73 --- /dev/null +++ b/tests/cases/compiler/moduleResolution_packageJson_notAtPackageRoot.ts @@ -0,0 +1,16 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// Loads from a "fake" nested package.json, not from the one at the root. + +// @Filename: /node_modules/foo/bar/package.json +{ "types": "types.d.ts" } + +// @Filename: /node_modules/foo/package.json +{} + +// @Filename: /node_modules/foo/bar/types.d.ts +export const x: number; + +// @Filename: /a.ts +import { x } from "foo/bar"; diff --git a/tests/cases/compiler/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.ts b/tests/cases/compiler/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.ts new file mode 100644 index 00000000000..55e3963357f --- /dev/null +++ b/tests/cases/compiler/moduleResolution_packageJson_notAtPackageRoot_fakeScopedPackage.ts @@ -0,0 +1,16 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// Copy of `moduleResolution_packageJson_notAtPackageRoot` with `foo/@bar` instead of `foo/bar`. Should behave identically. + +// @Filename: /node_modules/foo/@bar/package.json +{ "types": "types.d.ts" } + +// @Filename: /node_modules/foo/package.json +{} + +// @Filename: /node_modules/foo/@bar/types.d.ts +export const x: number; + +// @Filename: /a.ts +import { x } from "foo/@bar"; diff --git a/tests/cases/compiler/moduleResolution_packageJson_yesAtPackageRoot.ts b/tests/cases/compiler/moduleResolution_packageJson_yesAtPackageRoot.ts new file mode 100644 index 00000000000..64e46c4e710 --- /dev/null +++ b/tests/cases/compiler/moduleResolution_packageJson_yesAtPackageRoot.ts @@ -0,0 +1,14 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// @Filename: /node_modules/foo/bar/index.js +not read + +// @Filename: /node_modules/foo/package.json +{ "name": "foo", "version": "1.2.3", "types": "types.d.ts" } + +// @Filename: /node_modules/foo/types.d.ts +export const x = 0; + +// @Filename: /a.ts +import { x } from "foo/bar"; diff --git a/tests/cases/compiler/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.ts b/tests/cases/compiler/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.ts new file mode 100644 index 00000000000..9b9f35b41e7 --- /dev/null +++ b/tests/cases/compiler/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.ts @@ -0,0 +1,16 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// Copy of `moduleResolution_packageJson_notAtPackageRoot` with `foo/@bar` instead of `foo/bar`. Should behave identically. + +// @Filename: /node_modules/foo/@bar/index.js +not read + +// @Filename: /node_modules/foo/package.json +{ "name": "foo", "version": "1.2.3", "types": "types.d.ts" } + +// @Filename: /node_modules/foo/types.d.ts +export const x = 0; + +// @Filename: /a.ts +import { x } from "foo/@bar"; From 734bda833c2236ab2360e798b9465425e80f62ab Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 16 Oct 2017 13:06:15 -0700 Subject: [PATCH 153/312] Add comments about why we need two methods that return compilerOptions --- src/server/project.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/server/project.ts b/src/server/project.ts index ca6e82ec4be..9c3fab63d23 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -242,12 +242,14 @@ namespace ts.server { this.markAsDirty(); } + // Method of LanguageServiceHost getCompilationSettings() { return this.compilerOptions; } + // Method to support public API getCompilerOptions() { - return this.compilerOptions; + return this.getCompilationSettings(); } getNewLine() { From aea7e9a7a812d02bf36fd0f36192fb81d8433afc Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 16 Oct 2017 14:17:55 -0700 Subject: [PATCH 154/312] Fix instantiated generic mixin declaration emit (#19144) * Fix #18545, dont use declared type of class expression * Accept API Baselines * Add thus far unused flag from node builder * Accept baseline update --- src/compiler/checker.ts | 2 +- .../declarationNoDanglingGenerics.js | 125 ++++++++++++++++++ .../declarationNoDanglingGenerics.symbols | 82 ++++++++++++ .../declarationNoDanglingGenerics.types | 98 ++++++++++++++ .../compiler/declarationNoDanglingGenerics.ts | 33 +++++ 5 files changed, 339 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/declarationNoDanglingGenerics.js create mode 100644 tests/baselines/reference/declarationNoDanglingGenerics.symbols create mode 100644 tests/baselines/reference/declarationNoDanglingGenerics.types create mode 100644 tests/cases/compiler/declarationNoDanglingGenerics.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 32086157552..8f8be4a10ef 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3398,7 +3398,7 @@ namespace ts { else if (flags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral && type.symbol.valueDeclaration && type.symbol.valueDeclaration.kind === SyntaxKind.ClassExpression) { - writeAnonymousType(getDeclaredTypeOfClassOrInterface(type.symbol), flags); + writeAnonymousType(type, flags); } else { // Write the type reference in the format f.g.C where A and B are type arguments diff --git a/tests/baselines/reference/declarationNoDanglingGenerics.js b/tests/baselines/reference/declarationNoDanglingGenerics.js new file mode 100644 index 00000000000..9045be6827b --- /dev/null +++ b/tests/baselines/reference/declarationNoDanglingGenerics.js @@ -0,0 +1,125 @@ +//// [declarationNoDanglingGenerics.ts] +const kindCache: { [kind: string]: boolean } = {}; + +function register(kind: string): void | never { + if (kindCache[kind]) { + throw new Error(`Class with kind "${kind}" is already registered.`); + } + kindCache[kind] = true; +} + +function ClassFactory(kind: TKind) { + register(kind); + + return class { + static readonly THE_KIND: TKind = kind; + readonly kind: TKind = kind; + }; +} + +class Kinds { + static readonly A = "A"; + static readonly B = "B"; + static readonly C = "C"; +} + +export class AKind extends ClassFactory(Kinds.A) { +} + +export class BKind extends ClassFactory(Kinds.B) { +} + +export class CKind extends ClassFactory(Kinds.C) { +} + +//// [declarationNoDanglingGenerics.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +var kindCache = {}; +function register(kind) { + if (kindCache[kind]) { + throw new Error("Class with kind \"" + kind + "\" is already registered."); + } + kindCache[kind] = true; +} +function ClassFactory(kind) { + register(kind); + return _a = /** @class */ (function () { + function class_1() { + this.kind = kind; + } + return class_1; + }()), + _a.THE_KIND = kind, + _a; + var _a; +} +var Kinds = /** @class */ (function () { + function Kinds() { + } + Kinds.A = "A"; + Kinds.B = "B"; + Kinds.C = "C"; + return Kinds; +}()); +var AKind = /** @class */ (function (_super) { + __extends(AKind, _super); + function AKind() { + return _super !== null && _super.apply(this, arguments) || this; + } + return AKind; +}(ClassFactory(Kinds.A))); +exports.AKind = AKind; +var BKind = /** @class */ (function (_super) { + __extends(BKind, _super); + function BKind() { + return _super !== null && _super.apply(this, arguments) || this; + } + return BKind; +}(ClassFactory(Kinds.B))); +exports.BKind = BKind; +var CKind = /** @class */ (function (_super) { + __extends(CKind, _super); + function CKind() { + return _super !== null && _super.apply(this, arguments) || this; + } + return CKind; +}(ClassFactory(Kinds.C))); +exports.CKind = CKind; + + +//// [declarationNoDanglingGenerics.d.ts] +declare const AKind_base: { + new (): { + readonly kind: "A"; + }; + readonly THE_KIND: "A"; +}; +export declare class AKind extends AKind_base { +} +declare const BKind_base: { + new (): { + readonly kind: "B"; + }; + readonly THE_KIND: "B"; +}; +export declare class BKind extends BKind_base { +} +declare const CKind_base: { + new (): { + readonly kind: "C"; + }; + readonly THE_KIND: "C"; +}; +export declare class CKind extends CKind_base { +} diff --git a/tests/baselines/reference/declarationNoDanglingGenerics.symbols b/tests/baselines/reference/declarationNoDanglingGenerics.symbols new file mode 100644 index 00000000000..512bf95d4bb --- /dev/null +++ b/tests/baselines/reference/declarationNoDanglingGenerics.symbols @@ -0,0 +1,82 @@ +=== tests/cases/compiler/declarationNoDanglingGenerics.ts === +const kindCache: { [kind: string]: boolean } = {}; +>kindCache : Symbol(kindCache, Decl(declarationNoDanglingGenerics.ts, 0, 5)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 0, 20)) + +function register(kind: string): void | never { +>register : Symbol(register, Decl(declarationNoDanglingGenerics.ts, 0, 50)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 2, 18)) + + if (kindCache[kind]) { +>kindCache : Symbol(kindCache, Decl(declarationNoDanglingGenerics.ts, 0, 5)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 2, 18)) + + throw new Error(`Class with kind "${kind}" is already registered.`); +>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 2, 18)) + } + kindCache[kind] = true; +>kindCache : Symbol(kindCache, Decl(declarationNoDanglingGenerics.ts, 0, 5)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 2, 18)) +} + +function ClassFactory(kind: TKind) { +>ClassFactory : Symbol(ClassFactory, Decl(declarationNoDanglingGenerics.ts, 7, 1)) +>TKind : Symbol(TKind, Decl(declarationNoDanglingGenerics.ts, 9, 22)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 9, 44)) +>TKind : Symbol(TKind, Decl(declarationNoDanglingGenerics.ts, 9, 22)) + + register(kind); +>register : Symbol(register, Decl(declarationNoDanglingGenerics.ts, 0, 50)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 9, 44)) + + return class { + static readonly THE_KIND: TKind = kind; +>THE_KIND : Symbol((Anonymous class).THE_KIND, Decl(declarationNoDanglingGenerics.ts, 12, 16)) +>TKind : Symbol(TKind, Decl(declarationNoDanglingGenerics.ts, 9, 22)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 9, 44)) + + readonly kind: TKind = kind; +>kind : Symbol((Anonymous class).kind, Decl(declarationNoDanglingGenerics.ts, 13, 43)) +>TKind : Symbol(TKind, Decl(declarationNoDanglingGenerics.ts, 9, 22)) +>kind : Symbol(kind, Decl(declarationNoDanglingGenerics.ts, 9, 44)) + + }; +} + +class Kinds { +>Kinds : Symbol(Kinds, Decl(declarationNoDanglingGenerics.ts, 16, 1)) + + static readonly A = "A"; +>A : Symbol(Kinds.A, Decl(declarationNoDanglingGenerics.ts, 18, 13)) + + static readonly B = "B"; +>B : Symbol(Kinds.B, Decl(declarationNoDanglingGenerics.ts, 19, 26)) + + static readonly C = "C"; +>C : Symbol(Kinds.C, Decl(declarationNoDanglingGenerics.ts, 20, 26)) +} + +export class AKind extends ClassFactory(Kinds.A) { +>AKind : Symbol(AKind, Decl(declarationNoDanglingGenerics.ts, 22, 1)) +>ClassFactory : Symbol(ClassFactory, Decl(declarationNoDanglingGenerics.ts, 7, 1)) +>Kinds.A : Symbol(Kinds.A, Decl(declarationNoDanglingGenerics.ts, 18, 13)) +>Kinds : Symbol(Kinds, Decl(declarationNoDanglingGenerics.ts, 16, 1)) +>A : Symbol(Kinds.A, Decl(declarationNoDanglingGenerics.ts, 18, 13)) +} + +export class BKind extends ClassFactory(Kinds.B) { +>BKind : Symbol(BKind, Decl(declarationNoDanglingGenerics.ts, 25, 1)) +>ClassFactory : Symbol(ClassFactory, Decl(declarationNoDanglingGenerics.ts, 7, 1)) +>Kinds.B : Symbol(Kinds.B, Decl(declarationNoDanglingGenerics.ts, 19, 26)) +>Kinds : Symbol(Kinds, Decl(declarationNoDanglingGenerics.ts, 16, 1)) +>B : Symbol(Kinds.B, Decl(declarationNoDanglingGenerics.ts, 19, 26)) +} + +export class CKind extends ClassFactory(Kinds.C) { +>CKind : Symbol(CKind, Decl(declarationNoDanglingGenerics.ts, 28, 1)) +>ClassFactory : Symbol(ClassFactory, Decl(declarationNoDanglingGenerics.ts, 7, 1)) +>Kinds.C : Symbol(Kinds.C, Decl(declarationNoDanglingGenerics.ts, 20, 26)) +>Kinds : Symbol(Kinds, Decl(declarationNoDanglingGenerics.ts, 16, 1)) +>C : Symbol(Kinds.C, Decl(declarationNoDanglingGenerics.ts, 20, 26)) +} diff --git a/tests/baselines/reference/declarationNoDanglingGenerics.types b/tests/baselines/reference/declarationNoDanglingGenerics.types new file mode 100644 index 00000000000..c650839be16 --- /dev/null +++ b/tests/baselines/reference/declarationNoDanglingGenerics.types @@ -0,0 +1,98 @@ +=== tests/cases/compiler/declarationNoDanglingGenerics.ts === +const kindCache: { [kind: string]: boolean } = {}; +>kindCache : { [kind: string]: boolean; } +>kind : string +>{} : {} + +function register(kind: string): void | never { +>register : (kind: string) => void +>kind : string + + if (kindCache[kind]) { +>kindCache[kind] : boolean +>kindCache : { [kind: string]: boolean; } +>kind : string + + throw new Error(`Class with kind "${kind}" is already registered.`); +>new Error(`Class with kind "${kind}" is already registered.`) : Error +>Error : ErrorConstructor +>`Class with kind "${kind}" is already registered.` : string +>kind : string + } + kindCache[kind] = true; +>kindCache[kind] = true : true +>kindCache[kind] : boolean +>kindCache : { [kind: string]: boolean; } +>kind : string +>true : true +} + +function ClassFactory(kind: TKind) { +>ClassFactory : (kind: TKind) => typeof (Anonymous class) +>TKind : TKind +>kind : TKind +>TKind : TKind + + register(kind); +>register(kind) : void +>register : (kind: string) => void +>kind : TKind + + return class { +>class { static readonly THE_KIND: TKind = kind; readonly kind: TKind = kind; } : typeof (Anonymous class) + + static readonly THE_KIND: TKind = kind; +>THE_KIND : TKind +>TKind : TKind +>kind : TKind + + readonly kind: TKind = kind; +>kind : TKind +>TKind : TKind +>kind : TKind + + }; +} + +class Kinds { +>Kinds : Kinds + + static readonly A = "A"; +>A : "A" +>"A" : "A" + + static readonly B = "B"; +>B : "B" +>"B" : "B" + + static readonly C = "C"; +>C : "C" +>"C" : "C" +} + +export class AKind extends ClassFactory(Kinds.A) { +>AKind : AKind +>ClassFactory(Kinds.A) : ClassFactory<"A">.(Anonymous class) +>ClassFactory : (kind: TKind) => typeof (Anonymous class) +>Kinds.A : "A" +>Kinds : typeof Kinds +>A : "A" +} + +export class BKind extends ClassFactory(Kinds.B) { +>BKind : BKind +>ClassFactory(Kinds.B) : ClassFactory<"B">.(Anonymous class) +>ClassFactory : (kind: TKind) => typeof (Anonymous class) +>Kinds.B : "B" +>Kinds : typeof Kinds +>B : "B" +} + +export class CKind extends ClassFactory(Kinds.C) { +>CKind : CKind +>ClassFactory(Kinds.C) : ClassFactory<"C">.(Anonymous class) +>ClassFactory : (kind: TKind) => typeof (Anonymous class) +>Kinds.C : "C" +>Kinds : typeof Kinds +>C : "C" +} diff --git a/tests/cases/compiler/declarationNoDanglingGenerics.ts b/tests/cases/compiler/declarationNoDanglingGenerics.ts new file mode 100644 index 00000000000..baedcc8a74e --- /dev/null +++ b/tests/cases/compiler/declarationNoDanglingGenerics.ts @@ -0,0 +1,33 @@ +// @declaration: true +const kindCache: { [kind: string]: boolean } = {}; + +function register(kind: string): void | never { + if (kindCache[kind]) { + throw new Error(`Class with kind "${kind}" is already registered.`); + } + kindCache[kind] = true; +} + +function ClassFactory(kind: TKind) { + register(kind); + + return class { + static readonly THE_KIND: TKind = kind; + readonly kind: TKind = kind; + }; +} + +class Kinds { + static readonly A = "A"; + static readonly B = "B"; + static readonly C = "C"; +} + +export class AKind extends ClassFactory(Kinds.A) { +} + +export class BKind extends ClassFactory(Kinds.B) { +} + +export class CKind extends ClassFactory(Kinds.C) { +} \ No newline at end of file From 9563246993fdc4d323db60179a8bfd84a943cd70 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 16 Oct 2017 14:26:16 -0700 Subject: [PATCH 155/312] Do not reduce subtypes of awaited union type --- src/compiler/checker.ts | 2 +- .../baselines/reference/awaitUnionPromise.js | 89 +++++++++++++++++++ .../reference/awaitUnionPromise.symbols | 67 ++++++++++++++ .../reference/awaitUnionPromise.types | 76 ++++++++++++++++ tests/cases/compiler/awaitUnionPromise.ts | 19 ++++ 5 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/awaitUnionPromise.js create mode 100644 tests/baselines/reference/awaitUnionPromise.symbols create mode 100644 tests/baselines/reference/awaitUnionPromise.types create mode 100644 tests/cases/compiler/awaitUnionPromise.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9347329e624..9934793ace5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19680,7 +19680,7 @@ namespace ts { return undefined; } - return typeAsAwaitable.awaitedTypeOfType = getUnionType(types, /*subtypeReduction*/ true); + return typeAsAwaitable.awaitedTypeOfType = getUnionType(types); } const promisedType = getPromisedTypeOfPromise(type); diff --git a/tests/baselines/reference/awaitUnionPromise.js b/tests/baselines/reference/awaitUnionPromise.js new file mode 100644 index 00000000000..df4c937fc63 --- /dev/null +++ b/tests/baselines/reference/awaitUnionPromise.js @@ -0,0 +1,89 @@ +//// [awaitUnionPromise.ts] +/// @target: es2015 +// https://github.com/Microsoft/TypeScript/issues/18186 + +class AsyncEnumeratorDone { }; + +interface IAsyncEnumerator { + next1(): Promise; + next2(): Promise | Promise; + next3(): Promise; + next4(): Promise; +} + +async function main() { + const x: IAsyncEnumerator = null; + let a = await x.next1(); + let b = await x.next2(); + let c = await x.next3(); + let d = await x.next4(); +} + +//// [awaitUnionPromise.js] +/// @target: es2015 +// https://github.com/Microsoft/TypeScript/issues/18186 +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var AsyncEnumeratorDone = /** @class */ (function () { + function AsyncEnumeratorDone() { + } + return AsyncEnumeratorDone; +}()); +; +function main() { + return __awaiter(this, void 0, void 0, function () { + var x, a, b, c, d; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + x = null; + return [4 /*yield*/, x.next1()]; + case 1: + a = _a.sent(); + return [4 /*yield*/, x.next2()]; + case 2: + b = _a.sent(); + return [4 /*yield*/, x.next3()]; + case 3: + c = _a.sent(); + return [4 /*yield*/, x.next4()]; + case 4: + d = _a.sent(); + return [2 /*return*/]; + } + }); + }); +} diff --git a/tests/baselines/reference/awaitUnionPromise.symbols b/tests/baselines/reference/awaitUnionPromise.symbols new file mode 100644 index 00000000000..fb26ba1bfac --- /dev/null +++ b/tests/baselines/reference/awaitUnionPromise.symbols @@ -0,0 +1,67 @@ +=== tests/cases/compiler/awaitUnionPromise.ts === +/// @target: es2015 +// https://github.com/Microsoft/TypeScript/issues/18186 + +class AsyncEnumeratorDone { }; +>AsyncEnumeratorDone : Symbol(AsyncEnumeratorDone, Decl(awaitUnionPromise.ts, 0, 0)) + +interface IAsyncEnumerator { +>IAsyncEnumerator : Symbol(IAsyncEnumerator, Decl(awaitUnionPromise.ts, 3, 30)) +>T : Symbol(T, Decl(awaitUnionPromise.ts, 5, 27)) + + next1(): Promise; +>next1 : Symbol(IAsyncEnumerator.next1, Decl(awaitUnionPromise.ts, 5, 31)) +>Promise : Symbol(Promise, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(awaitUnionPromise.ts, 5, 27)) +>AsyncEnumeratorDone : Symbol(AsyncEnumeratorDone, Decl(awaitUnionPromise.ts, 0, 0)) + + next2(): Promise | Promise; +>next2 : Symbol(IAsyncEnumerator.next2, Decl(awaitUnionPromise.ts, 6, 46)) +>Promise : Symbol(Promise, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(awaitUnionPromise.ts, 5, 27)) +>Promise : Symbol(Promise, Decl(lib.d.ts, --, --)) +>AsyncEnumeratorDone : Symbol(AsyncEnumeratorDone, Decl(awaitUnionPromise.ts, 0, 0)) + + next3(): Promise; +>next3 : Symbol(IAsyncEnumerator.next3, Decl(awaitUnionPromise.ts, 7, 55)) +>Promise : Symbol(Promise, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(awaitUnionPromise.ts, 5, 27)) + + next4(): Promise; +>next4 : Symbol(IAsyncEnumerator.next4, Decl(awaitUnionPromise.ts, 8, 29)) +>Promise : Symbol(Promise, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(awaitUnionPromise.ts, 5, 27)) +>x : Symbol(x, Decl(awaitUnionPromise.ts, 9, 26)) +} + +async function main() { +>main : Symbol(main, Decl(awaitUnionPromise.ts, 10, 1)) + + const x: IAsyncEnumerator = null; +>x : Symbol(x, Decl(awaitUnionPromise.ts, 13, 9)) +>IAsyncEnumerator : Symbol(IAsyncEnumerator, Decl(awaitUnionPromise.ts, 3, 30)) + + let a = await x.next1(); +>a : Symbol(a, Decl(awaitUnionPromise.ts, 14, 7)) +>x.next1 : Symbol(IAsyncEnumerator.next1, Decl(awaitUnionPromise.ts, 5, 31)) +>x : Symbol(x, Decl(awaitUnionPromise.ts, 13, 9)) +>next1 : Symbol(IAsyncEnumerator.next1, Decl(awaitUnionPromise.ts, 5, 31)) + + let b = await x.next2(); +>b : Symbol(b, Decl(awaitUnionPromise.ts, 15, 7)) +>x.next2 : Symbol(IAsyncEnumerator.next2, Decl(awaitUnionPromise.ts, 6, 46)) +>x : Symbol(x, Decl(awaitUnionPromise.ts, 13, 9)) +>next2 : Symbol(IAsyncEnumerator.next2, Decl(awaitUnionPromise.ts, 6, 46)) + + let c = await x.next3(); +>c : Symbol(c, Decl(awaitUnionPromise.ts, 16, 7)) +>x.next3 : Symbol(IAsyncEnumerator.next3, Decl(awaitUnionPromise.ts, 7, 55)) +>x : Symbol(x, Decl(awaitUnionPromise.ts, 13, 9)) +>next3 : Symbol(IAsyncEnumerator.next3, Decl(awaitUnionPromise.ts, 7, 55)) + + let d = await x.next4(); +>d : Symbol(d, Decl(awaitUnionPromise.ts, 17, 7)) +>x.next4 : Symbol(IAsyncEnumerator.next4, Decl(awaitUnionPromise.ts, 8, 29)) +>x : Symbol(x, Decl(awaitUnionPromise.ts, 13, 9)) +>next4 : Symbol(IAsyncEnumerator.next4, Decl(awaitUnionPromise.ts, 8, 29)) +} diff --git a/tests/baselines/reference/awaitUnionPromise.types b/tests/baselines/reference/awaitUnionPromise.types new file mode 100644 index 00000000000..f1d91c038de --- /dev/null +++ b/tests/baselines/reference/awaitUnionPromise.types @@ -0,0 +1,76 @@ +=== tests/cases/compiler/awaitUnionPromise.ts === +/// @target: es2015 +// https://github.com/Microsoft/TypeScript/issues/18186 + +class AsyncEnumeratorDone { }; +>AsyncEnumeratorDone : AsyncEnumeratorDone + +interface IAsyncEnumerator { +>IAsyncEnumerator : IAsyncEnumerator +>T : T + + next1(): Promise; +>next1 : () => Promise +>Promise : Promise +>T : T +>AsyncEnumeratorDone : AsyncEnumeratorDone + + next2(): Promise | Promise; +>next2 : () => Promise | Promise +>Promise : Promise +>T : T +>Promise : Promise +>AsyncEnumeratorDone : AsyncEnumeratorDone + + next3(): Promise; +>next3 : () => Promise<{} | T> +>Promise : Promise +>T : T + + next4(): Promise; +>next4 : () => Promise +>Promise : Promise +>T : T +>x : string +} + +async function main() { +>main : () => Promise + + const x: IAsyncEnumerator = null; +>x : IAsyncEnumerator +>IAsyncEnumerator : IAsyncEnumerator +>null : null + + let a = await x.next1(); +>a : number | AsyncEnumeratorDone +>await x.next1() : number | AsyncEnumeratorDone +>x.next1() : Promise +>x.next1 : () => Promise +>x : IAsyncEnumerator +>next1 : () => Promise + + let b = await x.next2(); +>b : number | AsyncEnumeratorDone +>await x.next2() : number | AsyncEnumeratorDone +>x.next2() : Promise | Promise +>x.next2 : () => Promise | Promise +>x : IAsyncEnumerator +>next2 : () => Promise | Promise + + let c = await x.next3(); +>c : number | {} +>await x.next3() : number | {} +>x.next3() : Promise +>x.next3 : () => Promise +>x : IAsyncEnumerator +>next3 : () => Promise + + let d = await x.next4(); +>d : number | { x: string; } +>await x.next4() : number | { x: string; } +>x.next4() : Promise +>x.next4 : () => Promise +>x : IAsyncEnumerator +>next4 : () => Promise +} diff --git a/tests/cases/compiler/awaitUnionPromise.ts b/tests/cases/compiler/awaitUnionPromise.ts new file mode 100644 index 00000000000..2c8470e97a6 --- /dev/null +++ b/tests/cases/compiler/awaitUnionPromise.ts @@ -0,0 +1,19 @@ +/// @target: es2015 +// https://github.com/Microsoft/TypeScript/issues/18186 + +class AsyncEnumeratorDone { }; + +interface IAsyncEnumerator { + next1(): Promise; + next2(): Promise | Promise; + next3(): Promise; + next4(): Promise; +} + +async function main() { + const x: IAsyncEnumerator = null; + let a = await x.next1(); + let b = await x.next2(); + let c = await x.next3(); + let d = await x.next4(); +} \ No newline at end of file From eebb0447ab3ad06adf252ed9eb81a16e54832a51 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 16 Oct 2017 14:47:43 -0700 Subject: [PATCH 156/312] Fix generated name scope when emitting async functions --- src/compiler/transformers/es2017.ts | 2 +- .../asyncFunctionTempVariableScoping.js | 64 +++++++++++++++++++ .../asyncFunctionTempVariableScoping.symbols | 10 +++ .../asyncFunctionTempVariableScoping.types | 13 ++++ .../asyncFunctionTempVariableScoping.ts | 5 ++ 5 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/asyncFunctionTempVariableScoping.js create mode 100644 tests/baselines/reference/asyncFunctionTempVariableScoping.symbols create mode 100644 tests/baselines/reference/asyncFunctionTempVariableScoping.types create mode 100644 tests/cases/compiler/asyncFunctionTempVariableScoping.ts diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index d98f227e8c7..9fa39da2d23 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -463,7 +463,7 @@ namespace ts { ); // Mark this node as originally an async function - (generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= EmitFlags.AsyncFunctionBody; + (generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= EmitFlags.AsyncFunctionBody | EmitFlags.ReuseTempVariableScope; return createCall( getHelperName("__awaiter"), diff --git a/tests/baselines/reference/asyncFunctionTempVariableScoping.js b/tests/baselines/reference/asyncFunctionTempVariableScoping.js new file mode 100644 index 00000000000..b4f8caa6508 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionTempVariableScoping.js @@ -0,0 +1,64 @@ +//// [asyncFunctionTempVariableScoping.ts] +// https://github.com/Microsoft/TypeScript/issues/19187 + +async ({ foo, bar, ...rest }) => bar(await foo); + +//// [asyncFunctionTempVariableScoping.js] +// https://github.com/Microsoft/TypeScript/issues/19187 +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +var _this = this; +(function (_a) { return __awaiter(_this, void 0, void 0, function () { + var foo = _a.foo, bar = _a.bar, rest = __rest(_a, ["foo", "bar"]); + var _b; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + _b = bar; + return [4 /*yield*/, foo]; + case 1: return [2 /*return*/, _b.apply(void 0, [_c.sent()])]; + } + }); +}); }); diff --git a/tests/baselines/reference/asyncFunctionTempVariableScoping.symbols b/tests/baselines/reference/asyncFunctionTempVariableScoping.symbols new file mode 100644 index 00000000000..578cda3ac77 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionTempVariableScoping.symbols @@ -0,0 +1,10 @@ +=== tests/cases/compiler/asyncFunctionTempVariableScoping.ts === +// https://github.com/Microsoft/TypeScript/issues/19187 + +async ({ foo, bar, ...rest }) => bar(await foo); +>foo : Symbol(foo, Decl(asyncFunctionTempVariableScoping.ts, 2, 8)) +>bar : Symbol(bar, Decl(asyncFunctionTempVariableScoping.ts, 2, 13)) +>rest : Symbol(rest, Decl(asyncFunctionTempVariableScoping.ts, 2, 18)) +>bar : Symbol(bar, Decl(asyncFunctionTempVariableScoping.ts, 2, 13)) +>foo : Symbol(foo, Decl(asyncFunctionTempVariableScoping.ts, 2, 8)) + diff --git a/tests/baselines/reference/asyncFunctionTempVariableScoping.types b/tests/baselines/reference/asyncFunctionTempVariableScoping.types new file mode 100644 index 00000000000..30b23994903 --- /dev/null +++ b/tests/baselines/reference/asyncFunctionTempVariableScoping.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/asyncFunctionTempVariableScoping.ts === +// https://github.com/Microsoft/TypeScript/issues/19187 + +async ({ foo, bar, ...rest }) => bar(await foo); +>async ({ foo, bar, ...rest }) => bar(await foo) : ({ foo, bar, ...rest }: { [x: string]: any; foo: any; bar: any; }) => Promise +>foo : any +>bar : any +>rest : { [x: string]: any; } +>bar(await foo) : any +>bar : any +>await foo : any +>foo : any + diff --git a/tests/cases/compiler/asyncFunctionTempVariableScoping.ts b/tests/cases/compiler/asyncFunctionTempVariableScoping.ts new file mode 100644 index 00000000000..c1d52d6da17 --- /dev/null +++ b/tests/cases/compiler/asyncFunctionTempVariableScoping.ts @@ -0,0 +1,5 @@ +// @target: es5 +// @lib: es2015 +// https://github.com/Microsoft/TypeScript/issues/19187 + +async ({ foo, bar, ...rest }) => bar(await foo); \ No newline at end of file From fd86cd5a2ed120127f41a8a3c62dde9dd38d6a5e Mon Sep 17 00:00:00 2001 From: csigs Date: Mon, 16 Oct 2017 22:10:47 +0000 Subject: [PATCH 157/312] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 6 + .../diagnosticMessages.generated.json.lcl | 17094 ++++++++-------- 2 files changed, 8592 insertions(+), 8508 deletions(-) diff --git a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl index a2963d878f6..ec0503ee41f 100644 --- a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -3990,12 +3990,18 @@ + + + + + + diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl index affa7a48347..bcd7c4e2982 100644 --- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,8509 +1,8587 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - veya - biçiminde olmalıdır. Örneğin, '{0}' veya '{1}'.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - türü olmalıdır.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()' kullanın.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + veya - biçiminde olmalıdır. Örneğin, '{0}' veya '{1}'.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + türü olmalıdır.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()' kullanın.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 3c452057c2fb88098691bb16a7c490f91d17d6f2 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 16 Oct 2017 16:09:16 -0700 Subject: [PATCH 158/312] Add release-2.6 to covered branches --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 27b14739d8b..d24e155b580 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,7 @@ branches: only: - master - release-2.5 + - release-2.6 install: - npm uninstall typescript --no-save From 50628e73c57185b59e12fecde15ce1654fa95e56 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 16 Oct 2017 16:53:33 -0700 Subject: [PATCH 159/312] Do not watch root folders for failed lookup locations and effective type roots Fixes #19170 --- src/compiler/resolutionCache.ts | 72 +++++++-- src/harness/unittests/tscWatchMode.ts | 4 +- .../unittests/tsserverProjectSystem.ts | 142 +++++++++++------- 3 files changed, 148 insertions(+), 70 deletions(-) diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index 84fffbe6f5e..b988da0fd5f 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -64,6 +64,7 @@ namespace ts { interface DirectoryOfFailedLookupWatch { dir: string; dirPath: Path; + ignore?: true; } export const maxNumberOfFilesToIterateForInvalidation = 256; @@ -319,6 +320,33 @@ namespace ts { return endsWith(dirPath, "/node_modules"); } + function isDirectoryAtleastAtLevelFromFSRoot(dirPath: Path, minLevels: number) { + for (let searchIndex = getRootLength(dirPath); minLevels > 0; minLevels--) { + searchIndex = dirPath.indexOf(directorySeparator, searchIndex) + 1; + if (searchIndex === 0) { + // Folder isnt at expected minimun levels + return false; + } + } + return true; + } + + function canWatchDirectory(dirPath: Path) { + return isDirectoryAtleastAtLevelFromFSRoot(dirPath, + // When root is "/" do not watch directories like: + // "/", "/user", "/user/username", "/user/username/folderAtRoot" + // When root is "c:/" do not watch directories like: + // "c:/", "c:/folderAtRoot" + dirPath.charCodeAt(0) === CharacterCodes.slash ? 3 : 1); + } + + function filterFSRootDirectoriesToWatch(watchPath: DirectoryOfFailedLookupWatch, dirPath: Path): DirectoryOfFailedLookupWatch { + if (!canWatchDirectory(dirPath)) { + watchPath.ignore = true; + } + return watchPath; + } + function getDirectoryToWatchFailedLookupLocation(failedLookupLocation: string, failedLookupLocationPath: Path): DirectoryOfFailedLookupWatch { if (isInDirectoryPath(rootPath, failedLookupLocationPath)) { return { dir: rootDir, dirPath: rootPath }; @@ -335,7 +363,7 @@ namespace ts { // If the directory is node_modules use it to watch if (isNodeModulesDirectory(dirPath)) { - return { dir, dirPath }; + return filterFSRootDirectoriesToWatch({ dir, dirPath }, getDirectoryPath(dirPath)); } // Use some ancestor of the root directory @@ -350,7 +378,7 @@ namespace ts { } } - return { dir, dirPath }; + return filterFSRootDirectoriesToWatch({ dir, dirPath }, dirPath); } function isPathWithDefaultFailedLookupExtension(path: Path) { @@ -391,13 +419,15 @@ namespace ts { const refCount = customFailedLookupPaths.get(failedLookupLocationPath) || 0; customFailedLookupPaths.set(failedLookupLocationPath, refCount + 1); } - const { dir, dirPath } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath); - const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath); - if (dirWatcher) { - dirWatcher.refCount++; - } - else { - directoryWatchesOfFailedLookups.set(dirPath, { watcher: createDirectoryWatcher(dir, dirPath), refCount: 1 }); + const { dir, dirPath, ignore } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath); + if (!ignore) { + const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath); + if (dirWatcher) { + dirWatcher.refCount++; + } + else { + directoryWatchesOfFailedLookups.set(dirPath, { watcher: createDirectoryWatcher(dir, dirPath), refCount: 1 }); + } } } } @@ -422,10 +452,12 @@ namespace ts { customFailedLookupPaths.set(failedLookupLocationPath, refCount - 1); } } - const { dirPath } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath); - const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath); - // Do not close the watcher yet since it might be needed by other failed lookup locations. - dirWatcher.refCount--; + const { dirPath, ignore } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath); + if (!ignore) { + const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath); + // Do not close the watcher yet since it might be needed by other failed lookup locations. + dirWatcher.refCount--; + } } } @@ -577,7 +609,8 @@ namespace ts { } // we need to assume the directories exist to ensure that we can get all the type root directories that get included - const typeRoots = getEffectiveTypeRoots(options, { directoryExists: returnTrue, getCurrentDirectory }); + // But filter directories that are at root level to say directory doesnt exist, so that we arent watching them + const typeRoots = getEffectiveTypeRoots(options, { directoryExists: directoryExistsForTypeRootWatch, getCurrentDirectory }); if (typeRoots) { mutateMap( typeRootsWatches, @@ -592,5 +625,16 @@ namespace ts { closeTypeRootsWatch(); } } + + /** + * Use this function to return if directory exists to get type roots to watch + * If we return directory exists then only the paths will be added to type roots + * Hence return true for all directories except root directories which are filtered from watching + */ + function directoryExistsForTypeRootWatch(nodeTypesDirectory: string) { + const dir = getDirectoryPath(getDirectoryPath(nodeTypesDirectory)); + const dirPath = resolutionHost.toPath(dir); + return dirPath === rootPath || canWatchDirectory(dirPath); + } } } diff --git a/src/harness/unittests/tscWatchMode.ts b/src/harness/unittests/tscWatchMode.ts index b25a7b1eb53..24052bd1add 100644 --- a/src/harness/unittests/tscWatchMode.ts +++ b/src/harness/unittests/tscWatchMode.ts @@ -254,7 +254,7 @@ namespace ts.tscWatch { checkProgramRootFiles(watch(), [file1.path, file2.path]); checkWatchedFiles(host, [configFile.path, file1.path, file2.path, libFile.path]); const configDir = getDirectoryPath(configFile.path); - checkWatchedDirectories(host, projectSystem.getTypeRootsFromLocation(configDir).concat(configDir), /*recursive*/ true); + checkWatchedDirectories(host, [configDir, combinePaths(configDir, projectSystem.nodeModulesAtTypes)], /*recursive*/ true); }); // TODO: if watching for config file creation @@ -269,7 +269,7 @@ namespace ts.tscWatch { const host = createWatchedSystem([commonFile1, libFile, configFile]); const watch = createWatchModeWithConfigFile(configFile.path, host); const configDir = getDirectoryPath(configFile.path); - checkWatchedDirectories(host, projectSystem.getTypeRootsFromLocation(configDir).concat(configDir), /*recursive*/ true); + checkWatchedDirectories(host, [configDir, combinePaths(configDir, projectSystem.nodeModulesAtTypes)], /*recursive*/ true); checkProgramRootFiles(watch(), [commonFile1.path]); diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 4929cbfbaa5..175b579103f 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -323,14 +323,31 @@ namespace ts.projectSystem { checkFileNames(`${server.ProjectKind[project.projectKind]} project, rootFileNames`, project.getRootFiles(), expectedFiles); } - function getNodeModuleDirectories(dir: string) { + function mapCombinedPathsInAncestor(dir: string, path2: string, mapAncestor: (ancestor: string) => boolean) { + dir = normalizePath(dir); const result: string[] = []; forEachAncestorDirectory(dir, ancestor => { - result.push(combinePaths(ancestor, "node_modules")); + if (mapAncestor(ancestor)) { + result.push(combinePaths(ancestor, path2)); + } }); return result; } + function getRootsToWatchWithAncestorDirectory(dir: string, path2: string) { + return mapCombinedPathsInAncestor(dir, path2, ancestor => ancestor.split(directorySeparator).length > 4); + } + + const nodeModules = "node_modules"; + function getNodeModuleDirectories(dir: string) { + return getRootsToWatchWithAncestorDirectory(dir, nodeModules); + } + + export const nodeModulesAtTypes = "node_modules/@types"; + export function getTypeRootsFromLocation(currentDirectory: string) { + return getRootsToWatchWithAncestorDirectory(currentDirectory, nodeModulesAtTypes); + } + function getNumberOfWatchesInvokedForRecursiveWatches(recursiveWatchedDirs: string[], file: string) { return countWhere(recursiveWatchedDirs, dir => file.length > dir.length && startsWith(file, dir) && file[dir.length] === directorySeparator); } @@ -413,15 +430,6 @@ namespace ts.projectSystem { verifyDiagnostics(actual, []); } - export function getTypeRootsFromLocation(currentDirectory: string) { - currentDirectory = normalizePath(currentDirectory); - const result: string[] = []; - forEachAncestorDirectory(currentDirectory, ancestor => { - result.push(combinePaths(ancestor, "node_modules/@types")); - }); - return result; - } - describe("tsserverProjectSystem", () => { const commonFile1: FileOrFolder = { path: "/a/b/commonFile1.ts", @@ -460,7 +468,7 @@ namespace ts.projectSystem { const configFiles = flatMap(configFileLocations, location => [location + "tsconfig.json", location + "jsconfig.json"]); checkWatchedFiles(host, configFiles.concat(libFile.path, moduleFile.path)); checkWatchedDirectories(host, [], /*recursive*/ false); - checkWatchedDirectories(host, ["/a/b/c", ...getTypeRootsFromLocation(getDirectoryPath(appFile.path))], /*recursive*/ true); + checkWatchedDirectories(host, ["/a/b/c", combinePaths(getDirectoryPath(appFile.path), nodeModulesAtTypes)], /*recursive*/ true); }); it("can handle tsconfig file name with difference casing", () => { @@ -532,7 +540,7 @@ namespace ts.projectSystem { // watching all files except one that was open checkWatchedFiles(host, [configFile.path, file2.path, libFile.path]); const configFileDirectory = getDirectoryPath(configFile.path); - checkWatchedDirectories(host, getTypeRootsFromLocation(configFileDirectory).concat(configFileDirectory), /*recursive*/ true); + checkWatchedDirectories(host, [configFileDirectory, combinePaths(configFileDirectory, nodeModulesAtTypes)], /*recursive*/ true); }); it("create configured project with the file list", () => { @@ -621,7 +629,7 @@ namespace ts.projectSystem { const projectService = createProjectService(host); projectService.openClientFile(commonFile1.path); const configFileDir = getDirectoryPath(configFile.path); - checkWatchedDirectories(host, getTypeRootsFromLocation(configFileDir).concat(configFileDir), /*recursive*/ true); + checkWatchedDirectories(host, [configFileDir, combinePaths(configFileDir, nodeModulesAtTypes)], /*recursive*/ true); checkNumberOfConfiguredProjects(projectService, 1); const project = configuredProjectAt(projectService, 0); @@ -2433,7 +2441,7 @@ namespace ts.projectSystem { checkProjectActualFiles(project, map(files, file => file.path)); checkWatchedFiles(host, mapDefined(files, file => file === file1 ? undefined : file.path)); checkWatchedDirectories(host, [], /*recursive*/ false); - const watchedRecursiveDirectories = getTypeRootsFromLocation("/a/b"); + const watchedRecursiveDirectories = ["/a/b/node_modules/@types"]; watchedRecursiveDirectories.push("/a/b"); checkWatchedDirectories(host, watchedRecursiveDirectories, /*recursive*/ true); @@ -2459,7 +2467,8 @@ namespace ts.projectSystem { }); - it("Failed lookup locations are uses parent most node_modules directory", () => { + it("Failed lookup locations uses parent most node_modules directory", () => { + const root = "/user/username/rootfolder"; const file1: FileOrFolder = { path: "/a/b/src/file1.ts", content: 'import { classc } from "module1"' @@ -2479,9 +2488,11 @@ namespace ts.projectSystem { }; const configFile: FileOrFolder = { path: "/a/b/src/tsconfig.json", - content: JSON.stringify({ files: [file1.path] }) + content: JSON.stringify({ files: ["file1.ts"] }) }; - const files = [file1, module1, module2, module3, configFile, libFile]; + const nonLibFiles = [file1, module1, module2, module3, configFile]; + nonLibFiles.forEach(f => f.path = root + f.path); + const files = nonLibFiles.concat(libFile); const host = createServerHost(files); const projectService = createProjectService(host); projectService.openClientFile(file1.path); @@ -2491,8 +2502,8 @@ namespace ts.projectSystem { checkProjectActualFiles(project, [file1.path, libFile.path, module1.path, module2.path, configFile.path]); checkWatchedFiles(host, [libFile.path, module1.path, module2.path, configFile.path]); checkWatchedDirectories(host, [], /*recursive*/ false); - const watchedRecursiveDirectories = getTypeRootsFromLocation("/a/b/src"); - watchedRecursiveDirectories.push("/a/b/src", "/a/b/node_modules"); + const watchedRecursiveDirectories = getTypeRootsFromLocation(root + "/a/b/src"); + watchedRecursiveDirectories.push(`${root}/a/b/src`, `${root}/a/b/node_modules`); checkWatchedDirectories(host, watchedRecursiveDirectories, /*recursive*/ true); }); }); @@ -4682,7 +4693,6 @@ namespace ts.projectSystem { } const f2Lookups = getLocationsForModuleLookup("f2"); callsTrackingHost.verifyCalledOnEachEntryNTimes(CalledMapsWithSingleArg.fileExists, f2Lookups, 1); - const typeRootLocations = getTypeRootsFromLocation(getDirectoryPath(root.path)); const f2DirLookups = getLocationsForDirectoryLookup(); callsTrackingHost.verifyCalledOnEachEntry(CalledMapsWithSingleArg.directoryExists, f2DirLookups); callsTrackingHost.verifyNoCall(CalledMapsWithSingleArg.getDirectories); @@ -4693,7 +4703,7 @@ namespace ts.projectSystem { verifyImportedDiagnostics(); const f1Lookups = f2Lookups.map(s => s.replace("f2", "f1")); f1Lookups.length = f1Lookups.indexOf(imported.path) + 1; - const f1DirLookups = ["/c/d", "/c", ...typeRootLocations]; + const f1DirLookups = ["/c/d", "/c", ...mapCombinedPathsInAncestor(getDirectoryPath(root.path), nodeModulesAtTypes, returnTrue)]; vertifyF1Lookups(); // setting compiler options discards module resolution cache @@ -4744,13 +4754,12 @@ namespace ts.projectSystem { function getLocationsForDirectoryLookup() { const result = createMap(); - // Type root - typeRootLocations.forEach(location => result.set(location, 1)); forEachAncestorDirectory(getDirectoryPath(root.path), ancestor => { // To resolve modules result.set(ancestor, 2); // for type roots - result.set(combinePaths(ancestor, `node_modules`), 1); + result.set(combinePaths(ancestor, nodeModules), 1); + result.set(combinePaths(ancestor, nodeModulesAtTypes), 1); }); return result; } @@ -4990,15 +4999,20 @@ namespace ts.projectSystem { describe("Verify npm install in directory with tsconfig file works when", () => { function verifyNpmInstall(timeoutDuringPartialInstallation: boolean) { - const app: FileOrFolder = { + const root = "/user/username/rootfolder/otherfolder"; + const getRootedFileOrFolder = (fileOrFolder: FileOrFolder) => { + fileOrFolder.path = root + fileOrFolder.path; + return fileOrFolder; + }; + const app: FileOrFolder = getRootedFileOrFolder({ path: "/a/b/app.ts", content: "import _ from 'lodash';" - }; - const tsconfigJson: FileOrFolder = { + }); + const tsconfigJson: FileOrFolder = getRootedFileOrFolder({ path: "/a/b/tsconfig.json", content: '{ "compilerOptions": { } }' - }; - const packageJson: FileOrFolder = { + }); + const packageJson: FileOrFolder = getRootedFileOrFolder({ path: "/a/b/package.json", content: ` { @@ -5022,7 +5036,7 @@ namespace ts.projectSystem { "license": "ISC" } ` - }; + }); const appFolder = getDirectoryPath(app.path); const projectFiles = [app, libFile, tsconfigJson]; const typeRootDirectories = getTypeRootsFromLocation(getDirectoryPath(tsconfigJson.path)); @@ -5053,16 +5067,16 @@ namespace ts.projectSystem { { "path": "/a/b/node_modules/.staging/symbol-observable-24bcbbff/index.d.ts", "content": "declare const observableSymbol: symbol;\nexport default observableSymbol;\n" }, { "path": "/a/b/node_modules/.staging/symbol-observable-24bcbbff/lib" }, { "path": "/a/b/node_modules/.staging/symbol-observable-24bcbbff/lib/index.js", "content": "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _ponyfill = require('./ponyfill');\n\nvar _ponyfill2 = _interopRequireDefault(_ponyfill);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar root; /* global window */\n\n\nif (typeof self !== 'undefined') {\n root = self;\n} else if (typeof window !== 'undefined') {\n root = window;\n} else if (typeof global !== 'undefined') {\n root = global;\n} else if (typeof module !== 'undefined') {\n root = module;\n} else {\n root = Function('return this')();\n}\n\nvar result = (0, _ponyfill2['default'])(root);\nexports['default'] = result;" }, - ]; + ].map(getRootedFileOrFolder); verifyAfterPartialOrCompleteNpmInstall(2); - filesAndFoldersToAdd.push( + filesAndFoldersToAdd.push(...[ { "path": "/a/b/node_modules/.staging/typescript-8493ea5d/lib" }, { "path": "/a/b/node_modules/.staging/rxjs-22375c61/add/operator" }, { "path": "/a/b/node_modules/.staging/@types/lodash-e56c4fe7/package.json", "content": "{\n \"name\": \"@types/lodash\",\n \"version\": \"4.14.74\",\n \"description\": \"TypeScript definitions for Lo-Dash\",\n \"license\": \"MIT\",\n \"contributors\": [\n {\n \"name\": \"Brian Zengel\",\n \"url\": \"https://github.com/bczengel\"\n },\n {\n \"name\": \"Ilya Mochalov\",\n \"url\": \"https://github.com/chrootsu\"\n },\n {\n \"name\": \"Stepan Mikhaylyuk\",\n \"url\": \"https://github.com/stepancar\"\n },\n {\n \"name\": \"Eric L Anderson\",\n \"url\": \"https://github.com/ericanderson\"\n },\n {\n \"name\": \"AJ Richardson\",\n \"url\": \"https://github.com/aj-r\"\n },\n {\n \"name\": \"Junyoung Clare Jang\",\n \"url\": \"https://github.com/ailrun\"\n }\n ],\n \"main\": \"\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://www.github.com/DefinitelyTyped/DefinitelyTyped.git\"\n },\n \"scripts\": {},\n \"dependencies\": {},\n \"typesPublisherContentHash\": \"12af578ffaf8d86d2df37e591857906a86b983fa9258414326544a0fe6af0de8\",\n \"typeScriptVersion\": \"2.2\"\n}" }, { "path": "/a/b/node_modules/.staging/lodash-b0733faa/index.js", "content": "module.exports = require('./lodash');" }, { "path": "/a/b/node_modules/.staging/typescript-8493ea5d/package.json.3017591594" } - ); + ].map(getRootedFileOrFolder)); // Since we didnt add any supported extension file, there wont be any timeout scheduled verifyAfterPartialOrCompleteNpmInstall(0); @@ -5070,27 +5084,27 @@ namespace ts.projectSystem { filesAndFoldersToAdd.length--; verifyAfterPartialOrCompleteNpmInstall(0); - filesAndFoldersToAdd.push( + filesAndFoldersToAdd.push(...[ { "path": "/a/b/node_modules/.staging/rxjs-22375c61/bundles" }, { "path": "/a/b/node_modules/.staging/rxjs-22375c61/operator" }, { "path": "/a/b/node_modules/.staging/rxjs-22375c61/src/add/observable/dom" }, { "path": "/a/b/node_modules/.staging/@types/lodash-e56c4fe7/index.d.ts", "content": "\n// Stub for lodash\nexport = _;\nexport as namespace _;\ndeclare var _: _.LoDashStatic;\ndeclare namespace _ {\n interface LoDashStatic {\n someProp: string;\n }\n class SomeClass {\n someMethod(): void;\n }\n}" } - ); + ].map(getRootedFileOrFolder)); verifyAfterPartialOrCompleteNpmInstall(2); - filesAndFoldersToAdd.push( + filesAndFoldersToAdd.push(...[ { "path": "/a/b/node_modules/.staging/rxjs-22375c61/src/scheduler" }, { "path": "/a/b/node_modules/.staging/rxjs-22375c61/src/util" }, { "path": "/a/b/node_modules/.staging/rxjs-22375c61/symbol" }, { "path": "/a/b/node_modules/.staging/rxjs-22375c61/testing" }, { "path": "/a/b/node_modules/.staging/rxjs-22375c61/package.json.2252192041", "content": "{\n \"_args\": [\n [\n {\n \"raw\": \"rxjs@^5.4.2\",\n \"scope\": null,\n \"escapedName\": \"rxjs\",\n \"name\": \"rxjs\",\n \"rawSpec\": \"^5.4.2\",\n \"spec\": \">=5.4.2 <6.0.0\",\n \"type\": \"range\"\n },\n \"C:\\\\Users\\\\shkamat\\\\Desktop\\\\app\"\n ]\n ],\n \"_from\": \"rxjs@>=5.4.2 <6.0.0\",\n \"_id\": \"rxjs@5.4.3\",\n \"_inCache\": true,\n \"_location\": \"/rxjs\",\n \"_nodeVersion\": \"7.7.2\",\n \"_npmOperationalInternal\": {\n \"host\": \"s3://npm-registry-packages\",\n \"tmp\": \"tmp/rxjs-5.4.3.tgz_1502407898166_0.6800217325799167\"\n },\n \"_npmUser\": {\n \"name\": \"blesh\",\n \"email\": \"ben@benlesh.com\"\n },\n \"_npmVersion\": \"5.3.0\",\n \"_phantomChildren\": {},\n \"_requested\": {\n \"raw\": \"rxjs@^5.4.2\",\n \"scope\": null,\n \"escapedName\": \"rxjs\",\n \"name\": \"rxjs\",\n \"rawSpec\": \"^5.4.2\",\n \"spec\": \">=5.4.2 <6.0.0\",\n \"type\": \"range\"\n },\n \"_requiredBy\": [\n \"/\"\n ],\n \"_resolved\": \"https://registry.npmjs.org/rxjs/-/rxjs-5.4.3.tgz\",\n \"_shasum\": \"0758cddee6033d68e0fd53676f0f3596ce3d483f\",\n \"_shrinkwrap\": null,\n \"_spec\": \"rxjs@^5.4.2\",\n \"_where\": \"C:\\\\Users\\\\shkamat\\\\Desktop\\\\app\",\n \"author\": {\n \"name\": \"Ben Lesh\",\n \"email\": \"ben@benlesh.com\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/ReactiveX/RxJS/issues\"\n },\n \"config\": {\n \"commitizen\": {\n \"path\": \"cz-conventional-changelog\"\n }\n },\n \"contributors\": [\n {\n \"name\": \"Ben Lesh\",\n \"email\": \"ben@benlesh.com\"\n },\n {\n \"name\": \"Paul Taylor\",\n \"email\": \"paul.e.taylor@me.com\"\n },\n {\n \"name\": \"Jeff Cross\",\n \"email\": \"crossj@google.com\"\n },\n {\n \"name\": \"Matthew Podwysocki\",\n \"email\": \"matthewp@microsoft.com\"\n },\n {\n \"name\": \"OJ Kwon\",\n \"email\": \"kwon.ohjoong@gmail.com\"\n },\n {\n \"name\": \"Andre Staltz\",\n \"email\": \"andre@staltz.com\"\n }\n ],\n \"dependencies\": {\n \"symbol-observable\": \"^1.0.1\"\n },\n \"description\": \"Reactive Extensions for modern JavaScript\",\n \"devDependencies\": {\n \"babel-polyfill\": \"^6.23.0\",\n \"benchmark\": \"^2.1.0\",\n \"benchpress\": \"2.0.0-beta.1\",\n \"chai\": \"^3.5.0\",\n \"color\": \"^0.11.1\",\n \"colors\": \"1.1.2\",\n \"commitizen\": \"^2.8.6\",\n \"coveralls\": \"^2.11.13\",\n \"cz-conventional-changelog\": \"^1.2.0\",\n \"danger\": \"^1.1.0\",\n \"doctoc\": \"^1.0.0\",\n \"escape-string-regexp\": \"^1.0.5 \",\n \"esdoc\": \"^0.4.7\",\n \"eslint\": \"^3.8.0\",\n \"fs-extra\": \"^2.1.2\",\n \"get-folder-size\": \"^1.0.0\",\n \"glob\": \"^7.0.3\",\n \"gm\": \"^1.22.0\",\n \"google-closure-compiler-js\": \"^20170218.0.0\",\n \"gzip-size\": \"^3.0.0\",\n \"http-server\": \"^0.9.0\",\n \"husky\": \"^0.13.3\",\n \"lint-staged\": \"3.2.5\",\n \"lodash\": \"^4.15.0\",\n \"madge\": \"^1.4.3\",\n \"markdown-doctest\": \"^0.9.1\",\n \"minimist\": \"^1.2.0\",\n \"mkdirp\": \"^0.5.1\",\n \"mocha\": \"^3.0.2\",\n \"mocha-in-sauce\": \"0.0.1\",\n \"npm-run-all\": \"^4.0.2\",\n \"npm-scripts-info\": \"^0.3.4\",\n \"nyc\": \"^10.2.0\",\n \"opn-cli\": \"^3.1.0\",\n \"platform\": \"^1.3.1\",\n \"promise\": \"^7.1.1\",\n \"protractor\": \"^3.1.1\",\n \"rollup\": \"0.36.3\",\n \"rollup-plugin-inject\": \"^2.0.0\",\n \"rollup-plugin-node-resolve\": \"^2.0.0\",\n \"rx\": \"latest\",\n \"rxjs\": \"latest\",\n \"shx\": \"^0.2.2\",\n \"sinon\": \"^2.1.0\",\n \"sinon-chai\": \"^2.9.0\",\n \"source-map-support\": \"^0.4.0\",\n \"tslib\": \"^1.5.0\",\n \"tslint\": \"^4.4.2\",\n \"typescript\": \"~2.0.6\",\n \"typings\": \"^2.0.0\",\n \"validate-commit-msg\": \"^2.14.0\",\n \"watch\": \"^1.0.1\",\n \"webpack\": \"^1.13.1\",\n \"xmlhttprequest\": \"1.8.0\"\n },\n \"directories\": {},\n \"dist\": {\n \"integrity\": \"sha512-fSNi+y+P9ss+EZuV0GcIIqPUK07DEaMRUtLJvdcvMyFjc9dizuDjere+A4V7JrLGnm9iCc+nagV/4QdMTkqC4A==\",\n \"shasum\": \"0758cddee6033d68e0fd53676f0f3596ce3d483f\",\n \"tarball\": \"https://registry.npmjs.org/rxjs/-/rxjs-5.4.3.tgz\"\n },\n \"engines\": {\n \"npm\": \">=2.0.0\"\n },\n \"homepage\": \"https://github.com/ReactiveX/RxJS\",\n \"keywords\": [\n \"Rx\",\n \"RxJS\",\n \"ReactiveX\",\n \"ReactiveExtensions\",\n \"Streams\",\n \"Observables\",\n \"Observable\",\n \"Stream\",\n \"ES6\",\n \"ES2015\"\n ],\n \"license\": \"Apache-2.0\",\n \"lint-staged\": {\n \"*.@(js)\": [\n \"eslint --fix\",\n \"git add\"\n ],\n \"*.@(ts)\": [\n \"tslint --fix\",\n \"git add\"\n ]\n },\n \"main\": \"Rx.js\",\n \"maintainers\": [\n {\n \"name\": \"blesh\",\n \"email\": \"ben@benlesh.com\"\n }\n ],\n \"name\": \"rxjs\",\n \"optionalDependencies\": {},\n \"readme\": \"ERROR: No README data found!\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+ssh://git@github.com/ReactiveX/RxJS.git\"\n },\n \"scripts-info\": {\n \"info\": \"List available script\",\n \"build_all\": \"Build all packages (ES6, CJS, UMD) and generate packages\",\n \"build_cjs\": \"Build CJS package with clean up existing build, copy source into dist\",\n \"build_es6\": \"Build ES6 package with clean up existing build, copy source into dist\",\n \"build_closure_core\": \"Minify Global core build using closure compiler\",\n \"build_global\": \"Build Global package, then minify build\",\n \"build_perf\": \"Build CJS & Global build, run macro performance test\",\n \"build_test\": \"Build CJS package & test spec, execute mocha test runner\",\n \"build_cover\": \"Run lint to current code, build CJS & test spec, execute test coverage\",\n \"build_docs\": \"Build ES6 & global package, create documentation using it\",\n \"build_spec\": \"Build test specs\",\n \"check_circular_dependencies\": \"Check codebase has circular dependencies\",\n \"clean_spec\": \"Clean up existing test spec build output\",\n \"clean_dist_cjs\": \"Clean up existing CJS package output\",\n \"clean_dist_es6\": \"Clean up existing ES6 package output\",\n \"clean_dist_global\": \"Clean up existing Global package output\",\n \"commit\": \"Run git commit wizard\",\n \"compile_dist_cjs\": \"Compile codebase into CJS module\",\n \"compile_module_es6\": \"Compile codebase into ES6\",\n \"cover\": \"Execute test coverage\",\n \"lint_perf\": \"Run lint against performance test suite\",\n \"lint_spec\": \"Run lint against test spec\",\n \"lint_src\": \"Run lint against source\",\n \"lint\": \"Run lint against everything\",\n \"perf\": \"Run macro performance benchmark\",\n \"perf_micro\": \"Run micro performance benchmark\",\n \"test_mocha\": \"Execute mocha test runner against existing test spec build\",\n \"test_browser\": \"Execute mocha test runner on browser against existing test spec build\",\n \"test\": \"Clean up existing test spec build, build test spec and execute mocha test runner\",\n \"tests2png\": \"Generate marble diagram image from test spec\",\n \"watch\": \"Watch codebase, trigger compile when source code changes\"\n },\n \"typings\": \"Rx.d.ts\",\n \"version\": \"5.4.3\"\n}\n" } - ); + ].map(getRootedFileOrFolder)); verifyAfterPartialOrCompleteNpmInstall(0); // remove /a/b/node_modules/.staging/rxjs-22375c61/package.json.2252192041 filesAndFoldersToAdd.length--; // and add few more folders/files - filesAndFoldersToAdd.push( + filesAndFoldersToAdd.push(...[ { "path": "/a/b/node_modules/symbol-observable" }, { "path": "/a/b/node_modules/@types" }, { "path": "/a/b/node_modules/@types/lodash" }, @@ -5098,7 +5112,7 @@ namespace ts.projectSystem { { "path": "/a/b/node_modules/rxjs" }, { "path": "/a/b/node_modules/typescript" }, { "path": "/a/b/node_modules/.bin" } - ); + ].map(getRootedFileOrFolder)); // From the type root update verifyAfterPartialOrCompleteNpmInstall(2); @@ -5108,7 +5122,7 @@ namespace ts.projectSystem { .replace(/[\-\.][\d\w][\d\w][\d\w][\d\w][\d\w][\d\w][\d\w][\d\w]/g, ""); }); - const lodashIndexPath = "/a/b/node_modules/@types/lodash/index.d.ts"; + const lodashIndexPath = root + "/a/b/node_modules/@types/lodash/index.d.ts"; projectFiles.push(find(filesAndFoldersToAdd, f => f.path === lodashIndexPath)); // we would now not have failed lookup in the parent of appFolder since lodash is available recursiveWatchedDirectories.length = 1; @@ -5570,27 +5584,32 @@ namespace ts.projectSystem { }); describe("resolution when resolution cache size", () => { - function verifyWithMaxCacheLimit(limitHit: boolean) { + function verifyWithMaxCacheLimit(limitHit: boolean, useSlashRootAsSomeNotRootFolderInUserDirectory: boolean) { + const rootFolder = useSlashRootAsSomeNotRootFolderInUserDirectory ? "/user/username/rootfolder/otherfolder/" : "/"; const file1: FileOrFolder = { - path: "/a/b/project/file1.ts", + path: rootFolder + "a/b/project/file1.ts", content: 'import a from "file2"' }; const file2: FileOrFolder = { - path: "/a/b/node_modules/file2.d.ts", + path: rootFolder + "a/b/node_modules/file2.d.ts", content: "export class a { }" }; const file3: FileOrFolder = { - path: "/a/b/project/file3.ts", + path: rootFolder + "a/b/project/file3.ts", content: "export class c { }" }; const configFile: FileOrFolder = { - path: "/a/b/project/tsconfig.json", + path: rootFolder + "a/b/project/tsconfig.json", content: JSON.stringify({ compilerOptions: { typeRoots: [] } }) }; const projectFiles = [file1, file3, libFile, configFile]; const openFiles = [file1.path]; - const watchedRecursiveDirectories = ["/a/b/project", "/a/b/node_modules", "/a/node_modules", "/node_modules"]; + const watchedRecursiveDirectories = useSlashRootAsSomeNotRootFolderInUserDirectory ? + // Folders of node_modules lookup not in changedRoot + ["a/b/project", "a/b/node_modules", "a/node_modules", "node_modules"].map(v => rootFolder + v) : + // Folder of tsconfig + ["/a/b/project"]; const host = createServerHost(projectFiles); const { session, verifyInitialOpen, verifyProjectsUpdatedInBackgroundEventHandler } = createSession(host); const projectService = session.getProjectService(); @@ -5618,15 +5637,22 @@ namespace ts.projectSystem { projectFiles.push(file2); host.reloadFS(projectFiles); host.runQueuedTimeoutCallbacks(); - watchedRecursiveDirectories.length = 2; + if (useSlashRootAsSomeNotRootFolderInUserDirectory) { + watchedRecursiveDirectories.length = 2; + } + else { + // file2 addition wont be detected + projectFiles.pop(); + assert.isTrue(host.fileExists(file2.path)); + } verifyProject(); - verifyProjectsUpdatedInBackgroundEventHandler([{ + verifyProjectsUpdatedInBackgroundEventHandler(useSlashRootAsSomeNotRootFolderInUserDirectory ? [{ eventName: server.ProjectsUpdatedInBackgroundEvent, data: { openFiles } - }]); + }] : []); function verifyProject() { checkProjectActualFiles(project, map(projectFiles, file => file.path)); @@ -5635,12 +5661,20 @@ namespace ts.projectSystem { } } - it("limit not hit", () => { - verifyWithMaxCacheLimit(/*limitHit*/ false); + it("limit not hit and project is not at root level", () => { + verifyWithMaxCacheLimit(/*limitHit*/ false, /*useSlashRootAsSomeNotRootFolderInUserDirectory*/ true); }); - it("limit hit", () => { - verifyWithMaxCacheLimit(/*limitHit*/ true); + it("limit hit and project is not at root level", () => { + verifyWithMaxCacheLimit(/*limitHit*/ true, /*useSlashRootAsSomeNotRootFolderInUserDirectory*/ true); + }); + + it("limit not hit and project is at root level", () => { + verifyWithMaxCacheLimit(/*limitHit*/ false, /*useSlashRootAsSomeNotRootFolderInUserDirectory*/ false); + }); + + it("limit hit and project is at root level", () => { + verifyWithMaxCacheLimit(/*limitHit*/ true, /*useSlashRootAsSomeNotRootFolderInUserDirectory*/ false); }); }); } From 92d191990adee9cef63f6407ff2e2bd171a3a7a0 Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 17 Oct 2017 04:10:06 +0000 Subject: [PATCH 160/312] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 17048 ++++++++-------- 1 file changed, 8563 insertions(+), 8485 deletions(-) diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl index 79859d9bae2..38946acf472 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,8486 +1,8564 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - oder - erforderlich, z. B. "{0}" oder "{1}".]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - " sein.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()".]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + oder - erforderlich, z. B. "{0}" oder "{1}".]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + " sein.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()".]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 1af25ae9f1d3ee9076af6439444c93ab21b57f69 Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 17 Oct 2017 16:10:05 +0000 Subject: [PATCH 161/312] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 74 ++++++++++++++---- .../diagnosticMessages.generated.json.lcl | 74 ++++++++++++++---- .../diagnosticMessages.generated.json.lcl | 74 ++++++++++++++---- .../diagnosticMessages.generated.json.lcl | 75 ++++++++++++++++--- .../diagnosticMessages.generated.json.lcl | 74 ++++++++++++++---- 5 files changed, 307 insertions(+), 64 deletions(-) diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index 075923ea438..d27b3a500b8 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -801,6 +801,12 @@ + + + + + + @@ -1338,6 +1344,18 @@ + + + + + + + + + + + + @@ -1485,6 +1503,12 @@ + + + + + + @@ -1892,12 +1916,12 @@ - - + + - + @@ -2013,6 +2037,12 @@ + + + + + + @@ -3795,6 +3825,18 @@ + + + + + + + + + + + + @@ -3987,21 +4029,15 @@ - + - - - - + - + - - - - + @@ -7263,6 +7299,12 @@ + + + + + + @@ -7743,6 +7785,12 @@ + + + + + + diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl index 026f10b37be..43073f7cab3 100644 --- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -801,6 +801,12 @@ + + + + + + @@ -1338,6 +1344,18 @@ + + + + + + + + + + + + @@ -1485,6 +1503,12 @@ + + + + + + @@ -1892,12 +1916,12 @@ - - + + - + @@ -2013,6 +2037,12 @@ + + + + + + @@ -3795,6 +3825,18 @@ + + + + + + + + + + + + @@ -3987,21 +4029,15 @@ - + - - - - + - + - - - - + @@ -7263,6 +7299,12 @@ + + + + + + @@ -7743,6 +7785,12 @@ + + + + + + diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index b978802c564..727bf964abf 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -792,6 +792,12 @@ + + + + + + @@ -1329,6 +1335,18 @@ + + + + + + + + + + + + @@ -1476,6 +1494,12 @@ + + + + + + @@ -1883,12 +1907,12 @@ - - + + - + @@ -2004,6 +2028,12 @@ + + + + + + @@ -3786,6 +3816,18 @@ + + + + + + + + + + + + @@ -3978,21 +4020,15 @@ - + - - - - + - + - - - - + @@ -7254,6 +7290,12 @@ + + + + + + @@ -7734,6 +7776,12 @@ + + + + + + diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 3a8512e54b2..4ae9e7d5e56 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -782,6 +782,12 @@ + + + + + + @@ -1313,6 +1319,18 @@ + + + + + + + + + + + + @@ -1460,6 +1478,12 @@ + + + + + + @@ -1867,10 +1891,13 @@ - - + + + + + @@ -1982,6 +2009,12 @@ + + + + + + @@ -3758,6 +3791,18 @@ + + + + + + + + + + + + @@ -3950,21 +3995,15 @@ - + - - - - + - + - - - - + @@ -7217,6 +7256,12 @@ + + + + + + @@ -7697,6 +7742,12 @@ + + + + + + diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index aac4d18cd67..b0e6c4b3495 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -791,6 +791,12 @@ + + + + + + @@ -1328,6 +1334,18 @@ + + + + + + + + + + + + @@ -1475,6 +1493,12 @@ + + + + + + @@ -1882,12 +1906,12 @@ - - + + - + @@ -2003,6 +2027,12 @@ + + + + + + @@ -3785,6 +3815,18 @@ + + + + + + + + + + + + @@ -3977,21 +4019,15 @@ - + - - - - + - + - - - - + @@ -7253,6 +7289,12 @@ + + + + + + @@ -7733,6 +7775,12 @@ + + + + + + From abb3f58db29e4b9889f4fcc784f5ebf9d35f5263 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Fri, 13 Oct 2017 17:14:56 -0700 Subject: [PATCH 162/312] Add support for JSX fragment syntax --- src/compiler/binder.ts | 3 ++ src/compiler/checker.ts | 73 ++++++++++++++++++---------- src/compiler/diagnosticMessages.json | 8 +++ src/compiler/emitter.ts | 40 ++++++++++----- src/compiler/factory.ts | 53 ++++++++++++++++++-- src/compiler/parser.ts | 69 +++++++++++++++++++++----- src/compiler/scanner.ts | 5 ++ src/compiler/transformers/jsx.ts | 26 ++++++++++ src/compiler/types.ts | 27 +++++++++- src/compiler/utilities.ts | 18 ++++++- src/compiler/visitor.ts | 12 +++++ tests/cases/compiler/jsxFragment.tsx | 4 ++ 12 files changed, 282 insertions(+), 56 deletions(-) create mode 100644 tests/cases/compiler/jsxFragment.tsx diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 35a62a644d8..ce02d461ed5 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -3296,6 +3296,9 @@ namespace ts { case SyntaxKind.JsxOpeningElement: case SyntaxKind.JsxText: case SyntaxKind.JsxClosingElement: + case SyntaxKind.JsxFragment: + case SyntaxKind.JsxOpeningFragment: + case SyntaxKind.JsxClosingFragment: case SyntaxKind.JsxAttribute: case SyntaxKind.JsxAttributes: case SyntaxKind.JsxSpreadAttribute: diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 69a46ed6cb2..8a0e369789d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13467,32 +13467,37 @@ namespace ts { function getContextualTypeForJsxExpression(node: JsxExpression): Type { // JSX expression can appear in two position : JSX Element's children or JSX attribute - const jsxAttributes = isJsxAttributeLike(node.parent) ? + const jsxAttributes: JsxAttributes = isJsxAttributeLike(node.parent) ? node.parent.parent : - node.parent.openingElement.attributes; // node.parent is JsxElement + isJsxElement(node.parent) ? + node.parent.openingElement.attributes : + undefined; // node.parent is JsxFragment with no attributes - // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type - // which is a type of the parameter of the signature we are trying out. - // If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName - const attributesType = getContextualType(jsxAttributes); + if (jsxAttributes) { + // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type + // which is a type of the parameter of the signature we are trying out. + // If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName + const attributesType = getContextualType(jsxAttributes); - if (!attributesType || isTypeAny(attributesType)) { - return undefined; - } + if (!attributesType || isTypeAny(attributesType)) { + return undefined; + } - if (isJsxAttribute(node.parent)) { - // JSX expression is in JSX attribute - return getTypeOfPropertyOfContextualType(attributesType, node.parent.name.escapedText); - } - else if (node.parent.kind === SyntaxKind.JsxElement) { - // JSX expression is in children of JSX Element, we will look for an "children" atttribute (we get the name from JSX.ElementAttributesProperty) - const jsxChildrenPropertyName = getJsxElementChildrenPropertyname(); - return jsxChildrenPropertyName && jsxChildrenPropertyName !== "" ? getTypeOfPropertyOfContextualType(attributesType, jsxChildrenPropertyName) : anyType; - } - else { - // JSX expression is in JSX spread attribute - return attributesType; + if (isJsxAttribute(node.parent)) { + // JSX expression is in JSX attribute + return getTypeOfPropertyOfContextualType(attributesType, node.parent.name.escapedText); + } + else if (node.parent.kind === SyntaxKind.JsxElement) { + // JSX expression is in children of JSX Element, we will look for an "children" atttribute (we get the name from JSX.ElementAttributesProperty) + const jsxChildrenPropertyName = getJsxElementChildrenPropertyname(); + return jsxChildrenPropertyName && jsxChildrenPropertyName !== "" ? getTypeOfPropertyOfContextualType(attributesType, jsxChildrenPropertyName) : anyType; + } + else { + // JSX expression is in JSX spread attribute + return attributesType; + } } + return anyType; // don't check children of a fragment } function getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute) { @@ -14049,13 +14054,13 @@ namespace ts { } function checkJsxSelfClosingElement(node: JsxSelfClosingElement): Type { - checkJsxOpeningLikeElement(node); + checkJsxOpeningLikeElementOrOpeningFragment(node); return getJsxGlobalElementType() || anyType; } function checkJsxElement(node: JsxElement): Type { // Check attributes - checkJsxOpeningLikeElement(node.openingElement); + checkJsxOpeningLikeElementOrOpeningFragment(node.openingElement); // Perform resolution on the closing tag so that rename/go to definition/etc work if (isJsxIntrinsicIdentifier(node.closingElement.tagName)) { @@ -14068,6 +14073,11 @@ namespace ts { return getJsxGlobalElementType() || anyType; } + function checkJsxFragment(node: JsxFragment): Type { + checkJsxOpeningLikeElementOrOpeningFragment(node.openingFragment); + return getJsxGlobalElementType() || anyType; + } + /** * Returns true iff the JSX element name would be a valid JS identifier, ignoring restrictions about keywords not being identifiers */ @@ -14731,14 +14741,19 @@ namespace ts { } } - function checkJsxOpeningLikeElement(node: JsxOpeningLikeElement) { - checkGrammarJsxElement(node); + function checkJsxOpeningLikeElementOrOpeningFragment(node: JsxOpeningLikeElement | JsxOpeningFragment) { + const isNodeOpeningLikeElement = isJsxOpeningLikeElement(node); + + if (isNodeOpeningLikeElement) { + checkGrammarJsxElement(node); + } checkJsxPreconditions(node); // The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import. // And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error. const reactRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined; const reactNamespace = getJsxNamespace(); - const reactSym = resolveName(node.tagName, reactNamespace, SymbolFlags.Value, reactRefErr, reactNamespace, /*isUse*/ true); + const reactLocation = isNodeOpeningLikeElement ? (node).tagName : node; + const reactSym = resolveName(reactLocation, reactNamespace, SymbolFlags.Value, reactRefErr, reactNamespace, /*isUse*/ true); if (reactSym) { // Mark local symbol as referenced here because it might not have been marked // if jsx emit was not react as there wont be error being emitted @@ -14750,7 +14765,9 @@ namespace ts { } } - checkJsxAttributesAssignableToTagNameAttributes(node); + if (isNodeOpeningLikeElement) { + checkJsxAttributesAssignableToTagNameAttributes(node); + } } /** @@ -18518,6 +18535,8 @@ namespace ts { return checkJsxElement(node); case SyntaxKind.JsxSelfClosingElement: return checkJsxSelfClosingElement(node); + case SyntaxKind.JsxFragment: + return checkJsxFragment(node); case SyntaxKind.JsxAttributes: return checkJsxAttributes(node, checkMode); case SyntaxKind.JsxOpeningElement: diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 8cd5088049c..68cc5a7309e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3607,6 +3607,14 @@ "category": "Error", "code": 17013 }, + "JSX fragment has no corresponding closing tag.": { + "category": "Error", + "code": 17014 + }, + "Expected corresponding JSX fragment closing tag.": { + "category": "Error", + "code": 17015 + }, "Circularity detected while resolving configuration: {0}": { "category": "Error", diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 9ce220e723f..ced57157b26 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -699,9 +699,11 @@ namespace ts { case SyntaxKind.JsxText: return emitJsxText(node); case SyntaxKind.JsxOpeningElement: - return emitJsxOpeningElement(node); + case SyntaxKind.JsxOpeningFragment: + return emitJsxOpeningElementOrFragment(node); case SyntaxKind.JsxClosingElement: - return emitJsxClosingElement(node); + case SyntaxKind.JsxClosingFragment: + return emitJsxClosingElementOrFragment(node); case SyntaxKind.JsxAttribute: return emitJsxAttribute(node); case SyntaxKind.JsxAttributes: @@ -836,6 +838,8 @@ namespace ts { return emitJsxElement(node); case SyntaxKind.JsxSelfClosingElement: return emitJsxSelfClosingElement(node); + case SyntaxKind.JsxFragment: + return emitJsxFragment(node); // Transformation nodes case SyntaxKind.PartiallyEmittedExpression: @@ -2060,7 +2064,7 @@ namespace ts { function emitJsxElement(node: JsxElement) { emit(node.openingElement); - emitList(node, node.children, ListFormat.JsxElementChildren); + emitList(node, node.children, ListFormat.JsxElementOrFragmentChildren); emit(node.closingElement); } @@ -2075,14 +2079,24 @@ namespace ts { write("/>"); } - function emitJsxOpeningElement(node: JsxOpeningElement) { + function emitJsxFragment(node: JsxFragment) { + emit(node.openingFragment); + emitList(node, node.children, ListFormat.JsxElementOrFragmentChildren); + emit(node.closingFragment); + } + + function emitJsxOpeningElementOrFragment(node: JsxOpeningElement | JsxOpeningFragment) { write("<"); - emitJsxTagName(node.tagName); - writeIfAny(node.attributes.properties, " "); - // We are checking here so we won't re-enter the emitting pipeline and emit extra sourcemap - if (node.attributes.properties && node.attributes.properties.length > 0) { - emit(node.attributes); + + if (isJsxOpeningElement(node)) { + emitJsxTagName(node.tagName); + writeIfAny(node.attributes.properties, " "); + // We are checking here so we won't re-enter the emitting pipeline and emit extra sourcemap + if (node.attributes.properties && node.attributes.properties.length > 0) { + emit(node.attributes); + } } + write(">"); } @@ -2090,9 +2104,11 @@ namespace ts { writer.writeLiteral(getTextOfNode(node, /*includeTrivia*/ true)); } - function emitJsxClosingElement(node: JsxClosingElement) { + function emitJsxClosingElementOrFragment(node: JsxClosingElement | JsxClosingFragment) { write(""); } @@ -3176,7 +3192,7 @@ namespace ts { EnumMembers = CommaDelimited | Indented | MultiLine, CaseBlockClauses = Indented | MultiLine, NamedImportsOrExportsElements = CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | SingleLine | SpaceBetweenBraces, - JsxElementChildren = SingleLine | NoInterveningComments, + JsxElementOrFragmentChildren = SingleLine | NoInterveningComments, JsxElementAttributes = SingleLine | SpaceBetweenSiblings | NoInterveningComments, CaseOrDefaultClauseStatements = Indented | MultiLine | NoTrailingNewLine | OptionalIfEmpty, HeritageClauseTypes = CommaDelimited | SpaceBetweenSiblings | SingleLine, diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 65c1c92f366..8d66608c226 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -2115,6 +2115,22 @@ namespace ts { : node; } + export function createJsxFragment(openingFragment: JsxOpeningFragment, children: ReadonlyArray, closingFragment: JsxClosingFragment) { + const node = createSynthesizedNode(SyntaxKind.JsxFragment); + node.openingFragment = openingFragment; + node.children = createNodeArray(children); + node.closingFragment = closingFragment; + return node; + } + + export function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: ReadonlyArray, closingFragment: JsxClosingFragment) { + return node.openingFragment !== openingFragment + || node.children !== children + || node.closingFragment !== closingFragment + ? updateNode(createJsxFragment(openingFragment, children, closingFragment), node) + : node; + } + export function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression) { const node = createSynthesizedNode(SyntaxKind.JsxAttribute); node.name = name; @@ -2951,7 +2967,7 @@ namespace ts { ); } - function createReactNamespace(reactNamespace: string, parent: JsxOpeningLikeElement) { + function createReactNamespace(reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment) { // To ensure the emit resolver can properly resolve the namespace, we need to // treat this identifier as if it were a source tree node by clearing the `Synthesized` // flag and setting a parent node. @@ -2963,7 +2979,7 @@ namespace ts { return react; } - function createJsxFactoryExpressionFromEntityName(jsxFactory: EntityName, parent: JsxOpeningLikeElement): Expression { + function createJsxFactoryExpressionFromEntityName(jsxFactory: EntityName, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression { if (isQualifiedName(jsxFactory)) { const left = createJsxFactoryExpressionFromEntityName(jsxFactory.left, parent); const right = createIdentifier(idText(jsxFactory.right)); @@ -2975,7 +2991,7 @@ namespace ts { } } - function createJsxFactoryExpression(jsxFactoryEntity: EntityName, reactNamespace: string, parent: JsxOpeningLikeElement): Expression { + function createJsxFactoryExpression(jsxFactoryEntity: EntityName, reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression { return jsxFactoryEntity ? createJsxFactoryExpressionFromEntityName(jsxFactoryEntity, parent) : createPropertyAccess( @@ -3016,6 +3032,37 @@ namespace ts { ); } + export function createExpressionForJsxFragment(jsxFactoryEntity: EntityName, reactNamespace: string, children: Expression[], parentElement: JsxOpeningFragment, location: TextRange): LeftHandSideExpression { + const tagName = createPropertyAccess( + createReactNamespace(reactNamespace, parentElement), + "Fragment" + ); + + const argumentsList = [tagName]; + argumentsList.push(createNull()); + + if (children && children.length > 0) { + if (children.length > 1) { + for (const child of children) { + child.startsOnNewLine = true; + argumentsList.push(child); + } + } + else { + argumentsList.push(children[0]); + } + } + + return setTextRange( + createCall( + createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement), + /*typeArguments*/ undefined, + argumentsList + ), + location + ); + } + // Helpers export function getHelperName(name: string) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index e2bae71e6bf..28329791045 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -377,6 +377,10 @@ namespace ts { return visitNode(cbNode, (node).openingElement) || visitNodes(cbNode, cbNodes, (node).children) || visitNode(cbNode, (node).closingElement); + case SyntaxKind.JsxFragment: + return visitNode(cbNode, (node).openingFragment) || + visitNodes(cbNode, cbNodes, (node).children) || + visitNode(cbNode, (node).closingFragment); case SyntaxKind.JsxSelfClosingElement: case SyntaxKind.JsxOpeningElement: return visitNode(cbNode, (node).tagName) || @@ -1423,6 +1427,11 @@ namespace ts { return tokenIsIdentifierOrKeyword(token()); } + function nextTokenIsIdentifierOrKeywordOrGreaterThan() { + nextToken(); + return tokenIsIdentifierOrKeywordOrGreaterThan(token()); + } + function isHeritageClauseExtendsOrImplementsKeyword(): boolean { if (token() === SyntaxKind.ImplementsKeyword || token() === SyntaxKind.ExtendsKeyword) { @@ -3802,9 +3811,9 @@ namespace ts { node.operand = parseLeftHandSideExpressionOrHigher(); return finishNode(node); } - else if (sourceFile.languageVariant === LanguageVariant.JSX && token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeyword)) { + else if (sourceFile.languageVariant === LanguageVariant.JSX && token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) { // JSXElement is part of primaryExpression - return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true); + return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true); } const expression = parseLeftHandSideExpressionOrHigher(); @@ -3959,14 +3968,14 @@ namespace ts { } - function parseJsxElementOrSelfClosingElement(inExpressionContext: boolean): JsxElement | JsxSelfClosingElement { - const opening = parseJsxOpeningOrSelfClosingElement(inExpressionContext); - let result: JsxElement | JsxSelfClosingElement; + function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext: boolean): JsxElement | JsxSelfClosingElement | JsxFragment { + const opening = parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext); + let result: JsxElement | JsxSelfClosingElement | JsxFragment; if (opening.kind === SyntaxKind.JsxOpeningElement) { const node = createNode(SyntaxKind.JsxElement, opening.pos); node.openingElement = opening; - node.children = parseJsxChildren(node.openingElement.tagName); + node.children = parseJsxChildren(node.openingElement); node.closingElement = parseJsxClosingElement(inExpressionContext); if (!tagNamesAreEquivalent(node.openingElement.tagName, node.closingElement.tagName)) { @@ -3975,6 +3984,15 @@ namespace ts { result = finishNode(node); } + else if (opening.kind === SyntaxKind.JsxOpeningFragment) { + const node = createNode(SyntaxKind.JsxFragment, opening.pos); + node.openingFragment = opening; + + node.children = parseJsxChildren(node.openingFragment); + node.closingFragment = parseJsxClosingFragment(inExpressionContext); + + result = finishNode(node); + } else { Debug.assert(opening.kind === SyntaxKind.JsxSelfClosingElement); // Nothing else to do for self-closing elements @@ -3989,7 +4007,7 @@ namespace ts { // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios // of one sort or another. if (inExpressionContext && token() === SyntaxKind.LessThanToken) { - const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true)); + const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true)); if (invalidElement) { parseErrorAtCurrentToken(Diagnostics.JSX_expressions_must_have_one_parent_element); const badNode = createNode(SyntaxKind.BinaryExpression, result.pos); @@ -4020,12 +4038,12 @@ namespace ts { case SyntaxKind.OpenBraceToken: return parseJsxExpression(/*inExpressionContext*/ false); case SyntaxKind.LessThanToken: - return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ false); + return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ false); } Debug.fail("Unknown JSX child kind " + token()); } - function parseJsxChildren(openingTagName: LeftHandSideExpression): NodeArray { + function parseJsxChildren(openingTag: JsxOpeningElement | JsxOpeningFragment): NodeArray { const list = []; const listPos = getNodePos(); const saveParsingContext = parsingContext; @@ -4040,7 +4058,13 @@ namespace ts { else if (token() === SyntaxKind.EndOfFileToken) { // If we hit EOF, issue the error at the tag that lacks the closing element // rather than at the end of the file (which is useless) - parseErrorAtPosition(openingTagName.pos, openingTagName.end - openingTagName.pos, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, openingTagName)); + if (isJsxOpeningElement(openingTag)) { + const openingTagName = openingTag.tagName; + parseErrorAtPosition(openingTagName.pos, openingTagName.end - openingTagName.pos, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, openingTagName)); + } + else { + parseErrorAtPosition(openingTag.pos, openingTag.end - openingTag.pos, Diagnostics.JSX_fragment_has_no_corresponding_closing_tag); + } break; } else if (token() === SyntaxKind.ConflictMarkerTrivia) { @@ -4063,11 +4087,17 @@ namespace ts { return finishNode(jsxAttributes); } - function parseJsxOpeningOrSelfClosingElement(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement { + function parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement | JsxOpeningFragment { const fullStart = scanner.getStartPos(); parseExpected(SyntaxKind.LessThanToken); + if (token() === SyntaxKind.GreaterThanToken) { + parseExpected(SyntaxKind.GreaterThanToken); + const node: JsxOpeningFragment = createNode(SyntaxKind.JsxOpeningFragment, fullStart); + return finishNode(node); + } + const tagName = parseJsxElementName(); const attributes = parseJsxAttributes(); @@ -4179,6 +4209,23 @@ namespace ts { return finishNode(node); } + function parseJsxClosingFragment(inExpressionContext: boolean): JsxClosingFragment { + const node = createNode(SyntaxKind.JsxClosingFragment); + parseExpected(SyntaxKind.LessThanSlashToken); + if (tokenIsIdentifierOrKeyword(token())) { + const unexpectedTagName = parseJsxElementName(); + parseErrorAtPosition(unexpectedTagName.pos, unexpectedTagName.end - unexpectedTagName.pos, Diagnostics.Expected_corresponding_JSX_fragment_closing_tag); + } + if (inExpressionContext) { + parseExpected(SyntaxKind.GreaterThanToken); + } + else { + parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false); + scanJsxText(); + } + return finishNode(node); + } + function parseTypeAssertion(): TypeAssertion { const node = createNode(SyntaxKind.TypeAssertionExpression); parseExpected(SyntaxKind.LessThanToken); diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index b19a1466328..67d83f262c8 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -11,6 +11,11 @@ namespace ts { return token >= SyntaxKind.Identifier; } + /* @internal */ + export function tokenIsIdentifierOrKeywordOrGreaterThan(token: SyntaxKind): boolean { + return token === SyntaxKind.GreaterThanToken || token >= SyntaxKind.Identifier; + } + export interface Scanner { getStartPos(): number; getToken(): SyntaxKind; diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index bbe05afe878..2be6cdef0bc 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -41,6 +41,9 @@ namespace ts { case SyntaxKind.JsxSelfClosingElement: return visitJsxSelfClosingElement(node, /*isChild*/ false); + case SyntaxKind.JsxFragment: + return visitJsxFragment(node, /*isChild*/ false); + case SyntaxKind.JsxExpression: return visitJsxExpression(node); @@ -63,6 +66,9 @@ namespace ts { case SyntaxKind.JsxSelfClosingElement: return visitJsxSelfClosingElement(node, /*isChild*/ true); + case SyntaxKind.JsxFragment: + return visitJsxFragment(node, /*isChild*/ true); + default: Debug.failBadSyntaxKind(node); return undefined; @@ -77,6 +83,10 @@ namespace ts { return visitJsxOpeningLikeElement(node, /*children*/ undefined, isChild, /*location*/ node); } + function visitJsxFragment(node: JsxFragment, isChild: boolean) { + return visitJsxOpeningFragment(node.openingFragment, node.children, isChild, /*location*/ node); + } + function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: ReadonlyArray, isChild: boolean, location: TextRange) { const tagName = getTagName(node); let objectProperties: Expression; @@ -126,6 +136,22 @@ namespace ts { return element; } + function visitJsxOpeningFragment(node: JsxOpeningFragment, children: ReadonlyArray, isChild: boolean, location: TextRange) { + const element = createExpressionForJsxFragment( + context.getEmitResolver().getJsxFactoryEntity(), + compilerOptions.reactNamespace, + mapDefined(children, transformJsxChildToExpression), + node, + location + ); + + if (isChild) { + startOnNewLine(element); + } + + return element; + } + function transformJsxSpreadAttributeToExpression(node: JsxSpreadAttribute) { return visitNode(node.expression, visitor, isExpression); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 42e8292b13b..27cba8ef777 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -328,6 +328,9 @@ namespace ts { JsxSelfClosingElement, JsxOpeningElement, JsxClosingElement, + JsxFragment, + JsxOpeningFragment, + JsxClosingFragment, JsxAttribute, JsxAttributes, JsxSpreadAttribute, @@ -1618,7 +1621,7 @@ namespace ts { closingElement: JsxClosingElement; } - /// Either the opening tag in a ... pair, or the lone in a self-closing form + /// Either the opening tag in a ... pair, the opening tag in a <>... pair, or the lone in a self-closing form export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement; export type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute; @@ -1644,6 +1647,26 @@ namespace ts { attributes: JsxAttributes; } + /// A JSX expression of the form <>... + export interface JsxFragment extends PrimaryExpression { + kind: SyntaxKind.JsxFragment; + openingFragment: JsxOpeningFragment; + children: NodeArray; + closingFragment: JsxClosingFragment; + } + + /// The opening element of a <>... JsxFragment + export interface JsxOpeningFragment extends Expression { + kind: SyntaxKind.JsxOpeningFragment; + parent?: JsxFragment; + } + + /// The closing element of a <>... JsxFragment + export interface JsxClosingFragment extends Expression { + kind: SyntaxKind.JsxClosingFragment; + parent?: JsxFragment; + } + export interface JsxAttribute extends ObjectLiteralElement { kind: SyntaxKind.JsxAttribute; parent?: JsxAttributes; @@ -1677,7 +1700,7 @@ namespace ts { parent?: JsxElement; } - export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement; + export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment; export interface Statement extends Node { _statementBrand: any; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index c4d3de453ba..bfb9e488c92 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1251,6 +1251,7 @@ namespace ts { case SyntaxKind.OmittedExpression: case SyntaxKind.JsxElement: case SyntaxKind.JsxSelfClosingElement: + case SyntaxKind.JsxFragment: case SyntaxKind.YieldExpression: case SyntaxKind.AwaitExpression: case SyntaxKind.MetaProperty: @@ -2136,6 +2137,7 @@ namespace ts { case SyntaxKind.ClassExpression: case SyntaxKind.JsxElement: case SyntaxKind.JsxSelfClosingElement: + case SyntaxKind.JsxFragment: case SyntaxKind.RegularExpressionLiteral: case SyntaxKind.NoSubstitutionTemplateLiteral: case SyntaxKind.TemplateExpression: @@ -4760,6 +4762,18 @@ namespace ts { return node.kind === SyntaxKind.JsxClosingElement; } + export function isJsxFragment(node: Node): node is JsxFragment { + return node.kind === SyntaxKind.JsxFragment; + } + + export function isJsxOpeningFragment(node: Node): node is JsxOpeningFragment { + return node.kind === SyntaxKind.JsxOpeningFragment; + } + + export function isJsxClosingFragment(node: Node): node is JsxClosingFragment { + return node.kind === SyntaxKind.JsxClosingFragment; + } + export function isJsxAttribute(node: Node): node is JsxAttribute { return node.kind === SyntaxKind.JsxAttribute; } @@ -5285,6 +5299,7 @@ namespace ts { case SyntaxKind.CallExpression: case SyntaxKind.JsxElement: case SyntaxKind.JsxSelfClosingElement: + case SyntaxKind.JsxFragment: case SyntaxKind.TaggedTemplateExpression: case SyntaxKind.ArrayLiteralExpression: case SyntaxKind.ParenthesizedExpression: @@ -5606,7 +5621,8 @@ namespace ts { return kind === SyntaxKind.JsxElement || kind === SyntaxKind.JsxExpression || kind === SyntaxKind.JsxSelfClosingElement - || kind === SyntaxKind.JsxText; + || kind === SyntaxKind.JsxText + || kind === SyntaxKind.JsxFragment; } /* @internal */ diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 7d46630e227..0428d2d2d2e 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -819,6 +819,12 @@ namespace ts { return updateJsxClosingElement(node, visitNode((node).tagName, visitor, isJsxTagNameExpression)); + case SyntaxKind.JsxFragment: + return updateJsxFragment(node, + visitNode((node).openingFragment, visitor, isJsxOpeningFragment), + nodesVisitor((node).children, visitor, isJsxChild), + visitNode((node).closingFragment, visitor, isJsxClosingFragment)); + case SyntaxKind.JsxAttribute: return updateJsxAttribute(node, visitNode((node).name, visitor, isIdentifier), @@ -1334,6 +1340,12 @@ namespace ts { result = reduceNode((node).closingElement, cbNode, result); break; + case SyntaxKind.JsxFragment: + result = reduceNode((node).openingFragment, cbNode, result); + result = reduceLeft((node).children, cbNode, result); + result = reduceNode((node).closingFragment, cbNode, result); + break; + case SyntaxKind.JsxSelfClosingElement: case SyntaxKind.JsxOpeningElement: result = reduceNode((node).tagName, cbNode, result); diff --git a/tests/cases/compiler/jsxFragment.tsx b/tests/cases/compiler/jsxFragment.tsx new file mode 100644 index 00000000000..82e093327be --- /dev/null +++ b/tests/cases/compiler/jsxFragment.tsx @@ -0,0 +1,4 @@ +//@jsx: react + +declare var React: any; +
; \ No newline at end of file From 269d37a2e6c1e41a002fa5c0f18e23654b73cbfc Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Mon, 16 Oct 2017 16:51:39 -0700 Subject: [PATCH 163/312] Update tests --- tests/cases/compiler/jsxFragment.tsx | 4 -- .../jsx/checkJsxChildrenProperty14.tsx | 48 +++++++++++++++++++ .../conformance/jsx/tsxFragmentErrors.tsx | 14 ++++++ .../jsx/tsxFragmentPreserveEmit.tsx | 17 +++++++ .../conformance/jsx/tsxFragmentReactEmit.tsx | 17 +++++++ 5 files changed, 96 insertions(+), 4 deletions(-) delete mode 100644 tests/cases/compiler/jsxFragment.tsx create mode 100644 tests/cases/conformance/jsx/checkJsxChildrenProperty14.tsx create mode 100644 tests/cases/conformance/jsx/tsxFragmentErrors.tsx create mode 100644 tests/cases/conformance/jsx/tsxFragmentPreserveEmit.tsx create mode 100644 tests/cases/conformance/jsx/tsxFragmentReactEmit.tsx diff --git a/tests/cases/compiler/jsxFragment.tsx b/tests/cases/compiler/jsxFragment.tsx deleted file mode 100644 index 82e093327be..00000000000 --- a/tests/cases/compiler/jsxFragment.tsx +++ /dev/null @@ -1,4 +0,0 @@ -//@jsx: react - -declare var React: any; -
; \ No newline at end of file diff --git a/tests/cases/conformance/jsx/checkJsxChildrenProperty14.tsx b/tests/cases/conformance/jsx/checkJsxChildrenProperty14.tsx new file mode 100644 index 00000000000..65dfc720003 --- /dev/null +++ b/tests/cases/conformance/jsx/checkJsxChildrenProperty14.tsx @@ -0,0 +1,48 @@ +// @filename: file.tsx +// @jsx: preserve +// @noLib: true +// @skipLibCheck: true +// @libFiles: react.d.ts,lib.d.ts + +import React = require('react'); + +interface Prop { + a: number, + b: string, + children: JSX.Element | JSX.Element[]; +} + +class Button extends React.Component { + render() { + return (
My Button
) + } +} + +function AnotherButton(p: any) { + return

Just Another Button

; +} + +function Comp(p: Prop) { + return
{p.b}
; +} + +// OK +let k1 = <>