Merge branch 'master' into configFileDiag

This commit is contained in:
Sheetal Nandi
2017-10-10 18:30:59 -07:00
124 changed files with 826 additions and 323 deletions
+12 -1
View File
@@ -276,4 +276,15 @@ Francois Wouts <f@codonut.com>
Jan Melcher <jan.melcher@aeb.com> Jan Melcher <mail@jan-melcher.de>
Matt Mitchell <mmitche@microsoft.com>
Maxwell Paul Brickner <mbrickn@users.noreply.github.com>
Tycho Grouwstra <tychogrouwstra@gmail.com>
Tycho Grouwstra <tychogrouwstra@gmail.com>
Adrian Leonhard <adrianleonhard@gmail.com>
Alex Chugaev <achugaev93@gmail.com>
Henry Mercer <henry.mercer@me.com>
Ivan Enderlin <ivan.enderlin@hoa-project.net>
Joe Calzaretta <jcalz@mit.edu>
Magnus Kulke <mkulke@gmail.com>
Stas Vilchik <stas.vilchik@sonarsource.com>
Taras Mankovski <tarasm@gmail.com>
Thomas den Hollander <ThomasdenH@users.noreply.github.com>
Vakhurin Sergey <igelbox@gmail.com>
Zeeshan Ahmed <ziishaned@gmail.com>
+11
View File
@@ -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
+9
View File
@@ -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;
+2 -2
View File
@@ -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));
}
}
}
-15
View File
@@ -356,21 +356,6 @@ namespace ts {
return array;
}
export function removeWhere<T>(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<T>(array: T[], f: (x: T, i: number, array: T[]) => boolean): void {
let outIndex = 0;
for (let i = 0; i < array.length; i++) {
+3 -3
View File
@@ -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
},
@@ -3661,7 +3661,7 @@
"category": "Message",
"code": 90013
},
"Change {0} to {1}.": {
"Change '{0}' to '{1}'.": {
"category": "Message",
"code": 90014
},
+8 -2
View File
@@ -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() {
+5 -5
View File
@@ -322,6 +322,9 @@ namespace ts {
if (hasChangedCompilerOptions) {
newLine = getNewLineCharacter(compilerOptions, system);
if (program && changesAffectModuleResolution(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;
+1 -1
View File
@@ -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;
}
+37 -13
View File
@@ -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 });
+2 -2
View File
@@ -1,14 +1,14 @@
/// <reference path="./host.ts" />
/// <reference path="./worker.ts" />
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;
}
+42 -18
View File
@@ -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!`);
}
}
+1 -1
View File
@@ -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";
+3
View File
@@ -842,6 +842,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());
+24 -18
View File
@@ -233,9 +233,9 @@ namespace ts.server {
this.realpath = path => host.realpath(path);
}
this.languageService = createLanguageService(this, this.documentRegistry);
// Use the current directory as resolution root only if the project created using current directory string
this.resolutionCache = createResolutionCache(this, currentDirectory && this.currentDirectory);
this.languageService = createLanguageService(this, this.documentRegistry);
if (!languageServiceEnabled) {
this.disableLanguageService();
}
@@ -498,25 +498,23 @@ 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()) {
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.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;
this.resolutionCache.clear();
@@ -535,6 +533,15 @@ namespace ts.server {
this.languageService = undefined;
}
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 && !this.isRoot(info)) {
info.detachFromProject(this);
}
}
isClosed() {
return this.rootFiles === undefined;
}
@@ -735,7 +742,6 @@ namespace ts.server {
*/
updateGraph(): boolean {
this.resolutionCache.startRecordingFilesWithChangedResolutions();
this.hasInvalidatedResolution = this.resolutionCache.createHasInvalidatedResolution();
let hasChanges = this.updateGraphWorker();
@@ -795,9 +801,10 @@ 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();
this.resolutionCache.startCachingPerDirectoryResolution();
this.program = this.languageService.getProgram();
this.resolutionCache.finishCachingPerDirectoryResolution();
@@ -1320,8 +1327,6 @@ namespace ts.server {
}
close() {
super.close();
if (this.configFileWatcher) {
this.configFileWatcher.close();
this.configFileWatcher = undefined;
@@ -1330,6 +1335,7 @@ namespace ts.server {
this.stopWatchingWildCards();
this.projectErrors = undefined;
this.configFileSpecs = undefined;
super.close();
}
addOpenRef() {
@@ -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()
@@ -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]),
+5
View File
@@ -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:
@@ -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);
}
}
}
+1
View File
@@ -7145,6 +7145,7 @@ declare namespace ts.server {
getExternalFiles(): SortedReadonlyArray<string>;
getSourceFile(path: Path): SourceFile;
close(): void;
private detachScriptInfoIfNotRoot(uncheckedFilename);
isClosed(): boolean;
hasRoots(): boolean;
getRootFiles(): NormalizedPath[];
@@ -0,0 +1,5 @@
//// [castFunctionExpressionShouldBeParenthesized.ts]
(function a() { } as any)().foo()
//// [castFunctionExpressionShouldBeParenthesized.js]
(function a() { }().foo());
@@ -0,0 +1,4 @@
=== tests/cases/compiler/castFunctionExpressionShouldBeParenthesized.ts ===
(function a() { } as any)().foo()
>a : Symbol(a, Decl(castFunctionExpressionShouldBeParenthesized.ts, 0, 1))
@@ -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
@@ -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.
@@ -0,0 +1 @@
(function a() { } as any)().foo()
@@ -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;
}
@@ -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
`
});
@@ -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 };
}`
});
@@ -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
`
});
@@ -3,4 +3,7 @@
//// interface I {}
//// [|/* */ class /* */ C /* */ extends /* */ I|]{}
verify.rangeAfterCodeFix("/* */ class /* */ C /* */ implements /* */ I");
verify.codeFix({
description: "Change 'extends' to 'implements'.",
newRangeContent: "/* */ class /* */ C /* */ implements /* */ I",
});
@@ -5,4 +5,8 @@
//// [|abstract class A extends I1 implements I2|] { }
verify.rangeAfterCodeFix("abstract class A implements I1, I2");
verify.codeFix({
description: "Change 'extends' to 'implements'.",
// TODO: GH#18794
newRangeContent: "abstract class A implements I1 , I2",
});
@@ -3,4 +3,7 @@
////interface I<X> { x: X}
////[|class C<T extends string , U> extends I<T>|]{}
verify.rangeAfterCodeFix("class C<T extends string , U> implements I<T>");
verify.codeFix({
description: "Change 'extends' to 'implements'.",
newRangeContent: "class C<T extends string , U> implements I<T>",
});
@@ -10,4 +10,8 @@
//// @sealed
//// [|class A extends I1 implements I2 { }|]
verify.rangeAfterCodeFix("class A implements I1, I2 { }");
verify.codeFix({
description: "Change 'extends' to 'implements'.",
// TODO: GH#18794
newRangeContent: "class A implements I1 , I2 { }",
});
@@ -1,4 +1,7 @@
/// <reference path='fourslash.ts' />
//// var x: [|?|] = 12;
verify.rangeAfterCodeFix("any");
verify.codeFix({
description: "Change '?' to 'any'.",
newRangeContent: "any",
});
@@ -2,4 +2,10 @@
/// <reference path='fourslash.ts' />
//// 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",
});
@@ -2,4 +2,10 @@
/// <reference path='fourslash.ts' />
//// 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",
});
@@ -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",
});
@@ -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",
});
@@ -2,4 +2,9 @@
/// <reference path='fourslash.ts' />
//// 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",
});
@@ -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",
});
@@ -1,4 +1,7 @@
/// <reference path='fourslash.ts' />
//// var f: { [K in keyof number]: [|*|] };
verify.rangeAfterCodeFix("any");
verify.codeFix({
description: "Change '*' to 'any'.",
newRangeContent: "any",
});
@@ -1,3 +1,7 @@
/// <reference path='fourslash.ts' />
//// declare function index(ix: number): [|*|];
verify.rangeAfterCodeFix("any");
verify.codeFix({
description: "Change '*' to 'any'.",
newRangeContent: "any",
});
@@ -1,3 +1,7 @@
/// <reference path='fourslash.ts' />
//// var index: { (ix: number): [|?|] };
verify.rangeAfterCodeFix("any");
verify.codeFix({
description: "Change '?' to 'any'.",
newRangeContent: "any",
});
@@ -1,3 +1,7 @@
/// <reference path='fourslash.ts' />
//// var index: { new (ix: number): [|?|] };
verify.rangeAfterCodeFix("any");
verify.codeFix({
description: "Change '?' to 'any'.",
newRangeContent: "any",
});
@@ -1,4 +1,7 @@
/// <reference path='fourslash.ts' />
//// var x: [|*|] = 12;
verify.rangeAfterCodeFix("any");
verify.codeFix({
description: "Change '*' to 'any'.",
newRangeContent: "any",
});
@@ -1,3 +1,7 @@
/// <reference path='fourslash.ts' />
//// var index = { get p(): [|*|] { return 12 } };
verify.rangeAfterCodeFix("any");
verify.codeFix({
description: "Change '*' to 'any'.",
newRangeContent: "any",
});
@@ -1,3 +1,7 @@
/// <reference path='fourslash.ts' />
//// var index = { set p(x: [|*|]) { } };
verify.rangeAfterCodeFix("any");
verify.codeFix({
description: "Change '*' to 'any'.",
newRangeContent: "any",
});
@@ -1,3 +1,7 @@
/// <reference path='fourslash.ts' />
//// var index: { [s: string]: [|*|] };
verify.rangeAfterCodeFix("any");
verify.codeFix({
description: "Change '*' to 'any'.",
newRangeContent: "any",
});
@@ -3,4 +3,8 @@
//// m(): [|*|] {
//// }
////}
verify.rangeAfterCodeFix("any");
verify.codeFix({
description: "Change '*' to 'any'.",
newRangeContent: "any",
});
@@ -2,4 +2,8 @@
////declare class C {
//// m(): [|*|];
////}
verify.rangeAfterCodeFix("any");
verify.codeFix({
description: "Change '*' to 'any'.",
newRangeContent: "any",
});
@@ -2,4 +2,8 @@
////declare class C {
//// p: [|*|];
////}
verify.rangeAfterCodeFix("any");
verify.codeFix({
description: "Change '*' to 'any'.",
newRangeContent: "any",
});
@@ -2,4 +2,8 @@
////class C {
//// p: [|*|] = 12;
////}
verify.rangeAfterCodeFix("any");
verify.codeFix({
description: "Change '*' to 'any'.",
newRangeContent: "any",
});
@@ -1,4 +1,10 @@
// @strict: true
/// <reference path='fourslash.ts' />
////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",
});
@@ -1,4 +1,7 @@
/// <reference path='fourslash.ts' />
//// var x: [|......number[][]|] = 12;
verify.rangeAfterCodeFix("number[][][][]");
verify.codeFix({
description: "Change '......number[][]' to 'number[][][][]'.",
newRangeContent: "number[][][][]",
});
@@ -1,4 +1,7 @@
/// <reference path='fourslash.ts' />
//// var x: [|Array.<number>|] = 12;
verify.rangeAfterCodeFix("number[]");
verify.codeFix({
description: "Change 'Array.<number>' to 'number[]'.",
newRangeContent: "number[]",
});
@@ -2,4 +2,9 @@
/// <reference path='fourslash.ts' />
//// 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",
});
@@ -2,4 +2,8 @@
/// <reference path='fourslash.ts' />
//// 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",
});
@@ -1,4 +1,7 @@
/// <reference path='fourslash.ts' />
//// var x: [|!number|] = 12;
verify.rangeAfterCodeFix("number");
verify.codeFix({
description: "Change '!number' to 'number'.",
newRangeContent: "number",
});
@@ -1,4 +1,7 @@
/// <reference path='fourslash.ts' />
//// 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",
});
@@ -1,4 +1,7 @@
/// <reference path='fourslash.ts' />
//// var x: [|function(new: number)|] = 12;
verify.rangeAfterCodeFix("new () => number");
verify.codeFix({
description: "Change 'function(new: number)' to 'new () => number'.",
newRangeContent: "new () => number",
});
@@ -1,13 +1,16 @@
/// <reference path='fourslash.ts' />
//// 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
`
});
@@ -1,14 +1,17 @@
/// <reference path='fourslash.ts' />
//// function foo<T>(a: T) {
//// abstract class C<U> {
//// abstract a: T | U;
//// }
//// return C;
//// }
////function foo<T>(a: T) {
//// abstract class C<U> {
//// abstract a: T | U;
//// }
//// return C;
////}
////
//// let B = class extends foo("s")<number> {[| |]}
////let B = class extends foo("s")<number> {[| |]}
verify.rangeAfterCodeFix(`
a: string | number;
`);
verify.codeFix({
description: "Implement inherited abstract class.",
// TODO: GH#18795
newRangeContent: `a: string | number;\r
`
});
@@ -1,14 +1,17 @@
/// <reference path='fourslash.ts' />
//// function foo<T>(a: T) {
//// abstract class C<U> {
//// abstract a: T | U;
//// }
//// return C;
//// }
////function foo<T>(a: T) {
//// abstract class C<U> {
//// abstract a: T | U;
//// }
//// return C;
////}
////
//// class B extends foo("s")<number> {[| |]}
////class B extends foo("s")<number> {[| |]}
verify.rangeAfterCodeFix(`
a: string | number;
`);
verify.codeFix({
description: "Implement inherited abstract class.",
// TODO: GH#18795
newRangeContent: `a: string | number;\r
`
});
@@ -1,31 +1,34 @@
/// <reference path='fourslash.ts' />
//// 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
`
});
@@ -1,24 +1,27 @@
/// <reference path='fourslash.ts' />
//// 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
`
});
@@ -1,13 +1,16 @@
/// <reference path='fourslash.ts' />
//// 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
`
});
@@ -1,12 +1,16 @@
/// <reference path='fourslash.ts' />
//// abstract class A<T> {
////abstract class A<T> {
//// abstract f(x: T): T;
//// }
////}
////
//// class C extends A<number> {[| |]}
////class C extends A<number> {[| |]}
verify.rangeAfterCodeFix(`f(x: number): number{
throw new Error("Method not implemented.");
}
`);
verify.codeFix({
description: "Implement inherited abstract class.",
// TODO: GH#18795
newRangeContent: `f(x: number): number {\r
throw new Error("Method not implemented.");\r
}\r
`
});
@@ -1,12 +1,16 @@
/// <reference path='fourslash.ts' />
//// abstract class A<T> {
////abstract class A<T> {
//// abstract f(x: T): T;
//// }
////}
////
//// class C<U> extends A<U> {[| |]}
////class C<U> extends A<U> {[| |]}
verify.rangeAfterCodeFix(`f(x: U): U{
throw new Error("Method not implemented.");
}
`);
verify.codeFix({
description: "Implement inherited abstract class.",
// TODO: GH#18795
newRangeContent: `f(x: U): U {\r
throw new Error("Method not implemented.");\r
}\r
`
});
@@ -1,15 +1,18 @@
/// <reference path='fourslash.ts' />
//// 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
`
});
@@ -0,0 +1,32 @@
///<reference path="fourslash.ts" />
////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();
@@ -0,0 +1,19 @@
/// <reference path='fourslash.ts' />
// @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');
@@ -0,0 +1,19 @@
/// <reference path='fourslash.ts' />
// @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');
@@ -1,11 +1,12 @@
/// <reference path='fourslash.ts' />
// @noUnusedLocals: true
////[| class greeter {
////class greeter {
//// private function1() {
//// }
////} |]
////}
verify.rangeAfterCodeFix(`
class greeter {
}`);
verify.codeFix({
description: `Remove declaration for: 'function1'.`,
newFileContent: "class greeter {\n}",
});
@@ -1,15 +1,17 @@
/// <reference path='fourslash.ts' />
// @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() {
}
}`);
}`,
});
@@ -1,11 +1,12 @@
/// <reference path='fourslash.ts' />
// @noUnusedLocals: true
////[|class greeter {
////class greeter {
//// private function1 = function() {
//// }
////} |]
////}
verify.rangeAfterCodeFix(`
class greeter {
}`);
verify.codeFix({
description: `Remove declaration for: 'function1'.`,
newFileContent: "class greeter {\n}",
});
@@ -8,5 +8,9 @@
//// } |]
////}
verify.rangeAfterCodeFix(`public function2(){
}`);
verify.codeFix({
description: `Remove declaration for: 'function1'.`,
newRangeContent: `public function2(){
}
`,
});
@@ -1,8 +1,11 @@
/// <reference path='fourslash.ts' />
// @noUnusedLocals: true
//// [|class C {
//// private ["string"] (){}
//// }|]
////class C {
//// private ["string"] (){}
////}
verify.rangeAfterCodeFix("class C { }");
verify.codeFix({
description: `Remove declaration for: '"string"'.`,
newFileContent: "class C {\n}",
});
@@ -1,8 +1,11 @@
/// <reference path='fourslash.ts' />
// @noUnusedLocals: true
//// [|class C {
//// private "string" (){}
//// }|]
////class C {
//// private "string" (){}
////}
verify.rangeAfterCodeFix("class C { }");
verify.codeFix({
description: `Remove declaration for: '"string"'.`,
newFileContent: "class C {\n}",
});
@@ -1,13 +1,13 @@
/// <reference path='fourslash.ts' />
// @noUnusedLocals: true
//// [|namespace A {
////namespace A {
//// namespace B {
//// }
//// }|]
verify.rangeAfterCodeFix(`
namespace A {
}
`);
//// }
////}
verify.codeFix({
description: "Remove declaration for: 'B'.",
newFileContent: `namespace A {
}`,
});
@@ -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);
verify.codeFix({
description: "Remove declaration for: 'p1'.",
index: 0,
newRangeContent: "constructor(public p2: boolean, public p3: any, p5)",
});
@@ -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);
verify.codeFix({
description: "Prefix 'p1' with an underscore.",
index: 1,
newRangeContent: "constructor(private _p1: string, public p2: boolean, public p3: any, p5)",
});
@@ -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);
verify.codeFix({
description: "Remove declaration for: 'p2'.",
index: 0,
newRangeContent: "constructor(public p1: string, public p3: any, p5)",
});
@@ -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);
verify.codeFix({
description: "Remove declaration for: 'p3'.",
index: 0,
newRangeContent: "constructor(public p1: string, public p2: boolean, p5)",
});
@@ -5,4 +5,8 @@
//// [|constructor(private readonly p2: boolean, p5)|] { p5; }
//// }
verify.rangeAfterCodeFix("constructor(p5)", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0);
verify.codeFix({
description: "Remove declaration for: 'p2'.",
index: 0,
newRangeContent: "constructor(p5)",
});
@@ -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()",
});
@@ -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)",
});
@@ -5,4 +5,8 @@
//// use(x);
////}
verify.rangeAfterCodeFix("greeter(x)", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0);
verify.codeFix({
description: "Remove declaration for: 'y'.",
index: 0,
newRangeContent: "greeter(x)",
});
@@ -5,4 +5,8 @@
//// y++;
////}
verify.rangeAfterCodeFix("greeter(y)", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0);
verify.codeFix({
description: "Remove declaration for: 'x'.",
index: 0,
newRangeContent: "greeter(y)",
});
@@ -5,4 +5,8 @@
//// use(x, z);
////}
verify.rangeAfterCodeFix("function greeter(x,z)", /*includeWhiteSpace*/ false, /*errorCode*/ undefined, /*index*/ 0);
verify.codeFix({
description: "Remove declaration for: 'y'.",
index: 0,
newRangeContent: "function greeter(x,z) ",
});
@@ -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 () => {}",
});
@@ -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) => {}",
});
@@ -1,11 +1,14 @@
/// <reference path='fourslash.ts' />
// @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";
}`);
}`,
});
@@ -4,4 +4,7 @@
////[|class greeter<T> |] {
////}
verify.rangeAfterCodeFix("class greeter");
verify.codeFix({
description: "Remove declaration for: 'T'.",
newRangeContent: "class greeter ",
});
@@ -5,4 +5,7 @@
//// public a: X;
////}
verify.rangeAfterCodeFix("class greeter<X>");
verify.codeFix({
description: "Remove declaration for: 'Y'.",
newRangeContent: "class greeter<X> ",
});
@@ -6,4 +6,7 @@
//// public b: Z;
////}
verify.rangeAfterCodeFix("class greeter<X, Z>");
verify.codeFix({
description: "Remove declaration for: 'Y'.",
newRangeContent: "class greeter<X, Z> ",
});
@@ -3,4 +3,7 @@
// @noUnusedLocals: true
//// [|function f1<T>() {}|]
verify.rangeAfterCodeFix("function f1() {}");
verify.codeFix({
description: "Remove declaration for: 'T'.",
newRangeContent: "function f1() {}",
});
@@ -3,4 +3,7 @@
// @noUnusedLocals: true
//// [|function f1<X, Y>(a: X) {a}|]
verify.rangeAfterCodeFix("function f1<X>(a: X) {a}");
verify.codeFix({
description: "Remove declaration for: 'Y'.",
newRangeContent: "function f1<X>(a: X) {a}",
});
@@ -3,4 +3,7 @@
// @noUnusedLocals: true
//// [|function f1<X, Y, Z>(a: X) {a;var b:Z;b}|]
verify.rangeAfterCodeFix("function f1<X, Z>(a: X) {a;var b:Z;b}");
verify.codeFix({
description: "Remove declaration for: 'Y'.",
newRangeContent: "function f1<X, Z>(a: X) {a;var b:Z;b}",
});
@@ -4,4 +4,7 @@
// @noUnusedParameters: true
//// [|interface I<T> {}|]
verify.rangeAfterCodeFix("interface I {}");
verify.codeFix({
description: "Remove declaration for: 'T'.",
newRangeContent: "interface I {}",
});
@@ -6,4 +6,7 @@
//// [|return <T>(x:number) => {x}|]
//// }
verify.rangeAfterCodeFix("return (x:number) => {x}");
verify.codeFix({
description: "Remove declaration for: 'T'.",
newRangeContent: "return(x:number) => {x}",
});
@@ -6,4 +6,7 @@
//// [|new <T, U>(a: T): void;|]
//// }
verify.rangeAfterCodeFix("new <T>(a: T): void;");
verify.codeFix({
description: "Remove declaration for: 'U'.",
newRangeContent: "new <T>(a: T): void;",
});

Some files were not shown because too many files have changed in this diff Show More