mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into configFileDiag
This commit is contained in:
@@ -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
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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
|
||||
},
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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!`);
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
@@ -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
@@ -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]),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
`
|
||||
});
|
||||
|
||||
+11
-7
@@ -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
Reference in New Issue
Block a user