mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into incrementalBuildInfo
This commit is contained in:
@@ -5,8 +5,6 @@ node_js:
|
||||
- '10'
|
||||
- '8'
|
||||
|
||||
sudo: false
|
||||
|
||||
env:
|
||||
- workerCount=3 timeout=600000
|
||||
|
||||
|
||||
+1
-50
@@ -12,10 +12,9 @@ const merge2 = require("merge2");
|
||||
const mkdirp = require("mkdirp");
|
||||
const { src, dest, task, parallel, series, watch } = require("gulp");
|
||||
const { append, transform } = require("gulp-insert");
|
||||
const { browserify } = require("./scripts/build/browserify");
|
||||
const { prependFile } = require("./scripts/build/prepend");
|
||||
const { exec, readJson, needsUpdate, getDiffTool, getDirSize, rm } = require("./scripts/build/utils");
|
||||
const { runConsoleTests, cleanTestDirs, writeTestConfigFile, refBaseline, localBaseline, refRwcBaseline, localRwcBaseline } = require("./scripts/build/tests");
|
||||
const { runConsoleTests, refBaseline, localBaseline, refRwcBaseline, localRwcBaseline } = require("./scripts/build/tests");
|
||||
const { buildProject, cleanProject, watchProject } = require("./scripts/build/projects");
|
||||
const cmdLineOptions = require("./scripts/build/options");
|
||||
|
||||
@@ -432,44 +431,6 @@ task("runtests-parallel").flags = {
|
||||
" --built": "Compile using the built version of the compiler.",
|
||||
};
|
||||
|
||||
const buildWebTestServer = () => buildProject("tests/webTestServer.tsconfig.json");
|
||||
const cleanWebTestServer = () => cleanProject("tests/webTestServer.tsconfig.json");
|
||||
cleanTasks.push(cleanWebTestServer);
|
||||
|
||||
const browserifyTests = () => src(["built/local/run.js"], { base: "built/local" })
|
||||
.pipe(newer("built/local/bundle.js"))
|
||||
.pipe(sourcemaps.init({ loadMaps: true }))
|
||||
.pipe(browserify())
|
||||
.pipe(rename("bundle.js"))
|
||||
.pipe(sourcemaps.write(".", /**@type {*}*/({ includeContent: false, destPath: "built/local" })))
|
||||
.pipe(dest("built/local"));
|
||||
|
||||
const runtestsBrowser = async () => {
|
||||
await cleanTestDirs();
|
||||
const { tests, runners, light } = cmdLineOptions;
|
||||
const testConfigFile = "test.config";
|
||||
await del([testConfigFile]);
|
||||
if (tests || runners || light) {
|
||||
writeTestConfigFile(tests, runners, light);
|
||||
}
|
||||
const args = ["tests/webTestServer.js"];
|
||||
if (cmdLineOptions.browser) {
|
||||
args.push(cmdLineOptions.browser);
|
||||
}
|
||||
if (tests) {
|
||||
args.push(JSON.stringify(tests));
|
||||
}
|
||||
await exec(process.execPath, args);
|
||||
};
|
||||
|
||||
task("runtests-browser", series(preBuild, parallel(buildTests, buildServices, buildLssl, buildWebTestServer), browserifyTests, runtestsBrowser));
|
||||
task("runtests-browser").description = "Runs the tests using the built run.js file like 'gulp runtests'.";
|
||||
task("runtests-browser").flags = {
|
||||
"-t --tests=<regex>": "pattern for tests to run",
|
||||
"-b --browser=<browser>": "Either 'IE' or 'chrome'",
|
||||
" --built": "Compile using the built version of the compiler.",
|
||||
};
|
||||
|
||||
task("diff", () => exec(getDiffTool(), [refBaseline, localBaseline], { ignoreExitCode: true }));
|
||||
task("diff").description = "Diffs the compiler baselines using the diff tool specified by the 'DIFF' environment variable";
|
||||
|
||||
@@ -503,16 +464,6 @@ cleanTasks.push(cleanWebHost);
|
||||
task("clean-webhost", cleanWebHost);
|
||||
task("clean-webhost").description = "Cleans the outputs of the tsc web host";
|
||||
|
||||
// TODO(rbuckton): Determine if 'perftsc' is still in use.
|
||||
const buildPerfTsc = () => buildProject("tests/perftsc.tsconfig.json");
|
||||
task("perftsc", series(lkgPreBuild, buildPerfTsc));
|
||||
task("perftsc").description = "Builds augmented version of the compiler for perf tests";
|
||||
|
||||
const cleanPerfTsc = () => cleanProject("tests/perftsc.tsconfig.json");
|
||||
cleanTasks.push(cleanPerfTsc);
|
||||
task("clean-perftsc", cleanPerfTsc);
|
||||
task("clean-perftsc").description = "Cleans the outputs of the perftsc project";
|
||||
|
||||
const buildLoggedIO = async () => {
|
||||
mkdirp.sync("built/local/temp");
|
||||
await exec(process.execPath, ["lib/tsc", "--types", "--target", "es5", "--lib", "es5", "--outdir", "built/local/temp", "src/harness/loggedIO.ts"]);
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// simple script to optionally elide source-map-support (or other optional modules) when running browserify.
|
||||
|
||||
var stream = require("stream"),
|
||||
Transform = stream.Transform,
|
||||
resolve = require("browser-resolve");
|
||||
|
||||
var requirePattern = /require\s*\(\s*['"](source-map-support)['"]\s*\)/;
|
||||
module.exports = function (file) {
|
||||
return new Transform({
|
||||
transform: function (data, encoding, cb) {
|
||||
var text = encoding === "buffer" ? data.toString("utf8") : data;
|
||||
this.push(new Buffer(text.replace(requirePattern, function (originalText, moduleName) {
|
||||
try {
|
||||
resolve.sync(moduleName, { filename: file });
|
||||
return originalText;
|
||||
}
|
||||
catch (e) {
|
||||
return "(function () { throw new Error(\"module '" + moduleName + "' not found.\"); })()";
|
||||
}
|
||||
}), "utf8"));
|
||||
cb();
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -1,33 +0,0 @@
|
||||
// @ts-check
|
||||
const browserify = require("browserify");
|
||||
const Vinyl = require("vinyl");
|
||||
const { Transform } = require("stream");
|
||||
const { streamFromFile } = require("./utils");
|
||||
const { replaceContents } = require("./sourcemaps");
|
||||
|
||||
/**
|
||||
* @param {import("browserify").Options} [opts]
|
||||
*/
|
||||
function browserifyFile(opts) {
|
||||
return new Transform({
|
||||
objectMode: true,
|
||||
/**
|
||||
* @param {string | Buffer | Vinyl} input
|
||||
*/
|
||||
transform(input, _, cb) {
|
||||
if (typeof input === "string" || Buffer.isBuffer(input)) return cb(new Error("Only Vinyl files are supported."));
|
||||
try {
|
||||
browserify(Object.assign({}, opts, { debug: !!input.sourceMap, basedir: input.base }))
|
||||
.add(streamFromFile(input), { file: input.path, basedir: input.base })
|
||||
.bundle((err, contents) => {
|
||||
if (err) return cb(err);
|
||||
cb(null, replaceContents(input, contents));
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
cb(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.browserify = browserifyFile;
|
||||
@@ -1,102 +1,4 @@
|
||||
// @ts-check
|
||||
/// <reference path="../types/ambient.d.ts" />
|
||||
|
||||
const path = require("path");
|
||||
const convertMap = require("convert-source-map");
|
||||
const applySourceMap = require("vinyl-sourcemaps-apply");
|
||||
const through2 = require("through2");
|
||||
|
||||
/**
|
||||
* @param {import("vinyl")} input
|
||||
* @param {string | Buffer} contents
|
||||
* @param {string | RawSourceMap} [sourceMap]
|
||||
*/
|
||||
function replaceContents(input, contents, sourceMap) {
|
||||
const output = input.clone();
|
||||
output.contents = typeof contents === "string" ? Buffer.from(contents, "utf8") : contents;
|
||||
if (input.sourceMap) {
|
||||
output.sourceMap = typeof input.sourceMap === "string" ? /**@type {RawSourceMap}*/(JSON.parse(input.sourceMap)) : input.sourceMap;
|
||||
if (typeof sourceMap === "string") {
|
||||
sourceMap = /** @type {RawSourceMap} */(JSON.parse(sourceMap));
|
||||
}
|
||||
else if (sourceMap === undefined) {
|
||||
const stringContents = typeof contents === "string" ? contents : contents.toString("utf8");
|
||||
const newSourceMapConverter = convertMap.fromSource(stringContents);
|
||||
if (newSourceMapConverter) {
|
||||
sourceMap = /** @type {RawSourceMap} */(newSourceMapConverter.toObject());
|
||||
output.contents = new Buffer(convertMap.removeMapFileComments(stringContents), "utf8");
|
||||
}
|
||||
}
|
||||
if (sourceMap) {
|
||||
const cwd = input.cwd || process.cwd();
|
||||
const base = input.base || cwd;
|
||||
const sourceRoot = output.sourceMap.sourceRoot;
|
||||
makeAbsoluteSourceMap(cwd, base, output.sourceMap);
|
||||
makeAbsoluteSourceMap(cwd, base, /** @type {RawSourceMap} */(sourceMap));
|
||||
applySourceMap(output, sourceMap);
|
||||
makeRelativeSourceMap(cwd, base, sourceRoot, output.sourceMap);
|
||||
}
|
||||
else {
|
||||
output.sourceMap = undefined;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
exports.replaceContents = replaceContents;
|
||||
|
||||
function removeSourceMaps() {
|
||||
return through2.obj((/**@type {import("vinyl")}*/file, _, cb) => {
|
||||
if (file.isBuffer()) {
|
||||
file.contents = Buffer.from(convertMap.removeMapFileComments(file.contents.toString("utf8")), "utf8");
|
||||
if (file.sourceMap) {
|
||||
file.sourceMap = undefined;
|
||||
}
|
||||
}
|
||||
cb(null, file);
|
||||
});
|
||||
}
|
||||
exports.removeSourceMaps = removeSourceMaps;
|
||||
|
||||
/**
|
||||
* @param {string | undefined} cwd
|
||||
* @param {string | undefined} base
|
||||
* @param {RawSourceMap} sourceMap
|
||||
*
|
||||
* @typedef {object} RawSourceMap
|
||||
* @property {string} version
|
||||
* @property {string} file
|
||||
* @property {string} [sourceRoot]
|
||||
* @property {string[]} sources
|
||||
* @property {string[]} [sourcesContent]
|
||||
* @property {string} mappings
|
||||
* @property {string[]} [names]
|
||||
*/
|
||||
function makeAbsoluteSourceMap(cwd = process.cwd(), base = "", sourceMap) {
|
||||
const sourceRoot = sourceMap.sourceRoot || "";
|
||||
const resolvedBase = path.resolve(cwd, base);
|
||||
const resolvedSourceRoot = path.resolve(resolvedBase, sourceRoot);
|
||||
sourceMap.file = path.resolve(resolvedBase, sourceMap.file).replace(/\\/g, "/");
|
||||
sourceMap.sources = sourceMap.sources.map(source => path.resolve(resolvedSourceRoot, source).replace(/\\/g, "/"));
|
||||
sourceMap.sourceRoot = "";
|
||||
}
|
||||
exports.makeAbsoluteSourceMap = makeAbsoluteSourceMap;
|
||||
|
||||
/**
|
||||
* @param {string | undefined} cwd
|
||||
* @param {string | undefined} base
|
||||
* @param {string} sourceRoot
|
||||
* @param {RawSourceMap} sourceMap
|
||||
*/
|
||||
function makeRelativeSourceMap(cwd = process.cwd(), base = "", sourceRoot, sourceMap) {
|
||||
makeAbsoluteSourceMap(cwd, base, sourceMap);
|
||||
const resolvedBase = path.resolve(cwd, base);
|
||||
const resolvedSourceRoot = path.resolve(resolvedBase, sourceRoot);
|
||||
sourceMap.file = path.relative(resolvedBase, sourceMap.file).replace(/\\/g, "/");
|
||||
sourceMap.sources = sourceMap.sources.map(source => path.relative(resolvedSourceRoot, source).replace(/\\/g, "/"));
|
||||
sourceMap.sourceRoot = sourceRoot;
|
||||
}
|
||||
exports.makeRelativeSourceMap = makeRelativeSourceMap;
|
||||
|
||||
/**
|
||||
* @param {string} message
|
||||
* @returns {never}
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
/// <reference path="../src/harness/external/node.d.ts" />
|
||||
/// <reference path="../built/local/typescript.d.ts" />
|
||||
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import * as typescript from "typescript";
|
||||
declare var ts: typeof typescript;
|
||||
|
||||
var tsSourceDir = "../src";
|
||||
var tsBuildDir = "../built/local";
|
||||
var testOutputDir = "../built/benchmark";
|
||||
var sourceFiles = [
|
||||
"compiler/types.ts",
|
||||
"compiler/core.ts",
|
||||
"compiler/sys.ts",
|
||||
"compiler/diagnosticInformationMap.generated.ts",
|
||||
"compiler/scanner.ts",
|
||||
"compiler/binder.ts",
|
||||
"compiler/utilities.ts",
|
||||
"compiler/parser.ts",
|
||||
"compiler/checker.ts",
|
||||
"compiler/declarationEmitter.ts",
|
||||
"compiler/emitter.ts",
|
||||
"compiler/program.ts",
|
||||
"compiler/commandLineParser.ts",
|
||||
"compiler/tsc.ts"];
|
||||
|
||||
// .ts sources for the compiler, used as a test input
|
||||
var rawCompilerSources = "";
|
||||
sourceFiles.forEach(f=> {
|
||||
rawCompilerSources += "\r\n" + fs.readFileSync(path.join(tsSourceDir, f)).toString();
|
||||
});
|
||||
var compilerSources = `var compilerSources = ${JSON.stringify(rawCompilerSources) };`;
|
||||
|
||||
// .js code for the compiler, what we are actually testing
|
||||
var rawCompilerJavaScript = fs.readFileSync(path.join(tsBuildDir, "tsc.js")).toString();
|
||||
rawCompilerJavaScript = rawCompilerJavaScript.replace("ts.executeCommandLine(ts.sys.args);", "");
|
||||
|
||||
// lib.d.ts sources
|
||||
var rawLibSources = fs.readFileSync(path.join(tsBuildDir, "lib.d.ts")).toString();
|
||||
var libSources = `var libSources = ${JSON.stringify(rawLibSources) };`;
|
||||
|
||||
// write test output
|
||||
if (!fs.existsSync(testOutputDir)) {
|
||||
fs.mkdirSync(testOutputDir);
|
||||
}
|
||||
|
||||
// 1. compiler ts sources, used to test
|
||||
fs.writeFileSync(
|
||||
path.join(testOutputDir, "compilerSources.js"),
|
||||
`${ compilerSources } \r\n ${ libSources }`);
|
||||
|
||||
// 2. the compiler js sources + a call the compiler
|
||||
fs.writeFileSync(
|
||||
path.join(testOutputDir, "benchmarktsc.js"),
|
||||
`${ rawCompilerJavaScript }\r\n${ compile.toString() }\r\ncompile(compilerSources, libSources);`);
|
||||
|
||||
// 3. test html file to drive the test
|
||||
fs.writeFileSync(
|
||||
path.join(testOutputDir, "benchmarktsc.html"),
|
||||
`<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
|
||||
<title>Typescript 1.1 Compiler</title>
|
||||
<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
|
||||
</head>
|
||||
<body>
|
||||
<div><span>Status: </span><span id="status">Running</span></div>
|
||||
<div id="main"><span>End-to-End Time: </span><span id="totalTime">N/A</span></div>
|
||||
<script>
|
||||
var startTime = performance.now();
|
||||
</script>
|
||||
<script src="compilerSources.js"></script>
|
||||
<script src="benchmarktsc.js"></script>
|
||||
<script>
|
||||
var endTime = performance.now();
|
||||
document.getElementById("totalTime").innerHTML = parseInt(endTime - startTime, 10);
|
||||
document.getElementById("status").innerHTML = "DONE";
|
||||
</script>
|
||||
</body>
|
||||
</html>`);
|
||||
|
||||
function compile(compilerSources, librarySources) {
|
||||
var program = ts.createProgram(
|
||||
["lib.d.ts", "compiler.ts"],
|
||||
{
|
||||
noResolve: true,
|
||||
out: "compiler.js",
|
||||
removeComments: true,
|
||||
target: ts.ScriptTarget.ES3
|
||||
}, {
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
getSourceFile: (filename, languageVersion) => {
|
||||
var source: string;
|
||||
if (filename === "lib.d.ts") source = librarySources;
|
||||
else if (filename === "compiler.ts") source = compilerSources;
|
||||
else console.error("Unexpected read file request: " + filename);
|
||||
|
||||
return ts.createSourceFile(filename, source, languageVersion);
|
||||
},
|
||||
writeFile: (filename, data, writeByteOrderMark) => {
|
||||
if (filename !== "compiler.js")
|
||||
console.error("Unexpected write file request: " + filename);
|
||||
// console.log(data);
|
||||
},
|
||||
getCurrentDirectory: () => "",
|
||||
getCanonicalFileName: (filename) => filename,
|
||||
useCaseSensitiveFileNames: () => false,
|
||||
getNewLine: () => "\r\n"
|
||||
});
|
||||
|
||||
var emitOutput = program.emit();
|
||||
|
||||
var errors = program.getSyntacticDiagnostics()
|
||||
.concat(program.getSemanticDiagnostics())
|
||||
.concat(program.getGlobalDiagnostics())
|
||||
.concat(emitOutput.diagnostics);
|
||||
|
||||
if (errors.length) {
|
||||
console.error("Unexpected errors.");
|
||||
errors.forEach(e=> console.log(`${e.code}: ${e.messageText}`))
|
||||
}
|
||||
}
|
||||
-125
@@ -1,125 +0,0 @@
|
||||
/// <reference types="node"/>
|
||||
|
||||
import fs = require('fs');
|
||||
import path = require('path');
|
||||
|
||||
interface IOLog {
|
||||
filesRead: {
|
||||
path: string;
|
||||
result: { contents: string; };
|
||||
}[];
|
||||
arguments: string[];
|
||||
}
|
||||
|
||||
module Commands {
|
||||
export function dir(obj: IOLog) {
|
||||
obj.filesRead.filter(f => f.result !== undefined).forEach(f => {
|
||||
console.log(f.path);
|
||||
});
|
||||
}
|
||||
dir['description'] = ': displays a list of files';
|
||||
|
||||
export function find(obj: IOLog, str: string) {
|
||||
obj.filesRead.filter(f => f.result !== undefined).forEach(f => {
|
||||
var lines = f.result.contents.split('\n');
|
||||
var printedHeader = false;
|
||||
lines.forEach(line => {
|
||||
if (line.indexOf(str) >= 0) {
|
||||
if (!printedHeader) {
|
||||
console.log(' === ' + f.path + ' ===');
|
||||
printedHeader = true;
|
||||
}
|
||||
console.log(line);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
find['description'] = ' string: finds text in files';
|
||||
|
||||
export function grab(obj: IOLog, filename: string) {
|
||||
obj.filesRead.filter(f => f.result !== undefined).forEach(f => {
|
||||
if (path.basename(f.path) === filename) {
|
||||
fs.writeFile(filename, f.result.contents);
|
||||
}
|
||||
});
|
||||
}
|
||||
grab['description'] = ' filename.ts: writes out the specified file to disk';
|
||||
|
||||
export function extract(obj: IOLog, outputFolder: string) {
|
||||
var directorySeparator = "/";
|
||||
function directoryExists(path: string): boolean {
|
||||
return fs.existsSync(path) && fs.statSync(path).isDirectory();
|
||||
}
|
||||
function getDirectoryPath(path: string) {
|
||||
return path.substr(0, Math.max(getRootLength(path), path.lastIndexOf(directorySeparator)));
|
||||
}
|
||||
function getRootLength(path: string): number {
|
||||
if (path.charAt(0) === directorySeparator) {
|
||||
if (path.charAt(1) !== directorySeparator) return 1;
|
||||
var p1 = path.indexOf(directorySeparator, 2);
|
||||
if (p1 < 0) return 2;
|
||||
var p2 = path.indexOf(directorySeparator, p1 + 1);
|
||||
if (p2 < 0) return p1 + 1;
|
||||
return p2 + 1;
|
||||
}
|
||||
if (path.charAt(1) === ":") {
|
||||
if (path.charAt(2) === directorySeparator) return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
function ensureDirectoriesExist(directoryPath: string) {
|
||||
if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) {
|
||||
var parentDirectory = getDirectoryPath(directoryPath);
|
||||
ensureDirectoriesExist(parentDirectory);
|
||||
console.log("creating directory: " + directoryPath);
|
||||
fs.mkdirSync(directoryPath);
|
||||
}
|
||||
}
|
||||
function normalizeSlashes(path: string): string {
|
||||
return path.replace(/\\/g, "/");
|
||||
}
|
||||
function transalatePath(outputFolder:string, path: string): string {
|
||||
return normalizeSlashes(outputFolder + directorySeparator + path.replace(":", ""));
|
||||
}
|
||||
function fileExists(path: string): boolean {
|
||||
return fs.existsSync(path);
|
||||
}
|
||||
obj.filesRead.forEach(f => {
|
||||
var filename = transalatePath(outputFolder, f.path);
|
||||
ensureDirectoriesExist(getDirectoryPath(filename));
|
||||
console.log("writing filename: " + filename);
|
||||
fs.writeFileSync(filename, f.result.contents);
|
||||
});
|
||||
|
||||
console.log("Command: tsc ");
|
||||
obj.arguments.forEach(a => {
|
||||
if (getRootLength(a) > 0) {
|
||||
console.log(transalatePath(outputFolder, a));
|
||||
}
|
||||
else {
|
||||
console.log(a);
|
||||
}
|
||||
console.log(" ");
|
||||
});
|
||||
}
|
||||
extract['description'] = ' outputFolder: extract all input files to <outputFolder>';
|
||||
}
|
||||
|
||||
var args = process.argv.slice(2);
|
||||
if (args.length < 2) {
|
||||
console.log('Usage: node ior.js path_to_file.json [command]');
|
||||
console.log('List of commands: ');
|
||||
Object.keys(Commands).forEach(k => console.log(' ' + k + Commands[k]['description']));
|
||||
} else {
|
||||
var cmd: Function = Commands[args[1]];
|
||||
if (cmd === undefined) {
|
||||
console.log('Unknown command ' + args[1]);
|
||||
} else {
|
||||
fs.readFile(args[0], 'utf-8', (err, data) => {
|
||||
if (err) throw err;
|
||||
var json = JSON.parse(data);
|
||||
cmd.apply(undefined, [json].concat(args.slice(2)));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
var tslint = require("tslint");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
|
||||
function getLinterOptions() {
|
||||
return {
|
||||
formatter: "prose",
|
||||
formattersDirectory: undefined,
|
||||
rulesDirectory: "built/local/tslint"
|
||||
};
|
||||
}
|
||||
function getLinterConfiguration() {
|
||||
return tslint.Configuration.loadConfigurationFromPath(path.join(__dirname, "../tslint.json"));
|
||||
}
|
||||
|
||||
function lintFileContents(options, configuration, path, contents) {
|
||||
var ll = new tslint.Linter(options);
|
||||
ll.lint(path, contents, configuration);
|
||||
return ll.getResult();
|
||||
}
|
||||
|
||||
function lintFileAsync(options, configuration, path, cb) {
|
||||
fs.readFile(path, "utf8", function (err, contents) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
var result = lintFileContents(options, configuration, path, contents);
|
||||
cb(undefined, result);
|
||||
});
|
||||
}
|
||||
|
||||
process.on("message", function (data) {
|
||||
switch (data.kind) {
|
||||
case "file":
|
||||
var target = data.name;
|
||||
var lintOptions = getLinterOptions();
|
||||
var lintConfiguration = getLinterConfiguration();
|
||||
lintFileAsync(lintOptions, lintConfiguration, target, function (err, result) {
|
||||
if (err) {
|
||||
process.send({ kind: "error", error: err.toString() });
|
||||
return;
|
||||
}
|
||||
process.send({ kind: "result", failures: result.failureCount, output: result.output });
|
||||
});
|
||||
break;
|
||||
case "close":
|
||||
process.exit(0);
|
||||
break;
|
||||
}
|
||||
});
|
||||
Vendored
-8
@@ -1,13 +1,5 @@
|
||||
import { TaskFunction } from "gulp";
|
||||
|
||||
declare module "gulp-clone" {
|
||||
function Clone(): NodeJS.ReadWriteStream;
|
||||
namespace Clone {
|
||||
export function sink() : NodeJS.ReadWriteStream & {tap: () => NodeJS.ReadWriteStream};
|
||||
}
|
||||
export = Clone;
|
||||
}
|
||||
|
||||
declare module "gulp-insert" {
|
||||
export function append(text: string | Buffer): NodeJS.ReadWriteStream;
|
||||
export function prepend(text: string | Buffer): NodeJS.ReadWriteStream;
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
Vendored
-2856
File diff suppressed because it is too large
Load Diff
-109
@@ -1,109 +0,0 @@
|
||||
import Mocha = require("../../");
|
||||
|
||||
export = common;
|
||||
|
||||
declare function common(suites: Mocha.Suite[], context: Mocha.MochaGlobals, mocha: Mocha): common.CommonFunctions;
|
||||
|
||||
declare namespace common {
|
||||
export interface CommonFunctions {
|
||||
/**
|
||||
* This is only present if flag --delay is passed into Mocha. It triggers
|
||||
* root suite execution.
|
||||
*/
|
||||
runWithSuite(suite: Mocha.Suite): () => void;
|
||||
|
||||
/**
|
||||
* Execute before running tests.
|
||||
*/
|
||||
before(fn?: Mocha.Func | Mocha.AsyncFunc): void;
|
||||
|
||||
/**
|
||||
* Execute before running tests.
|
||||
*/
|
||||
before(name: string, fn?: Mocha.Func | Mocha.AsyncFunc): void;
|
||||
|
||||
/**
|
||||
* Execute after running tests.
|
||||
*/
|
||||
after(fn?: Mocha.Func | Mocha.AsyncFunc): void;
|
||||
|
||||
/**
|
||||
* Execute after running tests.
|
||||
*/
|
||||
after(name: string, fn?: Mocha.Func | Mocha.AsyncFunc): void;
|
||||
|
||||
/**
|
||||
* Execute before each test case.
|
||||
*/
|
||||
beforeEach(fn?: Mocha.Func | Mocha.AsyncFunc): void;
|
||||
|
||||
/**
|
||||
* Execute before each test case.
|
||||
*/
|
||||
beforeEach(name: string, fn?: Mocha.Func | Mocha.AsyncFunc): void;
|
||||
|
||||
/**
|
||||
* Execute after each test case.
|
||||
*/
|
||||
afterEach(fn?: Mocha.Func | Mocha.AsyncFunc): void;
|
||||
|
||||
/**
|
||||
* Execute after each test case.
|
||||
*/
|
||||
afterEach(name: string, fn?: Mocha.Func | Mocha.AsyncFunc): void;
|
||||
|
||||
suite: SuiteFunctions;
|
||||
test: TestFunctions;
|
||||
}
|
||||
|
||||
export interface CreateOptions {
|
||||
/** Title of suite */
|
||||
title: string;
|
||||
|
||||
/** Suite function */
|
||||
fn?: (this: Mocha.Suite) => void;
|
||||
|
||||
/** Is suite pending? */
|
||||
pending?: boolean;
|
||||
|
||||
/** Filepath where this Suite resides */
|
||||
file?: string;
|
||||
|
||||
/** Is suite exclusive? */
|
||||
isOnly?: boolean;
|
||||
}
|
||||
|
||||
export interface SuiteFunctions {
|
||||
/**
|
||||
* Create an exclusive Suite; convenience function
|
||||
*/
|
||||
only(opts: CreateOptions): Mocha.Suite;
|
||||
|
||||
/**
|
||||
* Create a Suite, but skip it; convenience function
|
||||
*/
|
||||
skip(opts: CreateOptions): Mocha.Suite;
|
||||
|
||||
/**
|
||||
* Creates a suite.
|
||||
*/
|
||||
create(opts: CreateOptions): Mocha.Suite;
|
||||
}
|
||||
|
||||
export interface TestFunctions {
|
||||
/**
|
||||
* Exclusive test-case.
|
||||
*/
|
||||
only(mocha: Mocha, test: Mocha.Test): Mocha.Test;
|
||||
|
||||
/**
|
||||
* Pending test case.
|
||||
*/
|
||||
skip(title: string): void;
|
||||
|
||||
/**
|
||||
* Number of retry attempts
|
||||
*/
|
||||
retries(n: number): void;
|
||||
}
|
||||
}
|
||||
Vendored
-17
@@ -1,17 +0,0 @@
|
||||
export = milliseconds;
|
||||
|
||||
/**
|
||||
* Parse the given `str` and return milliseconds.
|
||||
*
|
||||
* @see {@link https://mochajs.org/api/module-milliseconds.html}
|
||||
* @see {@link https://mochajs.org/api/module-milliseconds.html#~parse}
|
||||
*/
|
||||
declare function milliseconds(val: string): number;
|
||||
|
||||
/**
|
||||
* Format for `ms`.
|
||||
*
|
||||
* @see {@link https://mochajs.org/api/module-milliseconds.html}
|
||||
* @see {@link https://mochajs.org/api/module-milliseconds.html#~format}
|
||||
*/
|
||||
declare function milliseconds(val: number): string;
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"name": "@types/mocha",
|
||||
"private": true,
|
||||
"version": "5.2.1"
|
||||
}
|
||||
+242
-107
@@ -228,9 +228,9 @@ namespace ts {
|
||||
isContextSensitive,
|
||||
getFullyQualifiedName,
|
||||
getResolvedSignature: (node, candidatesOutArray, agumentCount) =>
|
||||
getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, /*isForSignatureHelp*/ false),
|
||||
getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, CheckMode.Normal),
|
||||
getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, agumentCount) =>
|
||||
getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, /*isForSignatureHelp*/ true),
|
||||
getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, CheckMode.IsForSignatureHelp),
|
||||
getConstantValue: nodeIn => {
|
||||
const node = getParseTreeNode(nodeIn, canHaveConstantValue);
|
||||
return node ? getConstantValue(node) : undefined;
|
||||
@@ -374,10 +374,10 @@ namespace ts {
|
||||
getLocalTypeParametersOfClassOrInterfaceOrTypeAlias,
|
||||
};
|
||||
|
||||
function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, isForSignatureHelp: boolean): Signature | undefined {
|
||||
function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, checkMode: CheckMode): Signature | undefined {
|
||||
const node = getParseTreeNode(nodeIn, isCallLikeExpression);
|
||||
apparentArgumentCount = argumentCount;
|
||||
const res = node ? getResolvedSignature(node, candidatesOutArray, isForSignatureHelp) : undefined;
|
||||
const res = node ? getResolvedSignature(node, candidatesOutArray, checkMode) : undefined;
|
||||
apparentArgumentCount = undefined;
|
||||
return res;
|
||||
}
|
||||
@@ -688,10 +688,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
const enum CheckMode {
|
||||
Normal = 0, // Normal type checking
|
||||
SkipContextSensitive = 1, // Skip context sensitive function expressions
|
||||
Inferential = 2, // Inferential typing
|
||||
Contextual = 3, // Normal type checking informed by a contextual type, therefore not cacheable
|
||||
Normal = 0, // Normal type checking
|
||||
Contextual = 1 << 0, // Explicitly assigned contextual type, therefore not cacheable
|
||||
Inferential = 1 << 1, // Inferential typing
|
||||
SkipContextSensitive = 1 << 2, // Skip context sensitive function expressions
|
||||
SkipGenericFunctions = 1 << 3, // Skip single signature generic functions
|
||||
IsForSignatureHelp = 1 << 4, // Call resolution for purposes of signature help
|
||||
}
|
||||
|
||||
const enum CallbackCheck {
|
||||
@@ -3981,7 +3983,7 @@ namespace ts {
|
||||
context.flags &= ~NodeBuilderFlags.WriteTypeParametersInQualifiedName; // Avoids potential infinite loop when building for a claimspace with a generic
|
||||
const shouldUseGeneratedName =
|
||||
context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams &&
|
||||
type.symbol.declarations[0] &&
|
||||
type.symbol.declarations && type.symbol.declarations[0] &&
|
||||
isTypeParameterDeclaration(type.symbol.declarations[0]) &&
|
||||
typeParameterShadowsNameInScope(type, context);
|
||||
const name = shouldUseGeneratedName
|
||||
@@ -8373,9 +8375,23 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean): Signature {
|
||||
return getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript));
|
||||
function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean, inferredTypeParameters?: ReadonlyArray<TypeParameter>): Signature {
|
||||
const instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript));
|
||||
if (inferredTypeParameters) {
|
||||
const returnSignature = getSingleCallSignature(getReturnTypeOfSignature(instantiatedSignature));
|
||||
if (returnSignature) {
|
||||
const newReturnSignature = cloneSignature(returnSignature);
|
||||
newReturnSignature.typeParameters = inferredTypeParameters;
|
||||
newReturnSignature.target = returnSignature.target;
|
||||
newReturnSignature.mapper = returnSignature.mapper;
|
||||
const newInstantiatedSignature = cloneSignature(instantiatedSignature);
|
||||
newInstantiatedSignature.resolvedReturnType = getOrCreateTypeFromSignature(newReturnSignature);
|
||||
return newInstantiatedSignature;
|
||||
}
|
||||
}
|
||||
return instantiatedSignature;
|
||||
}
|
||||
|
||||
function getSignatureInstantiationWithoutFillingInTypeArguments(signature: Signature, typeArguments: ReadonlyArray<Type> | undefined): Signature {
|
||||
const instantiations = signature.instantiations || (signature.instantiations = createMap<Signature>());
|
||||
const id = getTypeListId(typeArguments);
|
||||
@@ -8389,6 +8405,7 @@ namespace ts {
|
||||
function createSignatureInstantiation(signature: Signature, typeArguments: ReadonlyArray<Type> | undefined): Signature {
|
||||
return instantiateSignature(signature, createSignatureTypeMapper(signature, typeArguments), /*eraseTypeParameters*/ true);
|
||||
}
|
||||
|
||||
function createSignatureTypeMapper(signature: Signature, typeArguments: ReadonlyArray<Type> | undefined): TypeMapper {
|
||||
return createTypeMapper(signature.typeParameters!, typeArguments);
|
||||
}
|
||||
@@ -8790,7 +8807,7 @@ namespace ts {
|
||||
|
||||
function getTypeReferenceTypeWorker(node: NodeWithTypeArguments, symbol: Symbol, typeArguments: Type[] | undefined): Type | undefined {
|
||||
if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
if (symbol.valueDeclaration && isBinaryExpression(symbol.valueDeclaration.parent)) {
|
||||
if (symbol.valueDeclaration && symbol.valueDeclaration.parent && isBinaryExpression(symbol.valueDeclaration.parent)) {
|
||||
const jsdocType = getJSDocTypeReference(node, symbol, typeArguments);
|
||||
if (jsdocType) {
|
||||
return jsdocType;
|
||||
@@ -20035,27 +20052,36 @@ namespace ts {
|
||||
// Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
|
||||
function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper?: TypeMapper, compareTypes?: TypeComparer): Signature {
|
||||
const context = createInferenceContext(signature.typeParameters!, signature, InferenceFlags.None, compareTypes);
|
||||
const sourceSignature = contextualMapper ? instantiateSignature(contextualSignature, contextualMapper) : contextualSignature;
|
||||
// We clone the contextualMapper to avoid fixing. For example, when the source signature is <T>(x: T) => T[] and
|
||||
// the contextual signature is (...args: A) => B, we want to infer the element type of A's constraint (say 'any')
|
||||
// for T but leave it possible to later infer '[any]' back to A.
|
||||
const restType = getEffectiveRestType(contextualSignature);
|
||||
const mapper = contextualMapper && restType && restType.flags & TypeFlags.TypeParameter ? cloneTypeMapper(contextualMapper) : contextualMapper;
|
||||
const sourceSignature = mapper ? instantiateSignature(contextualSignature, mapper) : contextualSignature;
|
||||
forEachMatchingParameterType(sourceSignature, signature, (source, target) => {
|
||||
// Type parameters from outer context referenced by source type are fixed by instantiation of the source type
|
||||
inferTypes(context.inferences, source, target);
|
||||
});
|
||||
if (!contextualMapper) {
|
||||
inferTypes(context.inferences, getReturnTypeOfSignature(contextualSignature), getReturnTypeOfSignature(signature), InferencePriority.ReturnType);
|
||||
const signaturePredicate = getTypePredicateOfSignature(signature);
|
||||
const contextualPredicate = getTypePredicateOfSignature(sourceSignature);
|
||||
if (signaturePredicate && contextualPredicate && signaturePredicate.kind === contextualPredicate.kind &&
|
||||
(signaturePredicate.kind === TypePredicateKind.This || signaturePredicate.parameterIndex === (contextualPredicate as IdentifierTypePredicate).parameterIndex)) {
|
||||
inferTypes(context.inferences, contextualPredicate.type, signaturePredicate.type, InferencePriority.ReturnType);
|
||||
}
|
||||
}
|
||||
return getSignatureInstantiation(signature, getInferredTypes(context), isInJSFile(contextualSignature.declaration));
|
||||
}
|
||||
|
||||
function inferJsxTypeArguments(node: JsxOpeningLikeElement, signature: Signature, excludeArgument: ReadonlyArray<boolean> | undefined, context: InferenceContext): Type[] {
|
||||
function inferJsxTypeArguments(node: JsxOpeningLikeElement, signature: Signature, checkMode: CheckMode, context: InferenceContext): Type[] {
|
||||
const paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
|
||||
|
||||
const checkAttrType = checkExpressionWithContextualType(node.attributes, paramType, excludeArgument && excludeArgument[0] !== undefined ? identityMapper : context);
|
||||
const checkAttrType = checkExpressionWithContextualType(node.attributes, paramType, context, checkMode);
|
||||
inferTypes(context.inferences, checkAttrType, paramType);
|
||||
|
||||
return getInferredTypes(context);
|
||||
}
|
||||
|
||||
function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: ReadonlyArray<Expression>, excludeArgument: ReadonlyArray<boolean> | undefined, context: InferenceContext): Type[] {
|
||||
function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: ReadonlyArray<Expression>, checkMode: CheckMode, context: InferenceContext): Type[] {
|
||||
// Clear out all the inference results from the last time inferTypeArguments was called on this context
|
||||
for (const inference of context.inferences) {
|
||||
// As an optimization, we don't have to clear (and later recompute) inferred types
|
||||
@@ -20068,7 +20094,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (isJsxOpeningLikeElement(node)) {
|
||||
return inferJsxTypeArguments(node, signature, excludeArgument, context);
|
||||
return inferJsxTypeArguments(node, signature, checkMode, context);
|
||||
}
|
||||
|
||||
// If a contextual type is available, infer from that type to the return type of the call expression. For
|
||||
@@ -20115,10 +20141,7 @@ namespace ts {
|
||||
const arg = args[i];
|
||||
if (arg.kind !== SyntaxKind.OmittedExpression) {
|
||||
const paramType = getTypeAtPosition(signature, i);
|
||||
// For context sensitive arguments we pass the identityMapper, which is a signal to treat all
|
||||
// context sensitive function expressions as wildcards
|
||||
const mapper = excludeArgument && excludeArgument[i] !== undefined ? identityMapper : context;
|
||||
const argType = checkExpressionWithContextualType(arg, paramType, mapper);
|
||||
const argType = checkExpressionWithContextualType(arg, paramType, context, checkMode);
|
||||
inferTypes(context.inferences, argType, paramType);
|
||||
}
|
||||
}
|
||||
@@ -20146,7 +20169,7 @@ namespace ts {
|
||||
// and the argument are ...x forms.
|
||||
return arg.kind === SyntaxKind.SyntheticExpression ?
|
||||
createArrayType((<SyntheticExpression>arg).type) :
|
||||
getArrayifiedType(checkExpressionWithContextualType((<SpreadElement>arg).expression, restType, context));
|
||||
getArrayifiedType(checkExpressionWithContextualType((<SpreadElement>arg).expression, restType, context, CheckMode.Normal));
|
||||
}
|
||||
}
|
||||
const contextualType = getIndexTypeOfType(restType, IndexKind.Number) || anyType;
|
||||
@@ -20154,7 +20177,7 @@ namespace ts {
|
||||
const types = [];
|
||||
let spreadIndex = -1;
|
||||
for (let i = index; i < argCount; i++) {
|
||||
const argType = checkExpressionWithContextualType(args[i], contextualType, context);
|
||||
const argType = checkExpressionWithContextualType(args[i], contextualType, context, CheckMode.Normal);
|
||||
if (spreadIndex < 0 && isSpreadArgument(args[i])) {
|
||||
spreadIndex = i - index;
|
||||
}
|
||||
@@ -20212,14 +20235,13 @@ namespace ts {
|
||||
* @param node a JSX opening-like element we are trying to figure its call signature
|
||||
* @param signature a candidate signature we are trying whether it is a call signature
|
||||
* @param relation a relationship to check parameter and argument type
|
||||
* @param excludeArgument
|
||||
*/
|
||||
function checkApplicableSignatureForJsxOpeningLikeElement(node: JsxOpeningLikeElement, signature: Signature, relation: Map<RelationComparisonResult>, excludeArgument: boolean[] | undefined, reportErrors: boolean) {
|
||||
function checkApplicableSignatureForJsxOpeningLikeElement(node: JsxOpeningLikeElement, signature: Signature, relation: Map<RelationComparisonResult>, checkMode: CheckMode, reportErrors: boolean) {
|
||||
// Stateless function components can have maximum of three arguments: "props", "context", and "updater".
|
||||
// However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props,
|
||||
// can be specified by users through attributes property.
|
||||
const paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
|
||||
const attributesType = checkExpressionWithContextualType(node.attributes, paramType, excludeArgument && excludeArgument[0] ? identityMapper : undefined);
|
||||
const attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*contextualMapper*/ undefined, checkMode);
|
||||
return checkTypeRelatedToAndOptionallyElaborate(attributesType, paramType, relation, reportErrors ? node.tagName : undefined, node.attributes);
|
||||
}
|
||||
|
||||
@@ -20228,10 +20250,10 @@ namespace ts {
|
||||
args: ReadonlyArray<Expression>,
|
||||
signature: Signature,
|
||||
relation: Map<RelationComparisonResult>,
|
||||
excludeArgument: boolean[] | undefined,
|
||||
checkMode: CheckMode,
|
||||
reportErrors: boolean) {
|
||||
if (isJsxOpeningLikeElement(node)) {
|
||||
return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, excludeArgument, reportErrors);
|
||||
return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, checkMode, reportErrors);
|
||||
}
|
||||
const thisType = getThisTypeOfSignature(signature);
|
||||
if (thisType && thisType !== voidType && node.kind !== SyntaxKind.NewExpression) {
|
||||
@@ -20253,11 +20275,11 @@ namespace ts {
|
||||
const arg = args[i];
|
||||
if (arg.kind !== SyntaxKind.OmittedExpression) {
|
||||
const paramType = getTypeAtPosition(signature, i);
|
||||
const argType = checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
|
||||
// If one or more arguments are still excluded (as indicated by a non-null excludeArgument parameter),
|
||||
const argType = checkExpressionWithContextualType(arg, paramType, /*contextualMapper*/ undefined, checkMode);
|
||||
// If one or more arguments are still excluded (as indicated by CheckMode.SkipContextSensitive),
|
||||
// we obtain the regular type of any object literal arguments because we may not have inferred complete
|
||||
// parameter types yet and therefore excess property checks may yield false positives (see #17041).
|
||||
const checkArgType = excludeArgument ? getRegularTypeOfObjectLiteral(argType) : argType;
|
||||
const checkArgType = checkMode & CheckMode.SkipContextSensitive ? getRegularTypeOfObjectLiteral(argType) : argType;
|
||||
if (!checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? arg : undefined, arg, headMessage)) {
|
||||
return false;
|
||||
}
|
||||
@@ -20473,7 +20495,7 @@ namespace ts {
|
||||
return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, belowArgCount === -Infinity ? aboveArgCount : belowArgCount, argCount);
|
||||
}
|
||||
|
||||
function resolveCall(node: CallLikeExpression, signatures: ReadonlyArray<Signature>, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean, fallbackError?: DiagnosticMessage): Signature {
|
||||
function resolveCall(node: CallLikeExpression, signatures: ReadonlyArray<Signature>, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode, fallbackError?: DiagnosticMessage): Signature {
|
||||
const isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression;
|
||||
const isDecorator = node.kind === SyntaxKind.Decorator;
|
||||
const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node);
|
||||
@@ -20515,7 +20537,7 @@ namespace ts {
|
||||
// For a decorator, no arguments are susceptible to contextual typing due to the fact
|
||||
// decorators are applied to a declaration by the emitter, and not to an expression.
|
||||
const isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters;
|
||||
let excludeArgument = !isDecorator && !isSingleNonGenericCandidate ? getExcludeArgument(args) : undefined;
|
||||
let argCheckMode = !isDecorator && !isSingleNonGenericCandidate && some(args, isContextSensitive) ? CheckMode.SkipContextSensitive : CheckMode.Normal;
|
||||
|
||||
// The following variables are captured and modified by calls to chooseOverload.
|
||||
// If overload resolution or type argument inference fails, we want to report the
|
||||
@@ -20546,7 +20568,7 @@ namespace ts {
|
||||
// If we are in signature help, a trailing comma indicates that we intend to provide another argument,
|
||||
// so we will only accept overloads with arity at least 1 higher than the current number of provided arguments.
|
||||
const signatureHelpTrailingComma =
|
||||
isForSignatureHelp && node.kind === SyntaxKind.CallExpression && node.arguments.hasTrailingComma;
|
||||
!!(checkMode & CheckMode.IsForSignatureHelp) && node.kind === SyntaxKind.CallExpression && node.arguments.hasTrailingComma;
|
||||
|
||||
// Section 4.12.1:
|
||||
// if the candidate list contains one or more signatures for which the type of each argument
|
||||
@@ -20574,12 +20596,7 @@ namespace ts {
|
||||
// skip the checkApplicableSignature check.
|
||||
if (reportErrors) {
|
||||
if (candidateForArgumentError) {
|
||||
// excludeArgument is undefined, in this case also equivalent to [undefined, undefined, ...]
|
||||
// The importance of excludeArgument is to prevent us from typing function expression parameters
|
||||
// in arguments too early. If possible, we'd like to only type them once we know the correct
|
||||
// overload. However, this matters for the case where the call is correct. When the call is
|
||||
// an error, we don't need to exclude any arguments, although it would cause no harm to do so.
|
||||
checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, /*reportErrors*/ true);
|
||||
checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, CheckMode.Normal, /*reportErrors*/ true);
|
||||
}
|
||||
else if (candidateForArgumentArityError) {
|
||||
diagnostics.add(getArgumentArityError(node, [candidateForArgumentArityError], args));
|
||||
@@ -20613,7 +20630,7 @@ namespace ts {
|
||||
if (typeArguments || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
|
||||
return undefined;
|
||||
}
|
||||
if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) {
|
||||
if (!checkApplicableSignature(node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ false)) {
|
||||
candidateForArgumentError = candidate;
|
||||
return undefined;
|
||||
}
|
||||
@@ -20640,9 +20657,10 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
|
||||
typeArgumentTypes = inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext);
|
||||
typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext);
|
||||
argCheckMode |= inferenceContext.flags & InferenceFlags.SkippedGenericFunction ? CheckMode.SkipGenericFunctions : CheckMode.Normal;
|
||||
}
|
||||
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration));
|
||||
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
|
||||
// If the original signature has a generic rest type, instantiation may produce a
|
||||
// signature with different arity and we need to perform another arity check.
|
||||
if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
|
||||
@@ -20653,21 +20671,21 @@ namespace ts {
|
||||
else {
|
||||
checkCandidate = candidate;
|
||||
}
|
||||
if (!checkApplicableSignature(node, args, checkCandidate, relation, excludeArgument, /*reportErrors*/ false)) {
|
||||
if (!checkApplicableSignature(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false)) {
|
||||
// Give preference to error candidates that have no rest parameters (as they are more specific)
|
||||
if (!candidateForArgumentError || getEffectiveRestType(candidateForArgumentError) || !getEffectiveRestType(checkCandidate)) {
|
||||
candidateForArgumentError = checkCandidate;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (excludeArgument) {
|
||||
if (argCheckMode) {
|
||||
// If one or more context sensitive arguments were excluded, we start including
|
||||
// them now (and keeping do so for any subsequent candidates) and perform a second
|
||||
// round of type inference and applicability checking for this particular candidate.
|
||||
excludeArgument = undefined;
|
||||
argCheckMode = CheckMode.Normal;
|
||||
if (inferenceContext) {
|
||||
const typeArgumentTypes = inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext);
|
||||
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration));
|
||||
const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext);
|
||||
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
|
||||
// If the original signature has a generic rest type, instantiation may produce a
|
||||
// signature with different arity and we need to perform another arity check.
|
||||
if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
|
||||
@@ -20675,7 +20693,7 @@ namespace ts {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!checkApplicableSignature(node, args, checkCandidate, relation, excludeArgument, /*reportErrors*/ false)) {
|
||||
if (!checkApplicableSignature(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false)) {
|
||||
// Give preference to error candidates that have no rest parameters (as they are more specific)
|
||||
if (!candidateForArgumentError || getEffectiveRestType(candidateForArgumentError) || !getEffectiveRestType(checkCandidate)) {
|
||||
candidateForArgumentError = checkCandidate;
|
||||
@@ -20691,21 +20709,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getExcludeArgument(args: ReadonlyArray<Expression>): boolean[] | undefined {
|
||||
let excludeArgument: boolean[] | undefined;
|
||||
// We do not need to call `getEffectiveArgumentCount` here as it only
|
||||
// applies when calculating the number of arguments for a decorator.
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (isContextSensitive(args[i])) {
|
||||
if (!excludeArgument) {
|
||||
excludeArgument = new Array(args.length);
|
||||
}
|
||||
excludeArgument[i] = true;
|
||||
}
|
||||
}
|
||||
return excludeArgument;
|
||||
}
|
||||
|
||||
// No signature was applicable. We have already reported the errors for the invalid signature.
|
||||
// If this is a type resolution session, e.g. Language Service, try to get better information than anySignature.
|
||||
function getCandidateForOverloadFailure(
|
||||
@@ -20805,7 +20808,7 @@ namespace ts {
|
||||
|
||||
function inferSignatureInstantiationForOverloadFailure(node: CallLikeExpression, typeParameters: ReadonlyArray<TypeParameter>, candidate: Signature, args: ReadonlyArray<Expression>): Signature {
|
||||
const inferenceContext = createInferenceContext(typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
|
||||
const typeArgumentTypes = inferTypeArguments(node, candidate, args, getExcludeArgument(args), inferenceContext);
|
||||
const typeArgumentTypes = inferTypeArguments(node, candidate, args, CheckMode.SkipContextSensitive | CheckMode.SkipGenericFunctions, inferenceContext);
|
||||
return createSignatureInstantiation(candidate, typeArgumentTypes);
|
||||
}
|
||||
|
||||
@@ -20828,7 +20831,7 @@ namespace ts {
|
||||
return maxParamsIndex;
|
||||
}
|
||||
|
||||
function resolveCallExpression(node: CallExpression, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
|
||||
function resolveCallExpression(node: CallExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
const superType = checkSuperExpression(node.expression);
|
||||
if (isTypeAny(superType)) {
|
||||
@@ -20843,7 +20846,7 @@ namespace ts {
|
||||
const baseTypeNode = getEffectiveBaseTypeNode(getContainingClass(node)!);
|
||||
if (baseTypeNode) {
|
||||
const baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments, baseTypeNode);
|
||||
return resolveCall(node, baseConstructors, candidatesOutArray, isForSignatureHelp);
|
||||
return resolveCall(node, baseConstructors, candidatesOutArray, checkMode);
|
||||
}
|
||||
}
|
||||
return resolveUntypedCall(node);
|
||||
@@ -20903,12 +20906,32 @@ namespace ts {
|
||||
}
|
||||
return resolveErrorCall(node);
|
||||
}
|
||||
// When a call to a generic function is an argument to an outer call to a generic function for which
|
||||
// inference is in process, we have a choice to make. If the inner call relies on inferences made from
|
||||
// its contextual type to its return type, deferring the inner call processing allows the best possible
|
||||
// contextual type to accumulate. But if the outer call relies on inferences made from the return type of
|
||||
// the inner call, the inner call should be processed early. There's no sure way to know which choice is
|
||||
// right (only a full unification algorithm can determine that), so we resort to the following heuristic:
|
||||
// If no type arguments are specified in the inner call and at least one call signature is generic and
|
||||
// returns a function type, we choose to defer processing. This narrowly permits function composition
|
||||
// operators to flow inferences through return types, but otherwise processes calls right away. We
|
||||
// use the resolvingSignature singleton to indicate that we deferred processing. This result will be
|
||||
// propagated out and eventually turned into silentNeverType (a type that is assignable to anything and
|
||||
// from which we never make inferences).
|
||||
if (checkMode & CheckMode.SkipGenericFunctions && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) {
|
||||
skippedGenericFunction(node, checkMode);
|
||||
return resolvingSignature;
|
||||
}
|
||||
// If the function is explicitly marked with `@class`, then it must be constructed.
|
||||
if (callSignatures.some(sig => isInJSFile(sig.declaration) && !!getJSDocClassTag(sig.declaration!))) {
|
||||
error(node, Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
|
||||
return resolveErrorCall(node);
|
||||
}
|
||||
return resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp);
|
||||
return resolveCall(node, callSignatures, candidatesOutArray, checkMode);
|
||||
}
|
||||
|
||||
function isGenericFunctionReturningFunction(signature: Signature) {
|
||||
return !!(signature.typeParameters && isFunctionType(getReturnTypeOfSignature(signature)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -20922,7 +20945,7 @@ namespace ts {
|
||||
!numCallSignatures && !numConstructSignatures && !(apparentFuncType.flags & (TypeFlags.Union | TypeFlags.Never)) && isTypeAssignableTo(funcType, globalFunctionType);
|
||||
}
|
||||
|
||||
function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
|
||||
function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
|
||||
if (node.arguments && languageVersion < ScriptTarget.ES5) {
|
||||
const spreadIndex = getSpreadArgumentIndex(node.arguments);
|
||||
if (spreadIndex >= 0) {
|
||||
@@ -20975,7 +20998,7 @@ namespace ts {
|
||||
return resolveErrorCall(node);
|
||||
}
|
||||
|
||||
return resolveCall(node, constructSignatures, candidatesOutArray, isForSignatureHelp);
|
||||
return resolveCall(node, constructSignatures, candidatesOutArray, checkMode);
|
||||
}
|
||||
|
||||
// If expressionType's apparent type is an object type with no construct signatures but
|
||||
@@ -20984,7 +21007,7 @@ namespace ts {
|
||||
// operation is Any. It is an error to have a Void this type.
|
||||
const callSignatures = getSignaturesOfType(expressionType, SignatureKind.Call);
|
||||
if (callSignatures.length) {
|
||||
const signature = resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp);
|
||||
const signature = resolveCall(node, callSignatures, candidatesOutArray, checkMode);
|
||||
if (!noImplicitAny) {
|
||||
if (signature.declaration && !isJSConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) {
|
||||
error(node, Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword);
|
||||
@@ -21094,7 +21117,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function resolveTaggedTemplateExpression(node: TaggedTemplateExpression, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
|
||||
function resolveTaggedTemplateExpression(node: TaggedTemplateExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
|
||||
const tagType = checkExpression(node.tag);
|
||||
const apparentType = getApparentType(tagType);
|
||||
|
||||
@@ -21115,7 +21138,7 @@ namespace ts {
|
||||
return resolveErrorCall(node);
|
||||
}
|
||||
|
||||
return resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp);
|
||||
return resolveCall(node, callSignatures, candidatesOutArray, checkMode);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -21146,7 +21169,7 @@ namespace ts {
|
||||
/**
|
||||
* Resolves a decorator as if it were a call expression.
|
||||
*/
|
||||
function resolveDecorator(node: Decorator, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
|
||||
function resolveDecorator(node: Decorator, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
|
||||
const funcType = checkExpression(node.expression);
|
||||
const apparentType = getApparentType(funcType);
|
||||
if (apparentType === errorType) {
|
||||
@@ -21175,7 +21198,7 @@ namespace ts {
|
||||
return resolveErrorCall(node);
|
||||
}
|
||||
|
||||
return resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp, headMessage);
|
||||
return resolveCall(node, callSignatures, candidatesOutArray, checkMode, headMessage);
|
||||
}
|
||||
|
||||
function createSignatureForJSXIntrinsic(node: JsxOpeningLikeElement, result: Type): Signature {
|
||||
@@ -21204,11 +21227,11 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
function resolveJsxOpeningLikeElement(node: JsxOpeningLikeElement, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
|
||||
function resolveJsxOpeningLikeElement(node: JsxOpeningLikeElement, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
|
||||
if (isJsxIntrinsicIdentifier(node.tagName)) {
|
||||
const result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node);
|
||||
const fakeSignature = createSignatureForJSXIntrinsic(node, result);
|
||||
checkTypeAssignableToAndOptionallyElaborate(checkExpressionWithContextualType(node.attributes, getEffectiveFirstArgumentForJsxSignature(fakeSignature, node), /*mapper*/ undefined), result, node.tagName, node.attributes);
|
||||
checkTypeAssignableToAndOptionallyElaborate(checkExpressionWithContextualType(node.attributes, getEffectiveFirstArgumentForJsxSignature(fakeSignature, node), /*mapper*/ undefined, CheckMode.Normal), result, node.tagName, node.attributes);
|
||||
return fakeSignature;
|
||||
}
|
||||
const exprTypes = checkExpression(node.tagName);
|
||||
@@ -21228,7 +21251,7 @@ namespace ts {
|
||||
return resolveErrorCall(node);
|
||||
}
|
||||
|
||||
return resolveCall(node, signatures, candidatesOutArray, isForSignatureHelp);
|
||||
return resolveCall(node, signatures, candidatesOutArray, checkMode);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -21243,19 +21266,19 @@ namespace ts {
|
||||
signature.parameters.length < getDecoratorArgumentCount(decorator, signature));
|
||||
}
|
||||
|
||||
function resolveSignature(node: CallLikeExpression, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean): Signature {
|
||||
function resolveSignature(node: CallLikeExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.CallExpression:
|
||||
return resolveCallExpression(node, candidatesOutArray, isForSignatureHelp);
|
||||
return resolveCallExpression(node, candidatesOutArray, checkMode);
|
||||
case SyntaxKind.NewExpression:
|
||||
return resolveNewExpression(node, candidatesOutArray, isForSignatureHelp);
|
||||
return resolveNewExpression(node, candidatesOutArray, checkMode);
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
return resolveTaggedTemplateExpression(node, candidatesOutArray, isForSignatureHelp);
|
||||
return resolveTaggedTemplateExpression(node, candidatesOutArray, checkMode);
|
||||
case SyntaxKind.Decorator:
|
||||
return resolveDecorator(node, candidatesOutArray, isForSignatureHelp);
|
||||
return resolveDecorator(node, candidatesOutArray, checkMode);
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return resolveJsxOpeningLikeElement(node, candidatesOutArray, isForSignatureHelp);
|
||||
return resolveJsxOpeningLikeElement(node, candidatesOutArray, checkMode);
|
||||
}
|
||||
throw Debug.assertNever(node, "Branch in 'resolveSignature' should be unreachable.");
|
||||
}
|
||||
@@ -21267,7 +21290,7 @@ namespace ts {
|
||||
* the function will fill it up with appropriate candidate signatures
|
||||
* @return a signature of the call-like expression or undefined if one can't be found
|
||||
*/
|
||||
function getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[] | undefined, isForSignatureHelp = false): Signature {
|
||||
function getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[] | undefined, checkMode?: CheckMode): Signature {
|
||||
const links = getNodeLinks(node);
|
||||
// If getResolvedSignature has already been called, we will have cached the resolvedSignature.
|
||||
// However, it is possible that either candidatesOutArray was not passed in the first time,
|
||||
@@ -21278,11 +21301,15 @@ namespace ts {
|
||||
return cached;
|
||||
}
|
||||
links.resolvedSignature = resolvingSignature;
|
||||
const result = resolveSignature(node, candidatesOutArray, isForSignatureHelp);
|
||||
// If signature resolution originated in control flow type analysis (for example to compute the
|
||||
// assigned type in a flow assignment) we don't cache the result as it may be based on temporary
|
||||
// types from the control flow analysis.
|
||||
links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached;
|
||||
const result = resolveSignature(node, candidatesOutArray, checkMode || CheckMode.Normal);
|
||||
// When CheckMode.SkipGenericFunctions is set we use resolvingSignature to indicate that call
|
||||
// resolution should be deferred.
|
||||
if (result !== resolvingSignature) {
|
||||
// If signature resolution originated in control flow type analysis (for example to compute the
|
||||
// assigned type in a flow assignment) we don't cache the result as it may be based on temporary
|
||||
// types from the control flow analysis.
|
||||
links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -21366,10 +21393,15 @@ namespace ts {
|
||||
* @param node The call/new expression to be checked.
|
||||
* @returns On success, the expression's signature's return type. On failure, anyType.
|
||||
*/
|
||||
function checkCallExpression(node: CallExpression | NewExpression): Type {
|
||||
function checkCallExpression(node: CallExpression | NewExpression, checkMode?: CheckMode): Type {
|
||||
if (!checkGrammarTypeArguments(node, node.typeArguments)) checkGrammarArguments(node.arguments);
|
||||
|
||||
const signature = getResolvedSignature(node);
|
||||
const signature = getResolvedSignature(node, /*candidatesOutArray*/ undefined, checkMode);
|
||||
if (signature === resolvingSignature) {
|
||||
// CheckMode.SkipGenericFunctions is enabled and this is a call to a generic function that
|
||||
// returns a function type. We defer checking and return anyFunctionType.
|
||||
return silentNeverType;
|
||||
}
|
||||
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return voidType;
|
||||
@@ -21870,7 +21902,7 @@ namespace ts {
|
||||
const functionFlags = getFunctionFlags(func);
|
||||
let type: Type;
|
||||
if (func.body.kind !== SyntaxKind.Block) {
|
||||
type = checkExpressionCached(func.body, checkMode);
|
||||
type = checkExpressionCached(func.body, checkMode && checkMode & ~CheckMode.SkipGenericFunctions);
|
||||
if (functionFlags & FunctionFlags.Async) {
|
||||
// From within an async function you can return either a non-promise value or a promise. Any
|
||||
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
|
||||
@@ -22060,7 +22092,7 @@ namespace ts {
|
||||
forEachReturnStatement(<Block>func.body, returnStatement => {
|
||||
const expr = returnStatement.expression;
|
||||
if (expr) {
|
||||
let type = checkExpressionCached(expr, checkMode);
|
||||
let type = checkExpressionCached(expr, checkMode && checkMode & ~CheckMode.SkipGenericFunctions);
|
||||
if (functionFlags & FunctionFlags.Async) {
|
||||
// From within an async function you can return either a non-promise value or a promise. Any
|
||||
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
|
||||
@@ -22160,7 +22192,7 @@ namespace ts {
|
||||
checkNodeDeferred(node);
|
||||
|
||||
// The identityMapper object is used to indicate that function expressions are wildcards
|
||||
if (checkMode === CheckMode.SkipContextSensitive && isContextSensitive(node)) {
|
||||
if (checkMode && checkMode & CheckMode.SkipContextSensitive && isContextSensitive(node)) {
|
||||
// Skip parameters, return signature with return type that retains noncontextual parts so inferences can still be drawn in an early stage
|
||||
if (!getEffectiveReturnTypeNode(node) && hasContextSensitiveReturnExpression(node)) {
|
||||
const links = getNodeLinks(node);
|
||||
@@ -22200,7 +22232,7 @@ namespace ts {
|
||||
const signature = getSignaturesOfType(type, SignatureKind.Call)[0];
|
||||
if (isContextSensitive(node)) {
|
||||
const contextualMapper = getContextualMapper(node);
|
||||
if (checkMode === CheckMode.Inferential) {
|
||||
if (checkMode && checkMode & CheckMode.Inferential) {
|
||||
inferFromAnnotatedParameters(signature, contextualSignature, contextualMapper);
|
||||
}
|
||||
const instantiatedContextualSignature = contextualMapper === identityMapper ?
|
||||
@@ -23211,15 +23243,13 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
function checkExpressionWithContextualType(node: Expression, contextualType: Type, contextualMapper: TypeMapper | undefined): Type {
|
||||
function checkExpressionWithContextualType(node: Expression, contextualType: Type, contextualMapper: TypeMapper | undefined, checkMode: CheckMode): Type {
|
||||
const context = getContextNode(node);
|
||||
const saveContextualType = context.contextualType;
|
||||
const saveContextualMapper = context.contextualMapper;
|
||||
context.contextualType = contextualType;
|
||||
context.contextualMapper = contextualMapper;
|
||||
const checkMode = contextualMapper === identityMapper ? CheckMode.SkipContextSensitive :
|
||||
contextualMapper ? CheckMode.Inferential : CheckMode.Contextual;
|
||||
const type = checkExpression(node, checkMode);
|
||||
const type = checkExpression(node, checkMode | CheckMode.Contextual | (contextualMapper ? CheckMode.Inferential : 0));
|
||||
// We strip literal freshness when an appropriate contextual type is present such that contextually typed
|
||||
// literals always preserve their literal types (otherwise they might widen during type inference). An alternative
|
||||
// here would be to not mark contextually typed literals as fresh in the first place.
|
||||
@@ -23233,7 +23263,7 @@ namespace ts {
|
||||
function checkExpressionCached(node: Expression, checkMode?: CheckMode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
if (checkMode) {
|
||||
if (checkMode && checkMode !== CheckMode.Normal) {
|
||||
return checkExpression(node, checkMode);
|
||||
}
|
||||
// When computing a type that we're going to cache, we need to ignore any ongoing control flow
|
||||
@@ -23341,22 +23371,127 @@ namespace ts {
|
||||
}
|
||||
|
||||
function instantiateTypeWithSingleGenericCallSignature(node: Expression | MethodDeclaration | QualifiedName, type: Type, checkMode?: CheckMode) {
|
||||
if (checkMode === CheckMode.Inferential) {
|
||||
if (checkMode && checkMode & (CheckMode.Inferential | CheckMode.SkipGenericFunctions)) {
|
||||
const signature = getSingleCallSignature(type);
|
||||
if (signature && signature.typeParameters) {
|
||||
if (checkMode & CheckMode.SkipGenericFunctions) {
|
||||
skippedGenericFunction(node, checkMode);
|
||||
return anyFunctionType;
|
||||
}
|
||||
const contextualType = getApparentTypeOfContextualType(<Expression>node);
|
||||
if (contextualType) {
|
||||
const contextualSignature = getSingleCallSignature(getNonNullableType(contextualType));
|
||||
if (contextualSignature && !contextualSignature.typeParameters) {
|
||||
return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, getContextualMapper(node)));
|
||||
const context = <InferenceContext>getContextualMapper(node);
|
||||
// We have an expression that is an argument of a generic function for which we are performing
|
||||
// type argument inference. The expression is of a function type with a single generic call
|
||||
// signature and a contextual function type with a single non-generic call signature. Now check
|
||||
// if the outer function returns a function type with a single non-generic call signature and
|
||||
// if some of the outer function type parameters have no inferences so far. If so, we can
|
||||
// potentially add inferred type parameters to the outer function return type.
|
||||
const returnSignature = context.signature && getSingleCallSignature(getReturnTypeOfSignature(context.signature));
|
||||
if (returnSignature && !returnSignature.typeParameters && !every(context.inferences, hasInferenceCandidates)) {
|
||||
// Instantiate the expression type with its own type parameters as type arguments. This
|
||||
// ensures that the type parameters are not erased to type any during type inference such
|
||||
// that they can be inferred as actual types.
|
||||
const uniqueTypeParameters = getUniqueTypeParameters(context, signature.typeParameters);
|
||||
const strippedType = getOrCreateTypeFromSignature(getSignatureInstantiationWithoutFillingInTypeArguments(signature, uniqueTypeParameters));
|
||||
// Infer from the stripped expression type to the contextual type starting with an empty
|
||||
// set of inference candidates.
|
||||
const inferences = map(context.typeParameters, createInferenceInfo);
|
||||
inferTypes(inferences, strippedType, contextualType);
|
||||
// If we produced some inference candidates and if the type parameters for which we produced
|
||||
// candidates do not already have existing inferences, we adopt the new inference candidates and
|
||||
// add the type parameters of the expression type to the set of inferred type parameters for
|
||||
// the outer function return type.
|
||||
if (some(inferences, hasInferenceCandidates) && !hasOverlappingInferences(context.inferences, inferences)) {
|
||||
mergeInferences(context.inferences, inferences);
|
||||
context.inferredTypeParameters = concatenate(context.inferredTypeParameters, uniqueTypeParameters);
|
||||
return strippedType;
|
||||
}
|
||||
}
|
||||
return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, context));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
function skippedGenericFunction(node: Node, checkMode: CheckMode) {
|
||||
if (checkMode & CheckMode.Inferential) {
|
||||
// We have skipped a generic function during inferential typing. Obtain the inference context and
|
||||
// indicate this has occurred such that we know a second pass of inference is be needed.
|
||||
const context = <InferenceContext>getContextualMapper(node);
|
||||
context.flags |= InferenceFlags.SkippedGenericFunction;
|
||||
}
|
||||
}
|
||||
|
||||
function hasInferenceCandidates(info: InferenceInfo) {
|
||||
return !!(info.candidates || info.contraCandidates);
|
||||
}
|
||||
|
||||
function hasOverlappingInferences(a: InferenceInfo[], b: InferenceInfo[]) {
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
if (hasInferenceCandidates(a[i]) && hasInferenceCandidates(b[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function mergeInferences(target: InferenceInfo[], source: InferenceInfo[]) {
|
||||
for (let i = 0; i < target.length; i++) {
|
||||
if (!hasInferenceCandidates(target[i]) && hasInferenceCandidates(source[i])) {
|
||||
target[i] = source[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getUniqueTypeParameters(context: InferenceContext, typeParameters: ReadonlyArray<TypeParameter>): ReadonlyArray<TypeParameter> {
|
||||
const result: TypeParameter[] = [];
|
||||
let oldTypeParameters: TypeParameter[] | undefined;
|
||||
let newTypeParameters: TypeParameter[] | undefined;
|
||||
for (const tp of typeParameters) {
|
||||
const name = tp.symbol.escapedName;
|
||||
if (hasTypeParameterByName(context.inferredTypeParameters, name) || hasTypeParameterByName(result, name)) {
|
||||
const newName = getUniqueTypeParameterName(concatenate(context.inferredTypeParameters, result), name);
|
||||
const symbol = createSymbol(SymbolFlags.TypeParameter, newName);
|
||||
const newTypeParameter = createTypeParameter(symbol);
|
||||
newTypeParameter.target = tp;
|
||||
oldTypeParameters = append(oldTypeParameters, tp);
|
||||
newTypeParameters = append(newTypeParameters, newTypeParameter);
|
||||
result.push(newTypeParameter);
|
||||
}
|
||||
else {
|
||||
result.push(tp);
|
||||
}
|
||||
}
|
||||
if (newTypeParameters) {
|
||||
const mapper = createTypeMapper(oldTypeParameters!, newTypeParameters);
|
||||
for (const tp of newTypeParameters) {
|
||||
tp.mapper = mapper;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function hasTypeParameterByName(typeParameters: ReadonlyArray<TypeParameter> | undefined, name: __String) {
|
||||
return some(typeParameters, tp => tp.symbol.escapedName === name);
|
||||
}
|
||||
|
||||
function getUniqueTypeParameterName(typeParameters: ReadonlyArray<TypeParameter>, baseName: __String) {
|
||||
let len = (<string>baseName).length;
|
||||
while (len > 1 && (<string>baseName).charCodeAt(len - 1) >= CharacterCodes._0 && (<string>baseName).charCodeAt(len - 1) <= CharacterCodes._9) len--;
|
||||
const s = (<string>baseName).slice(0, len);
|
||||
for (let index = 1; true; index++) {
|
||||
const augmentedName = <__String>(s + index);
|
||||
if (!hasTypeParameterByName(typeParameters, augmentedName)) {
|
||||
return augmentedName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of an expression. Unlike checkExpression, this function is simply concerned
|
||||
* with computing the type and may not fully check all contained sub-expressions for errors.
|
||||
@@ -23496,7 +23631,7 @@ namespace ts {
|
||||
}
|
||||
/* falls through */
|
||||
case SyntaxKind.NewExpression:
|
||||
return checkCallExpression(<CallExpression>node);
|
||||
return checkCallExpression(<CallExpression>node, checkMode);
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
return checkTaggedTemplateExpression(<TaggedTemplateExpression>node);
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
|
||||
+16
-1
@@ -917,7 +917,7 @@ namespace ts {
|
||||
|
||||
/**
|
||||
* Deduplicates an unsorted array.
|
||||
* @param equalityComparer An optional `EqualityComparer` used to determine if two values are duplicates.
|
||||
* @param equalityComparer An `EqualityComparer` used to determine if two values are duplicates.
|
||||
* @param comparer An optional `Comparer` used to sort entries before comparison, though the
|
||||
* result will remain in the original order in `array`.
|
||||
*/
|
||||
@@ -1173,6 +1173,21 @@ namespace ts {
|
||||
}};
|
||||
}
|
||||
|
||||
export function arrayReverseIterator<T>(array: ReadonlyArray<T>): Iterator<T> {
|
||||
let i = array.length;
|
||||
return {
|
||||
next: () => {
|
||||
if (i === 0) {
|
||||
return { value: undefined as never, done: true };
|
||||
}
|
||||
else {
|
||||
i--;
|
||||
return { value: array[i], done: false };
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Stable sort of an array. Elements equal to each other maintain their relative position in the array.
|
||||
*/
|
||||
|
||||
@@ -2927,6 +2927,10 @@
|
||||
"category": "Error",
|
||||
"code": 4102
|
||||
},
|
||||
"Type parameter '{0}' of exported mapped object type is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 4103
|
||||
},
|
||||
|
||||
"The current host does not support the '{0}' option.": {
|
||||
"category": "Error",
|
||||
@@ -4910,5 +4914,9 @@
|
||||
"Enable the 'experimentalDecorators' option in your configuration file": {
|
||||
"category": "Message",
|
||||
"code": 95074
|
||||
},
|
||||
"Convert to named parameters": {
|
||||
"category": "Message",
|
||||
"code": 95075
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,8 +71,8 @@ namespace ts {
|
||||
nonRecursive?: boolean;
|
||||
}
|
||||
|
||||
export function isPathInNodeModulesStartingWithDot(path: Path) {
|
||||
return stringContains(path, "/node_modules/.");
|
||||
export function isPathIgnored(path: Path) {
|
||||
return some(ignoredPaths, searchPath => stringContains(path, searchPath));
|
||||
}
|
||||
|
||||
export const maxNumberOfFilesToIterateForInvalidation = 256;
|
||||
@@ -696,7 +696,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
// If something to do with folder/file starting with "." in node_modules folder, skip it
|
||||
if (isPathInNodeModulesStartingWithDot(fileOrDirectoryPath)) return false;
|
||||
if (isPathIgnored(fileOrDirectoryPath)) return false;
|
||||
|
||||
// Some file or directory in the watching directory is created
|
||||
// Return early if it does not have any of the watching extension or not the custom failed lookup path
|
||||
|
||||
+16
-1
@@ -326,6 +326,9 @@ namespace ts {
|
||||
: FileWatcherEventKind.Changed;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export const ignoredPaths = ["/node_modules/.", "/.git"];
|
||||
|
||||
/*@internal*/
|
||||
export interface RecursiveDirectoryWatcherHost {
|
||||
watchDirectory: HostWatchDirectory;
|
||||
@@ -371,6 +374,8 @@ namespace ts {
|
||||
else {
|
||||
directoryWatcher = {
|
||||
watcher: host.watchDirectory(dirName, fileName => {
|
||||
if (isIgnoredPath(fileName)) return;
|
||||
|
||||
// Call the actual callback
|
||||
callbackCache.forEach((callbacks, rootDirName) => {
|
||||
if (rootDirName === dirPath || (startsWith(dirPath, rootDirName) && dirPath[rootDirName.length] === directorySeparator)) {
|
||||
@@ -426,7 +431,7 @@ namespace ts {
|
||||
const childFullName = getNormalizedAbsolutePath(child, parentDir);
|
||||
// Filter our the symbolic link directories since those arent included in recursive watch
|
||||
// which is same behaviour when recursive: true is passed to fs.watch
|
||||
return filePathComparer(childFullName, normalizePath(host.realpath(childFullName))) === Comparison.EqualTo ? childFullName : undefined;
|
||||
return !isIgnoredPath(childFullName) && filePathComparer(childFullName, normalizePath(host.realpath(childFullName))) === Comparison.EqualTo ? childFullName : undefined;
|
||||
}) : emptyArray,
|
||||
existingChildWatches,
|
||||
(child, childWatcher) => filePathComparer(child, childWatcher.dirName),
|
||||
@@ -452,6 +457,16 @@ namespace ts {
|
||||
(newChildWatches || (newChildWatches = [])).push(childWatcher);
|
||||
}
|
||||
}
|
||||
|
||||
function isIgnoredPath(path: string) {
|
||||
return some(ignoredPaths, searchPath => isInPath(path, searchPath));
|
||||
}
|
||||
|
||||
function isInPath(path: string, searchPath: string) {
|
||||
if (stringContains(path, searchPath)) return true;
|
||||
if (host.useCaseSensitiveFileNames) return false;
|
||||
return stringContains(toCanonicalFilePath(path), searchPath);
|
||||
}
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
|
||||
@@ -391,6 +391,10 @@ namespace ts {
|
||||
diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1;
|
||||
break;
|
||||
|
||||
case SyntaxKind.MappedType:
|
||||
diagnosticMessage = Diagnostics.Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
diagnosticMessage = Diagnostics.Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
|
||||
|
||||
@@ -4423,6 +4423,7 @@ namespace ts {
|
||||
NoDefault = 1 << 0, // Infer unknownType for no inferences (otherwise anyType or emptyObjectType)
|
||||
AnyDefault = 1 << 1, // Infer anyType for no inferences (otherwise emptyObjectType)
|
||||
NoFixing = 1 << 2, // Disable type parameter fixing
|
||||
SkippedGenericFunction = 1 << 3,
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4452,6 +4453,7 @@ namespace ts {
|
||||
flags: InferenceFlags; // Inference flags
|
||||
compareTypes: TypeComparer; // Type comparer function
|
||||
returnMapper?: TypeMapper; // Type mapper for inferences from return types (if any)
|
||||
inferredTypeParameters?: ReadonlyArray<TypeParameter>;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
||||
@@ -987,7 +987,7 @@ namespace ts {
|
||||
}
|
||||
nextSourceFileVersion(fileOrDirectoryPath);
|
||||
|
||||
if (isPathInNodeModulesStartingWithDot(fileOrDirectoryPath)) return;
|
||||
if (isPathIgnored(fileOrDirectoryPath)) return;
|
||||
|
||||
// If the the added or created file or directory is not supported file name, ignore the file
|
||||
// But when watched directory is added/removed, we need to reload the file list
|
||||
|
||||
+9
-372
@@ -47,23 +47,6 @@ interface XMLHttpRequest {
|
||||
/* tslint:enable:no-var-keyword prefer-const */
|
||||
|
||||
namespace Utils {
|
||||
// Setup some globals based on the current environment
|
||||
export const enum ExecutionEnvironment {
|
||||
Node,
|
||||
Browser,
|
||||
}
|
||||
|
||||
export function getExecutionEnvironment() {
|
||||
if (typeof window !== "undefined") {
|
||||
return ExecutionEnvironment.Browser;
|
||||
}
|
||||
else {
|
||||
return ExecutionEnvironment.Node;
|
||||
}
|
||||
}
|
||||
|
||||
export let currentExecutionEnvironment = getExecutionEnvironment();
|
||||
|
||||
export function encodeString(s: string): string {
|
||||
return ts.sys.bufferFrom!(s).toString("utf8");
|
||||
}
|
||||
@@ -74,23 +57,12 @@ namespace Utils {
|
||||
}
|
||||
|
||||
export function evalFile(fileContents: string, fileName: string, nodeContext?: any) {
|
||||
const environment = getExecutionEnvironment();
|
||||
switch (environment) {
|
||||
case ExecutionEnvironment.Browser:
|
||||
// tslint:disable-next-line:no-eval
|
||||
eval(fileContents);
|
||||
break;
|
||||
case ExecutionEnvironment.Node:
|
||||
const vm = require("vm");
|
||||
if (nodeContext) {
|
||||
vm.runInNewContext(fileContents, nodeContext, fileName);
|
||||
}
|
||||
else {
|
||||
vm.runInThisContext(fileContents, fileName);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unknown context");
|
||||
const vm = require("vm");
|
||||
if (nodeContext) {
|
||||
vm.runInNewContext(fileContents, nodeContext, fileName);
|
||||
}
|
||||
else {
|
||||
vm.runInThisContext(fileContents, fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -624,344 +596,11 @@ namespace Harness {
|
||||
};
|
||||
}
|
||||
|
||||
interface URL {
|
||||
hash: string;
|
||||
host: string;
|
||||
hostname: string;
|
||||
href: string;
|
||||
password: string;
|
||||
pathname: string;
|
||||
port: string;
|
||||
protocol: string;
|
||||
search: string;
|
||||
username: string;
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
declare var URL: {
|
||||
prototype: URL;
|
||||
new(url: string, base?: string | URL): URL;
|
||||
};
|
||||
|
||||
function createBrowserIO(): IO {
|
||||
const serverRoot = new URL("http://localhost:8888/");
|
||||
|
||||
class HttpHeaders extends collections.SortedMap<string, string | string[]> {
|
||||
constructor(template?: Record<string, string | string[]>) {
|
||||
super(ts.compareStringsCaseInsensitive);
|
||||
if (template) {
|
||||
for (const key in template) {
|
||||
if (ts.hasProperty(template, key)) {
|
||||
this.set(key, template[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static combine(left: HttpHeaders | undefined, right: HttpHeaders | undefined): HttpHeaders | undefined {
|
||||
if (!left && !right) return undefined;
|
||||
const headers = new HttpHeaders();
|
||||
if (left) left.forEach((value, key) => { headers.set(key, value); });
|
||||
if (right) right.forEach((value, key) => { headers.set(key, value); });
|
||||
return headers;
|
||||
}
|
||||
|
||||
public has(key: string) {
|
||||
return super.has(key.toLowerCase());
|
||||
}
|
||||
|
||||
public get(key: string) {
|
||||
return super.get(key.toLowerCase());
|
||||
}
|
||||
|
||||
public set(key: string, value: string | string[]) {
|
||||
return super.set(key.toLowerCase(), value);
|
||||
}
|
||||
|
||||
public delete(key: string) {
|
||||
return super.delete(key.toLowerCase());
|
||||
}
|
||||
|
||||
public writeRequestHeaders(xhr: XMLHttpRequest) {
|
||||
this.forEach((values, key) => {
|
||||
if (key === "access-control-allow-origin" || key === "content-length") return;
|
||||
const value = Array.isArray(values) ? values.join(",") : values;
|
||||
if (key === "content-type") {
|
||||
xhr.overrideMimeType(value);
|
||||
return;
|
||||
}
|
||||
xhr.setRequestHeader(key, value);
|
||||
});
|
||||
}
|
||||
|
||||
public static readResponseHeaders(xhr: XMLHttpRequest): HttpHeaders {
|
||||
const allHeaders = xhr.getAllResponseHeaders();
|
||||
const headers = new HttpHeaders();
|
||||
for (const header of allHeaders.split(/\r\n/g)) {
|
||||
const colonIndex = header.indexOf(":");
|
||||
if (colonIndex >= 0) {
|
||||
const key = header.slice(0, colonIndex).trim();
|
||||
const value = header.slice(colonIndex + 1).trim();
|
||||
const values = value.split(",");
|
||||
headers.set(key, values.length > 1 ? values : value);
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
}
|
||||
|
||||
class HttpContent {
|
||||
public headers: HttpHeaders;
|
||||
public content: string;
|
||||
|
||||
constructor(headers: HttpHeaders | Record<string, string | string[]>, content: string) {
|
||||
this.headers = headers instanceof HttpHeaders ? headers : new HttpHeaders(headers);
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public static fromMediaType(mediaType: string, content: string) {
|
||||
return new HttpContent({ "Content-Type": mediaType }, content);
|
||||
}
|
||||
|
||||
public static text(content: string) {
|
||||
return HttpContent.fromMediaType("text/plain", content);
|
||||
}
|
||||
|
||||
public static json(content: object) {
|
||||
return HttpContent.fromMediaType("application/json", JSON.stringify(content));
|
||||
}
|
||||
|
||||
public static readResponseContent(xhr: XMLHttpRequest) {
|
||||
if (typeof xhr.responseText === "string") {
|
||||
return new HttpContent({
|
||||
"Content-Type": xhr.getResponseHeader("Content-Type") || undefined!, // TODO: GH#18217
|
||||
"Content-Length": xhr.getResponseHeader("Content-Length") || undefined!, // TODO: GH#18217
|
||||
}, xhr.responseText);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public writeRequestHeaders(xhr: XMLHttpRequest) {
|
||||
this.headers.writeRequestHeaders(xhr);
|
||||
}
|
||||
}
|
||||
|
||||
class HttpRequestMessage {
|
||||
public method: string;
|
||||
public url: URL;
|
||||
public headers: HttpHeaders;
|
||||
public content?: HttpContent;
|
||||
|
||||
constructor(method: string, url: string | URL, headers?: HttpHeaders | Record<string, string | string[]>, content?: HttpContent) {
|
||||
this.method = method;
|
||||
this.url = typeof url === "string" ? new URL(url) : url;
|
||||
this.headers = headers instanceof HttpHeaders ? headers : new HttpHeaders(headers);
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public static options(url: string | URL) {
|
||||
return new HttpRequestMessage("OPTIONS", url);
|
||||
}
|
||||
|
||||
public static head(url: string | URL) {
|
||||
return new HttpRequestMessage("HEAD", url);
|
||||
}
|
||||
|
||||
public static get(url: string | URL) {
|
||||
return new HttpRequestMessage("GET", url);
|
||||
}
|
||||
|
||||
public static delete(url: string | URL) {
|
||||
return new HttpRequestMessage("DELETE", url);
|
||||
}
|
||||
|
||||
public static put(url: string | URL, content: HttpContent) {
|
||||
return new HttpRequestMessage("PUT", url, /*headers*/ undefined, content);
|
||||
}
|
||||
|
||||
public static post(url: string | URL, content: HttpContent) {
|
||||
return new HttpRequestMessage("POST", url, /*headers*/ undefined, content);
|
||||
}
|
||||
|
||||
public writeRequestHeaders(xhr: XMLHttpRequest) {
|
||||
this.headers.writeRequestHeaders(xhr);
|
||||
if (this.content) {
|
||||
this.content.writeRequestHeaders(xhr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class HttpResponseMessage {
|
||||
public statusCode: number;
|
||||
public statusMessage: string;
|
||||
public headers: HttpHeaders;
|
||||
public content?: HttpContent;
|
||||
|
||||
constructor(statusCode: number, statusMessage: string, headers?: HttpHeaders | Record<string, string | string[]>, content?: HttpContent) {
|
||||
this.statusCode = statusCode;
|
||||
this.statusMessage = statusMessage;
|
||||
this.headers = headers instanceof HttpHeaders ? headers : new HttpHeaders(headers);
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public static notFound(): HttpResponseMessage {
|
||||
return new HttpResponseMessage(404, "Not Found");
|
||||
}
|
||||
|
||||
public static hasSuccessStatusCode(response: HttpResponseMessage) {
|
||||
return response.statusCode === 304 || (response.statusCode >= 200 && response.statusCode < 300);
|
||||
}
|
||||
|
||||
public static readResponseMessage(xhr: XMLHttpRequest) {
|
||||
return new HttpResponseMessage(
|
||||
xhr.status,
|
||||
xhr.statusText,
|
||||
HttpHeaders.readResponseHeaders(xhr),
|
||||
HttpContent.readResponseContent(xhr));
|
||||
}
|
||||
}
|
||||
|
||||
function send(request: HttpRequestMessage): HttpResponseMessage {
|
||||
const xhr = new XMLHttpRequest();
|
||||
try {
|
||||
xhr.open(request.method, request.url.toString(), /*async*/ false);
|
||||
request.writeRequestHeaders(xhr);
|
||||
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
|
||||
xhr.send(request.content && request.content.content);
|
||||
while (xhr.readyState !== 4); // block until ready
|
||||
return HttpResponseMessage.readResponseMessage(xhr);
|
||||
}
|
||||
catch (e) {
|
||||
return HttpResponseMessage.notFound();
|
||||
}
|
||||
}
|
||||
|
||||
let caseSensitivity: "CI" | "CS" | undefined;
|
||||
|
||||
function useCaseSensitiveFileNames() {
|
||||
if (!caseSensitivity) {
|
||||
const response = send(HttpRequestMessage.options(new URL("*", serverRoot)));
|
||||
const xCaseSensitivity = response.headers.get("X-Case-Sensitivity");
|
||||
caseSensitivity = xCaseSensitivity === "CS" ? "CS" : "CI";
|
||||
}
|
||||
return caseSensitivity === "CS";
|
||||
}
|
||||
|
||||
function resolvePath(path: string) {
|
||||
const response = send(HttpRequestMessage.post(new URL("/api/resolve", serverRoot), HttpContent.text(path)));
|
||||
return HttpResponseMessage.hasSuccessStatusCode(response) && response.content ? response.content.content : undefined;
|
||||
}
|
||||
|
||||
function getFileSize(path: string): number {
|
||||
const response = send(HttpRequestMessage.head(new URL(path, serverRoot)));
|
||||
return HttpResponseMessage.hasSuccessStatusCode(response) ? +response.headers.get("Content-Length")!.toString() : 0;
|
||||
}
|
||||
|
||||
function readFile(path: string): string | undefined {
|
||||
const response = send(HttpRequestMessage.get(new URL(path, serverRoot)));
|
||||
return HttpResponseMessage.hasSuccessStatusCode(response) && response.content ? response.content.content : undefined;
|
||||
}
|
||||
|
||||
function writeFile(path: string, contents: string) {
|
||||
send(HttpRequestMessage.put(new URL(path, serverRoot), HttpContent.text(contents)));
|
||||
}
|
||||
|
||||
function fileExists(path: string): boolean {
|
||||
const response = send(HttpRequestMessage.head(new URL(path, serverRoot)));
|
||||
return HttpResponseMessage.hasSuccessStatusCode(response);
|
||||
}
|
||||
|
||||
function directoryExists(path: string): boolean {
|
||||
const response = send(HttpRequestMessage.post(new URL("/api/directoryExists", serverRoot), HttpContent.text(path)));
|
||||
return hasJsonContent(response) && JSON.parse(response.content.content) as boolean;
|
||||
}
|
||||
|
||||
function deleteFile(path: string) {
|
||||
send(HttpRequestMessage.delete(new URL(path, serverRoot)));
|
||||
}
|
||||
|
||||
function directoryName(path: string) {
|
||||
const url = new URL(path, serverRoot);
|
||||
return ts.getDirectoryPath(ts.normalizeSlashes(url.pathname || "/"));
|
||||
}
|
||||
|
||||
function enumerateTestFiles(runner: RunnerBase): (string | FileBasedTest)[] {
|
||||
const response = send(HttpRequestMessage.post(new URL("/api/enumerateTestFiles", serverRoot), HttpContent.text(runner.kind())));
|
||||
return hasJsonContent(response) ? JSON.parse(response.content.content) : [];
|
||||
}
|
||||
|
||||
function listFiles(dirname: string, spec?: RegExp, options?: { recursive?: boolean }): string[] {
|
||||
if (spec || (options && !options.recursive)) {
|
||||
let results = IO.listFiles(dirname);
|
||||
if (spec) {
|
||||
results = results.filter(file => spec.test(file));
|
||||
}
|
||||
if (options && !options.recursive) {
|
||||
results = results.filter(file => ts.getDirectoryPath(ts.normalizeSlashes(file)) === dirname);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
const response = send(HttpRequestMessage.post(new URL("/api/listFiles", serverRoot), HttpContent.text(dirname)));
|
||||
return hasJsonContent(response) ? JSON.parse(response.content.content) : [];
|
||||
}
|
||||
|
||||
function readDirectory(path: string, extension?: string[], exclude?: string[], include?: string[], depth?: number) {
|
||||
return ts.matchFiles(path, extension, exclude, include, useCaseSensitiveFileNames(), "", depth, getAccessibleFileSystemEntries);
|
||||
}
|
||||
|
||||
function getAccessibleFileSystemEntries(dirname: string): ts.FileSystemEntries {
|
||||
const response = send(HttpRequestMessage.post(new URL("/api/getAccessibleFileSystemEntries", serverRoot), HttpContent.text(dirname)));
|
||||
return hasJsonContent(response) ? JSON.parse(response.content.content) : { files: [], directories: [] };
|
||||
}
|
||||
|
||||
function hasJsonContent(response: HttpResponseMessage): response is HttpResponseMessage & { content: HttpContent } {
|
||||
return HttpResponseMessage.hasSuccessStatusCode(response)
|
||||
&& !!response.content
|
||||
&& /^application\/json(;.*)$/.test("" + response.content.headers.get("Content-Type"));
|
||||
}
|
||||
|
||||
return {
|
||||
newLine: () => harnessNewLine,
|
||||
getCurrentDirectory: () => "",
|
||||
useCaseSensitiveFileNames,
|
||||
resolvePath,
|
||||
getFileSize,
|
||||
readFile,
|
||||
writeFile,
|
||||
directoryName: Utils.memoize(directoryName, path => path),
|
||||
getDirectories: () => [],
|
||||
createDirectory: () => {}, // tslint:disable-line no-empty
|
||||
fileExists,
|
||||
directoryExists,
|
||||
deleteFile,
|
||||
listFiles: Utils.memoize(listFiles, (path, spec, options) => `${path}|${spec}|${options ? options.recursive === true : true}`),
|
||||
enumerateTestFiles: Utils.memoize(enumerateTestFiles, runner => runner.kind()),
|
||||
log: s => console.log(s),
|
||||
args: () => [],
|
||||
getExecutingFilePath: () => "",
|
||||
exit: () => {}, // tslint:disable-line no-empty
|
||||
readDirectory,
|
||||
getAccessibleFileSystemEntries,
|
||||
getWorkspaceRoot: () => "/"
|
||||
};
|
||||
}
|
||||
|
||||
export function mockHash(s: string): string {
|
||||
return `hash-${s}`;
|
||||
}
|
||||
|
||||
const environment = Utils.getExecutionEnvironment();
|
||||
switch (environment) {
|
||||
case Utils.ExecutionEnvironment.Node:
|
||||
IO = createNodeIO();
|
||||
break;
|
||||
case Utils.ExecutionEnvironment.Browser:
|
||||
IO = createBrowserIO();
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown value '${environment}' for ExecutionEnvironment.`);
|
||||
}
|
||||
IO = createNodeIO();
|
||||
}
|
||||
|
||||
if (Harness.IO.tryEnableSourceMapsForHost && /^development$/i.test(Harness.IO.getEnvironmentVariable!("NODE_ENV"))) {
|
||||
@@ -970,10 +609,8 @@ if (Harness.IO.tryEnableSourceMapsForHost && /^development$/i.test(Harness.IO.ge
|
||||
|
||||
namespace Harness {
|
||||
export const libFolder = "built/local/";
|
||||
const tcServicesFileName = ts.combinePaths(libFolder, Utils.getExecutionEnvironment() === Utils.ExecutionEnvironment.Browser ? "typescriptServicesInBrowserTest.js" : "typescriptServices.js");
|
||||
export const tcServicesFile = IO.readFile(tcServicesFileName) + (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser
|
||||
? IO.newLine() + `//# sourceURL=${IO.resolvePath(tcServicesFileName)}`
|
||||
: "");
|
||||
const tcServicesFileName = ts.combinePaths(libFolder, "typescriptServices.js");
|
||||
export const tcServicesFile = IO.readFile(tcServicesFileName) + IO.newLine() + `//# sourceURL=${IO.resolvePath(tcServicesFileName)}`;
|
||||
|
||||
export type SourceMapEmitterCallback = (
|
||||
emittedFile: string,
|
||||
|
||||
+103
-35
@@ -408,6 +408,21 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export interface OpenFileArguments {
|
||||
fileName: string;
|
||||
content?: string;
|
||||
scriptKind?: protocol.ScriptKindName | ScriptKind;
|
||||
hasMixedContent?: boolean;
|
||||
projectRootPath?: string;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export interface ChangeFileArguments {
|
||||
fileName: string;
|
||||
changes: Iterator<TextChange>;
|
||||
}
|
||||
|
||||
export class ProjectService {
|
||||
|
||||
/*@internal*/
|
||||
@@ -988,7 +1003,7 @@ namespace ts.server {
|
||||
fileOrDirectory => {
|
||||
const fileOrDirectoryPath = this.toPath(fileOrDirectory);
|
||||
project.getCachedDirectoryStructureHost().addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
|
||||
if (isPathInNodeModulesStartingWithDot(fileOrDirectoryPath)) return;
|
||||
if (isPathIgnored(fileOrDirectoryPath)) return;
|
||||
const configFilename = project.getConfigFilePath();
|
||||
|
||||
// If the the added or created file or directory is not supported file name, ignore the file
|
||||
@@ -1129,11 +1144,22 @@ namespace ts.server {
|
||||
return project;
|
||||
}
|
||||
|
||||
private assignOrphanScriptInfosToInferredProject() {
|
||||
// collect orphaned files and assign them to inferred project just like we treat open of a file
|
||||
this.openFiles.forEach((projectRootPath, path) => {
|
||||
const info = this.getScriptInfoForPath(path as Path)!;
|
||||
// collect all orphaned script infos from open files
|
||||
if (info.isOrphan()) {
|
||||
this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove this file from the set of open, non-configured files.
|
||||
* @param info The file that has been closed or newly configured
|
||||
*/
|
||||
private closeOpenFile(info: ScriptInfo): void {
|
||||
private closeOpenFile(info: ScriptInfo, skipAssignOrphanScriptInfosToInferredProject?: true) {
|
||||
// Closing file should trigger re-reading the file content from disk. This is
|
||||
// because the user may chose to discard the buffer content before saving
|
||||
// to the disk, and the server's version of the file can be out of sync.
|
||||
@@ -1177,15 +1203,8 @@ namespace ts.server {
|
||||
|
||||
this.openFiles.delete(info.path);
|
||||
|
||||
if (ensureProjectsForOpenFiles) {
|
||||
// collect orphaned files and assign them to inferred project just like we treat open of a file
|
||||
this.openFiles.forEach((projectRootPath, path) => {
|
||||
const info = this.getScriptInfoForPath(path as Path)!;
|
||||
// collect all orphaned script infos from open files
|
||||
if (info.isOrphan()) {
|
||||
this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
|
||||
}
|
||||
});
|
||||
if (!skipAssignOrphanScriptInfosToInferredProject && ensureProjectsForOpenFiles) {
|
||||
this.assignOrphanScriptInfosToInferredProject();
|
||||
}
|
||||
|
||||
// Cleanup script infos that arent part of any project (eg. those could be closed script infos not referenced by any project)
|
||||
@@ -1200,6 +1219,8 @@ namespace ts.server {
|
||||
else {
|
||||
this.handleDeletedFile(info);
|
||||
}
|
||||
|
||||
return ensureProjectsForOpenFiles;
|
||||
}
|
||||
|
||||
private deleteScriptInfo(info: ScriptInfo) {
|
||||
@@ -2051,7 +2072,7 @@ namespace ts.server {
|
||||
watchDir,
|
||||
(fileOrDirectory) => {
|
||||
const fileOrDirectoryPath = this.toPath(fileOrDirectory);
|
||||
if (isPathInNodeModulesStartingWithDot(fileOrDirectoryPath)) return;
|
||||
if (isPathIgnored(fileOrDirectoryPath)) return;
|
||||
|
||||
// Has extension
|
||||
Debug.assert(result.refCount > 0);
|
||||
@@ -2571,20 +2592,22 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult {
|
||||
private getOrCreateOpenScriptInfo(fileName: NormalizedPath, fileContent: string | undefined, scriptKind: ScriptKind | undefined, hasMixedContent: boolean | undefined, projectRootPath: NormalizedPath | undefined) {
|
||||
const info = this.getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName, projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory, fileContent, scriptKind, hasMixedContent)!; // TODO: GH#18217
|
||||
this.openFiles.set(info.path, projectRootPath);
|
||||
return info;
|
||||
}
|
||||
|
||||
private assignProjectToOpenedScriptInfo(info: ScriptInfo): OpenConfiguredProjectResult {
|
||||
let configFileName: NormalizedPath | undefined;
|
||||
let configFileErrors: ReadonlyArray<Diagnostic> | undefined;
|
||||
|
||||
const info = this.getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName, projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory, fileContent, scriptKind, hasMixedContent)!; // TODO: GH#18217
|
||||
|
||||
this.openFiles.set(info.path, projectRootPath);
|
||||
let project: ConfiguredProject | ExternalProject | undefined = this.findExternalProjectContainingOpenScriptInfo(info);
|
||||
if (!project && !this.syntaxOnly) { // Checking syntaxOnly is an optimization
|
||||
configFileName = this.getConfigFileNameForFile(info);
|
||||
if (configFileName) {
|
||||
project = this.findConfiguredProjectByProjectName(configFileName);
|
||||
if (!project) {
|
||||
project = this.createLoadAndUpdateConfiguredProject(configFileName, `Creating possible configured project for ${fileName} to open`);
|
||||
project = this.createLoadAndUpdateConfiguredProject(configFileName, `Creating possible configured project for ${info.fileName} to open`);
|
||||
// Send the event only if the project got created as part of this open request and info is part of the project
|
||||
if (info.isOrphan()) {
|
||||
// Since the file isnt part of configured project, do not send config file info
|
||||
@@ -2592,7 +2615,7 @@ namespace ts.server {
|
||||
}
|
||||
else {
|
||||
configFileErrors = project.getAllProjectErrors();
|
||||
this.sendConfigFileDiagEvent(project, fileName);
|
||||
this.sendConfigFileDiagEvent(project, info.fileName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -2614,10 +2637,14 @@ namespace ts.server {
|
||||
// At this point if file is part of any any configured or external project, then it would be present in the containing projects
|
||||
// So if it still doesnt have any containing projects, it needs to be part of inferred project
|
||||
if (info.isOrphan()) {
|
||||
this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
|
||||
Debug.assert(this.openFiles.has(info.path));
|
||||
this.assignOrphanScriptInfoToInferredProject(info, this.openFiles.get(info.path));
|
||||
}
|
||||
Debug.assert(!info.isOrphan());
|
||||
return { configFileName, configFileErrors };
|
||||
}
|
||||
|
||||
private cleanupAfterOpeningFile() {
|
||||
// This was postponed from closeOpenFile to after opening next file,
|
||||
// so that we can reuse the project if we need to right away
|
||||
this.removeOrphanConfiguredProjects();
|
||||
@@ -2637,9 +2664,14 @@ namespace ts.server {
|
||||
this.removeOrphanScriptInfos();
|
||||
|
||||
this.printProjects();
|
||||
}
|
||||
|
||||
openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult {
|
||||
const info = this.getOrCreateOpenScriptInfo(fileName, fileContent, scriptKind, hasMixedContent, projectRootPath);
|
||||
const result = this.assignProjectToOpenedScriptInfo(info);
|
||||
this.cleanupAfterOpeningFile();
|
||||
this.telemetryOnOpenFile(info);
|
||||
return { configFileName, configFileErrors };
|
||||
return result;
|
||||
}
|
||||
|
||||
private removeOrphanConfiguredProjects() {
|
||||
@@ -2746,12 +2778,16 @@ namespace ts.server {
|
||||
* Close file whose contents is managed by the client
|
||||
* @param filename is absolute pathname
|
||||
*/
|
||||
closeClientFile(uncheckedFileName: string) {
|
||||
closeClientFile(uncheckedFileName: string): void;
|
||||
/*@internal*/
|
||||
closeClientFile(uncheckedFileName: string, skipAssignOrphanScriptInfosToInferredProject: true): boolean;
|
||||
closeClientFile(uncheckedFileName: string, skipAssignOrphanScriptInfosToInferredProject?: true) {
|
||||
const info = this.getScriptInfoForNormalizedPath(toNormalizedPath(uncheckedFileName));
|
||||
if (info) {
|
||||
this.closeOpenFile(info);
|
||||
const result = info ? this.closeOpenFile(info, skipAssignOrphanScriptInfosToInferredProject) : false;
|
||||
if (!skipAssignOrphanScriptInfosToInferredProject) {
|
||||
this.printProjects();
|
||||
}
|
||||
this.printProjects();
|
||||
return result;
|
||||
}
|
||||
|
||||
private collectChanges(lastKnownProjectVersions: protocol.ProjectVersionInfo[], currentProjects: Project[], result: ProjectFilesWithTSDiagnostics[]): void {
|
||||
@@ -2771,36 +2807,68 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
applyChangesInOpenFiles(openFiles: protocol.ExternalFile[] | undefined, changedFiles: protocol.ChangedOpenFile[] | undefined, closedFiles: string[] | undefined): void {
|
||||
applyChangesInOpenFiles(openFiles: Iterator<OpenFileArguments> | undefined, changedFiles?: Iterator<ChangeFileArguments>, closedFiles?: string[]): void {
|
||||
let openScriptInfos: ScriptInfo[] | undefined;
|
||||
let assignOrphanScriptInfosToInferredProject = false;
|
||||
if (openFiles) {
|
||||
for (const file of openFiles) {
|
||||
while (true) {
|
||||
const { value: file, done } = openFiles.next();
|
||||
if (done) break;
|
||||
const scriptInfo = this.getScriptInfo(file.fileName);
|
||||
Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen(), "Script should not exist and not be open already");
|
||||
const normalizedPath = scriptInfo ? scriptInfo.fileName : toNormalizedPath(file.fileName);
|
||||
this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind!), file.hasMixedContent); // TODO: GH#18217
|
||||
// Create script infos so we have the new content for all the open files before we do any updates to projects
|
||||
const info = this.getOrCreateOpenScriptInfo(
|
||||
scriptInfo ? scriptInfo.fileName : toNormalizedPath(file.fileName),
|
||||
file.content,
|
||||
tryConvertScriptKindName(file.scriptKind!),
|
||||
file.hasMixedContent,
|
||||
file.projectRootPath ? toNormalizedPath(file.projectRootPath) : undefined
|
||||
);
|
||||
(openScriptInfos || (openScriptInfos = [])).push(info);
|
||||
}
|
||||
}
|
||||
|
||||
if (changedFiles) {
|
||||
for (const file of changedFiles) {
|
||||
while (true) {
|
||||
const { value: file, done } = changedFiles.next();
|
||||
if (done) break;
|
||||
const scriptInfo = this.getScriptInfo(file.fileName)!;
|
||||
Debug.assert(!!scriptInfo);
|
||||
// Make edits to script infos and marks containing project as dirty
|
||||
this.applyChangesToFile(scriptInfo, file.changes);
|
||||
}
|
||||
}
|
||||
|
||||
if (closedFiles) {
|
||||
for (const file of closedFiles) {
|
||||
this.closeClientFile(file);
|
||||
// Close files, but dont assign projects to orphan open script infos, that part comes later
|
||||
assignOrphanScriptInfosToInferredProject = this.closeClientFile(file, /*skipAssignOrphanScriptInfosToInferredProject*/ true) || assignOrphanScriptInfosToInferredProject;
|
||||
}
|
||||
}
|
||||
|
||||
// All the script infos now exist, so ok to go update projects for open files
|
||||
if (openScriptInfos) {
|
||||
openScriptInfos.forEach(info => this.assignProjectToOpenedScriptInfo(info));
|
||||
}
|
||||
|
||||
// While closing files there could be open files that needed assigning new inferred projects, do it now
|
||||
if (assignOrphanScriptInfosToInferredProject) {
|
||||
this.assignOrphanScriptInfosToInferredProject();
|
||||
}
|
||||
|
||||
// Cleanup projects
|
||||
this.cleanupAfterOpeningFile();
|
||||
|
||||
// Telemetry
|
||||
forEach(openScriptInfos, info => this.telemetryOnOpenFile(info));
|
||||
this.printProjects();
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
applyChangesToFile(scriptInfo: ScriptInfo, changes: TextChange[]) {
|
||||
// apply changes in reverse order
|
||||
for (let i = changes.length - 1; i >= 0; i--) {
|
||||
const change = changes[i];
|
||||
applyChangesToFile(scriptInfo: ScriptInfo, changes: Iterator<TextChange>) {
|
||||
while (true) {
|
||||
const { value: change, done } = changes.next();
|
||||
if (done) break;
|
||||
scriptInfo.editContent(change.span.start, change.span.start + change.span.length, change.newText);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ namespace ts.server.protocol {
|
||||
SynchronizeProjectList = "synchronizeProjectList",
|
||||
/* @internal */
|
||||
ApplyChangedToOpenFiles = "applyChangedToOpenFiles",
|
||||
UpdateOpen = "updateOpen",
|
||||
/* @internal */
|
||||
EncodedSemanticClassificationsFull = "encodedSemanticClassifications-full",
|
||||
/* @internal */
|
||||
@@ -1543,6 +1544,32 @@ namespace ts.server.protocol {
|
||||
closedFiles?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Request to synchronize list of open files with the client
|
||||
*/
|
||||
export interface UpdateOpenRequest extends Request {
|
||||
command: CommandTypes.UpdateOpen;
|
||||
arguments: UpdateOpenRequestArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Arguments to UpdateOpenRequest
|
||||
*/
|
||||
export interface UpdateOpenRequestArgs {
|
||||
/**
|
||||
* List of newly open files
|
||||
*/
|
||||
openFiles?: OpenRequestArgs[];
|
||||
/**
|
||||
* List of open files files that were changes
|
||||
*/
|
||||
changedFiles?: FileCodeEdits[];
|
||||
/**
|
||||
* List of files that were closed
|
||||
*/
|
||||
closedFiles?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Request to set compiler options for inferred projects.
|
||||
* External projects are opened / closed explicitly.
|
||||
|
||||
+33
-3
@@ -1654,10 +1654,10 @@ namespace ts.server {
|
||||
const end = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset);
|
||||
if (start >= 0) {
|
||||
this.changeSeq++;
|
||||
this.projectService.applyChangesToFile(scriptInfo, [{
|
||||
this.projectService.applyChangesToFile(scriptInfo, singleIterator({
|
||||
span: { start, length: end - start },
|
||||
newText: args.insertString! // TODO: GH#18217
|
||||
}]);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2096,9 +2096,39 @@ namespace ts.server {
|
||||
});
|
||||
return this.requiredResponse(converted);
|
||||
},
|
||||
[CommandNames.UpdateOpen]: (request: protocol.UpdateOpenRequest) => {
|
||||
this.changeSeq++;
|
||||
this.projectService.applyChangesInOpenFiles(
|
||||
request.arguments.openFiles && mapIterator(arrayIterator(request.arguments.openFiles), file => ({
|
||||
fileName: file.file,
|
||||
content: file.fileContent,
|
||||
scriptKind: file.scriptKindName,
|
||||
projectRootPath: file.projectRootPath
|
||||
})),
|
||||
request.arguments.changedFiles && mapIterator(arrayIterator(request.arguments.changedFiles), file => ({
|
||||
fileName: file.fileName,
|
||||
changes: mapDefinedIterator(arrayReverseIterator(file.textChanges), change => {
|
||||
const scriptInfo = Debug.assertDefined(this.projectService.getScriptInfo(file.fileName));
|
||||
const start = scriptInfo.lineOffsetToPosition(change.start.line, change.start.offset);
|
||||
const end = scriptInfo.lineOffsetToPosition(change.end.line, change.end.offset);
|
||||
return start >= 0 ? { span: { start, length: end - start }, newText: change.newText } : undefined;
|
||||
})
|
||||
})),
|
||||
request.arguments.closedFiles
|
||||
);
|
||||
return this.requiredResponse(/*response*/ true);
|
||||
},
|
||||
[CommandNames.ApplyChangedToOpenFiles]: (request: protocol.ApplyChangedToOpenFilesRequest) => {
|
||||
this.changeSeq++;
|
||||
this.projectService.applyChangesInOpenFiles(request.arguments.openFiles, request.arguments.changedFiles!, request.arguments.closedFiles!); // TODO: GH#18217
|
||||
this.projectService.applyChangesInOpenFiles(
|
||||
request.arguments.openFiles && arrayIterator(request.arguments.openFiles),
|
||||
request.arguments.changedFiles && mapIterator(arrayIterator(request.arguments.changedFiles), file => ({
|
||||
fileName: file.fileName,
|
||||
// apply changes in reverse order
|
||||
changes: arrayReverseIterator(file.changes)
|
||||
})),
|
||||
request.arguments.closedFiles
|
||||
);
|
||||
// TODO: report errors
|
||||
return this.requiredResponse(/*response*/ true);
|
||||
},
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace ts.codefix {
|
||||
precedingNode = ctorDeclaration.parent.parent;
|
||||
newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration as VariableDeclaration);
|
||||
if ((<VariableDeclarationList>ctorDeclaration.parent).declarations.length === 1) {
|
||||
copyComments(precedingNode, newClassDeclaration!, sourceFile); // TODO: GH#18217
|
||||
copyLeadingComments(precedingNode, newClassDeclaration!, sourceFile); // TODO: GH#18217
|
||||
changes.delete(sourceFile, precedingNode);
|
||||
}
|
||||
else {
|
||||
@@ -48,7 +48,7 @@ namespace ts.codefix {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
copyComments(ctorDeclaration, newClassDeclaration, sourceFile);
|
||||
copyLeadingComments(ctorDeclaration, newClassDeclaration, sourceFile);
|
||||
|
||||
// Because the preceding node could be touched, we need to insert nodes before delete nodes.
|
||||
changes.insertNodeAfter(sourceFile, precedingNode!, newClassDeclaration);
|
||||
@@ -112,7 +112,7 @@ namespace ts.codefix {
|
||||
const fullModifiers = concatenate(modifiers, getModifierKindFromSource(functionExpression, SyntaxKind.AsyncKeyword));
|
||||
const method = createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined,
|
||||
/*typeParameters*/ undefined, functionExpression.parameters, /*type*/ undefined, functionExpression.body);
|
||||
copyComments(assignmentBinaryExpression, method, sourceFile);
|
||||
copyLeadingComments(assignmentBinaryExpression, method, sourceFile);
|
||||
return method;
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace ts.codefix {
|
||||
const fullModifiers = concatenate(modifiers, getModifierKindFromSource(arrowFunction, SyntaxKind.AsyncKeyword));
|
||||
const method = createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined,
|
||||
/*typeParameters*/ undefined, arrowFunction.parameters, /*type*/ undefined, bodyBlock);
|
||||
copyComments(assignmentBinaryExpression, method, sourceFile);
|
||||
copyLeadingComments(assignmentBinaryExpression, method, sourceFile);
|
||||
return method;
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace ts.codefix {
|
||||
}
|
||||
const prop = createProperty(/*decorators*/ undefined, modifiers, memberDeclaration.name, /*questionToken*/ undefined,
|
||||
/*type*/ undefined, assignmentBinaryExpression.right);
|
||||
copyComments(assignmentBinaryExpression.parent, prop, sourceFile);
|
||||
copyLeadingComments(assignmentBinaryExpression.parent, prop, sourceFile);
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,30 +304,6 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeNodeIfAccessible(type: Type, enclosingScope: Node, program: Program, host: LanguageServiceHost): TypeNode | undefined {
|
||||
const checker = program.getTypeChecker();
|
||||
let typeIsAccessible = true;
|
||||
const notAccessible = () => { typeIsAccessible = false; };
|
||||
const res = checker.typeToTypeNode(type, enclosingScope, /*flags*/ undefined, {
|
||||
trackSymbol: (symbol, declaration, meaning) => {
|
||||
// TODO: GH#18217
|
||||
typeIsAccessible = typeIsAccessible && checker.isSymbolAccessible(symbol, declaration, meaning!, /*shouldComputeAliasToMarkVisible*/ false).accessibility === SymbolAccessibility.Accessible;
|
||||
},
|
||||
reportInaccessibleThisError: notAccessible,
|
||||
reportPrivateInBaseOfClassExpression: notAccessible,
|
||||
reportInaccessibleUniqueSymbolError: notAccessible,
|
||||
moduleResolverHost: {
|
||||
readFile: host.readFile,
|
||||
fileExists: host.fileExists,
|
||||
directoryExists: host.directoryExists,
|
||||
getSourceFiles: program.getSourceFiles,
|
||||
getCurrentDirectory: program.getCurrentDirectory,
|
||||
getCommonSourceDirectory: program.getCommonSourceDirectory,
|
||||
}
|
||||
});
|
||||
return typeIsAccessible ? res : undefined;
|
||||
}
|
||||
|
||||
function getReferences(token: PropertyName | Token<SyntaxKind.ConstructorKeyword>, program: Program, cancellationToken: CancellationToken): ReadonlyArray<Identifier> {
|
||||
// Position shouldn't matter since token is not a SourceFile.
|
||||
return mapDefined(FindAllReferences.getReferenceEntriesForNode(-1, token, program, program.getSourceFiles(), cancellationToken), entry =>
|
||||
|
||||
@@ -68,8 +68,8 @@ namespace ts.OrganizeImports {
|
||||
else {
|
||||
// Note: Delete the surrounding trivia because it will have been retained in newImportDecls.
|
||||
changeTracker.replaceNodeWithNodes(sourceFile, oldImportDecls[0], newImportDecls, {
|
||||
useNonAdjustedStartPosition: true, // Leave header comment in place
|
||||
useNonAdjustedEndPosition: false,
|
||||
leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, // Leave header comment in place
|
||||
trailingTriviaOption: textChanges.TrailingTriviaOption.Include,
|
||||
suffix: getNewLineOrDefaultFromHost(host, formatContext.options),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -48,13 +48,13 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction {
|
||||
const returnStatement = createReturn(expression);
|
||||
body = createBlock([returnStatement], /* multiLine */ true);
|
||||
suppressLeadingAndTrailingTrivia(body);
|
||||
copyComments(expression!, returnStatement, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ true);
|
||||
copyLeadingComments(expression!, returnStatement, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ true);
|
||||
}
|
||||
else if (actionName === removeBracesActionName && returnStatement) {
|
||||
const actualExpression = expression || createVoidZero();
|
||||
body = needsParentheses(actualExpression) ? createParen(actualExpression) : actualExpression;
|
||||
suppressLeadingAndTrailingTrivia(body);
|
||||
copyComments(returnStatement, body, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false);
|
||||
copyLeadingComments(returnStatement, body, file, SyntaxKind.MultiLineCommentTrivia, /* hasTrailingNewLine */ false);
|
||||
}
|
||||
else {
|
||||
Debug.fail("invalid action");
|
||||
|
||||
@@ -0,0 +1,520 @@
|
||||
/* @internal */
|
||||
namespace ts.refactor.convertToNamedParameters {
|
||||
const refactorName = "Convert to named parameters";
|
||||
const minimumParameterLength = 2;
|
||||
registerRefactor(refactorName, { getEditsForAction, getAvailableActions });
|
||||
|
||||
|
||||
function getAvailableActions(context: RefactorContext): ReadonlyArray<ApplicableRefactorInfo> {
|
||||
const { file, startPosition } = context;
|
||||
const isJSFile = isSourceFileJS(file);
|
||||
if (isJSFile) return emptyArray; // TODO: GH#30113
|
||||
const functionDeclaration = getFunctionDeclarationAtPosition(file, startPosition, context.program.getTypeChecker());
|
||||
if (!functionDeclaration) return emptyArray;
|
||||
|
||||
const description = getLocaleSpecificMessage(Diagnostics.Convert_to_named_parameters);
|
||||
return [{
|
||||
name: refactorName,
|
||||
description,
|
||||
actions: [{
|
||||
name: refactorName,
|
||||
description
|
||||
}]
|
||||
}];
|
||||
}
|
||||
|
||||
function getEditsForAction(context: RefactorContext, actionName: string): RefactorEditInfo | undefined {
|
||||
Debug.assert(actionName === refactorName);
|
||||
const { file, startPosition, program, cancellationToken, host } = context;
|
||||
const functionDeclaration = getFunctionDeclarationAtPosition(file, startPosition, program.getTypeChecker());
|
||||
if (!functionDeclaration || !cancellationToken) return undefined;
|
||||
|
||||
const groupedReferences = getGroupedReferences(functionDeclaration, program, cancellationToken);
|
||||
if (groupedReferences.valid) {
|
||||
const edits = textChanges.ChangeTracker.with(context, t => doChange(file, program, host, t, functionDeclaration, groupedReferences));
|
||||
return { renameFilename: undefined, renameLocation: undefined, edits };
|
||||
}
|
||||
|
||||
return { edits: [] }; // TODO: GH#30113
|
||||
}
|
||||
|
||||
function doChange(
|
||||
sourceFile: SourceFile,
|
||||
program: Program,
|
||||
host: LanguageServiceHost,
|
||||
changes: textChanges.ChangeTracker,
|
||||
functionDeclaration: ValidFunctionDeclaration,
|
||||
groupedReferences: GroupedReferences): void {
|
||||
const newParamDeclaration = map(createNewParameters(functionDeclaration, program, host), param => getSynthesizedDeepClone(param));
|
||||
changes.replaceNodeRangeWithNodes(
|
||||
sourceFile,
|
||||
first(functionDeclaration.parameters),
|
||||
last(functionDeclaration.parameters),
|
||||
newParamDeclaration,
|
||||
{ joiner: ", ",
|
||||
// indentation is set to 0 because otherwise the object parameter will be indented if there is a `this` parameter
|
||||
indentation: 0,
|
||||
leadingTriviaOption: textChanges.LeadingTriviaOption.IncludeAll,
|
||||
trailingTriviaOption: textChanges.TrailingTriviaOption.Include
|
||||
});
|
||||
|
||||
const functionCalls = sortAndDeduplicate(groupedReferences.functionCalls, /*comparer*/ (a, b) => compareValues(a.pos, b.pos));
|
||||
for (const call of functionCalls) {
|
||||
if (call.arguments && call.arguments.length) {
|
||||
const newArgument = getSynthesizedDeepClone(createNewArgument(functionDeclaration, call.arguments), /*includeTrivia*/ true);
|
||||
changes.replaceNodeRange(
|
||||
getSourceFileOfNode(call),
|
||||
first(call.arguments),
|
||||
last(call.arguments),
|
||||
newArgument,
|
||||
{ leadingTriviaOption: textChanges.LeadingTriviaOption.IncludeAll, trailingTriviaOption: textChanges.TrailingTriviaOption.Include });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getGroupedReferences(functionDeclaration: ValidFunctionDeclaration, program: Program, cancellationToken: CancellationToken): GroupedReferences {
|
||||
const functionNames = getFunctionNames(functionDeclaration);
|
||||
const classNames = isConstructorDeclaration(functionDeclaration) ? getClassNames(functionDeclaration) : [];
|
||||
const names = deduplicate([...functionNames, ...classNames], equateValues);
|
||||
const checker = program.getTypeChecker();
|
||||
|
||||
const references = flatMap(names, /*mapfn*/ name => FindAllReferences.getReferenceEntriesForNode(-1, name, program, program.getSourceFiles(), cancellationToken));
|
||||
const groupedReferences = groupReferences(references);
|
||||
|
||||
if (!every(groupedReferences.declarations, decl => contains(names, decl))) {
|
||||
groupedReferences.valid = false;
|
||||
}
|
||||
|
||||
return groupedReferences;
|
||||
|
||||
function groupReferences(referenceEntries: ReadonlyArray<FindAllReferences.Entry>): GroupedReferences {
|
||||
const classReferences: ClassReferences = { accessExpressions: [], typeUsages: [] };
|
||||
const groupedReferences: GroupedReferences = { functionCalls: [], declarations: [], classReferences, valid: true };
|
||||
const functionSymbols = map(functionNames, checker.getSymbolAtLocation);
|
||||
const classSymbols = map(classNames, checker.getSymbolAtLocation);
|
||||
const isConstructor = isConstructorDeclaration(functionDeclaration);
|
||||
|
||||
for (const entry of referenceEntries) {
|
||||
if (entry.kind !== FindAllReferences.EntryKind.Node) {
|
||||
groupedReferences.valid = false;
|
||||
continue;
|
||||
}
|
||||
if (contains(functionSymbols, checker.getSymbolAtLocation(entry.node), symbolComparer)) {
|
||||
const decl = entryToDeclaration(entry);
|
||||
if (decl) {
|
||||
groupedReferences.declarations.push(decl);
|
||||
continue;
|
||||
}
|
||||
|
||||
const call = entryToFunctionCall(entry);
|
||||
if (call) {
|
||||
groupedReferences.functionCalls.push(call);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// if the refactored function is a constructor, we must also check if the references to its class are valid
|
||||
if (isConstructor && contains(classSymbols, checker.getSymbolAtLocation(entry.node), symbolComparer)) {
|
||||
const decl = entryToDeclaration(entry);
|
||||
if (decl) {
|
||||
groupedReferences.declarations.push(decl);
|
||||
continue;
|
||||
}
|
||||
|
||||
const accessExpression = entryToAccessExpression(entry);
|
||||
if (accessExpression) {
|
||||
classReferences.accessExpressions.push(accessExpression);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only class declarations are allowed to be used as a type (in a heritage clause),
|
||||
// otherwise `findAllReferences` might not be able to track constructor calls.
|
||||
if (isClassDeclaration(functionDeclaration.parent)) {
|
||||
const type = entryToType(entry);
|
||||
if (type) {
|
||||
classReferences.typeUsages.push(type);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
groupedReferences.valid = false;
|
||||
}
|
||||
|
||||
return groupedReferences;
|
||||
}
|
||||
}
|
||||
|
||||
function symbolComparer(a: Symbol, b: Symbol): boolean {
|
||||
return getSymbolTarget(a) === getSymbolTarget(b);
|
||||
}
|
||||
|
||||
function entryToDeclaration(entry: FindAllReferences.NodeEntry): Node | undefined {
|
||||
if (isDeclaration(entry.node.parent)) {
|
||||
return entry.node;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function entryToFunctionCall(entry: FindAllReferences.NodeEntry): CallExpression | NewExpression | undefined {
|
||||
if (entry.node.parent) {
|
||||
const functionReference = entry.node;
|
||||
const parent = functionReference.parent;
|
||||
switch (parent.kind) {
|
||||
// Function call (foo(...) or super(...))
|
||||
case SyntaxKind.CallExpression:
|
||||
const callExpression = tryCast(parent, isCallExpression);
|
||||
if (callExpression && callExpression.expression === functionReference) {
|
||||
return callExpression;
|
||||
}
|
||||
break;
|
||||
// Constructor call (new Foo(...))
|
||||
case SyntaxKind.NewExpression:
|
||||
const newExpression = tryCast(parent, isNewExpression);
|
||||
if (newExpression && newExpression.expression === functionReference) {
|
||||
return newExpression;
|
||||
}
|
||||
break;
|
||||
// Method call (x.foo(...))
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
const propertyAccessExpression = tryCast(parent, isPropertyAccessExpression);
|
||||
if (propertyAccessExpression && propertyAccessExpression.parent && propertyAccessExpression.name === functionReference) {
|
||||
const callExpression = tryCast(propertyAccessExpression.parent, isCallExpression);
|
||||
if (callExpression && callExpression.expression === propertyAccessExpression) {
|
||||
return callExpression;
|
||||
}
|
||||
}
|
||||
break;
|
||||
// Method call (x["foo"](...))
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
const elementAccessExpression = tryCast(parent, isElementAccessExpression);
|
||||
if (elementAccessExpression && elementAccessExpression.parent && elementAccessExpression.argumentExpression === functionReference) {
|
||||
const callExpression = tryCast(elementAccessExpression.parent, isCallExpression);
|
||||
if (callExpression && callExpression.expression === elementAccessExpression) {
|
||||
return callExpression;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function entryToAccessExpression(entry: FindAllReferences.NodeEntry): ElementAccessExpression | PropertyAccessExpression | undefined {
|
||||
if (entry.node.parent) {
|
||||
const reference = entry.node;
|
||||
const parent = reference.parent;
|
||||
switch (parent.kind) {
|
||||
// `C.foo`
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
const propertyAccessExpression = tryCast(parent, isPropertyAccessExpression);
|
||||
if (propertyAccessExpression && propertyAccessExpression.expression === reference) {
|
||||
return propertyAccessExpression;
|
||||
}
|
||||
break;
|
||||
// `C["foo"]`
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
const elementAccessExpression = tryCast(parent, isElementAccessExpression);
|
||||
if (elementAccessExpression && elementAccessExpression.expression === reference) {
|
||||
return elementAccessExpression;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function entryToType(entry: FindAllReferences.NodeEntry): Node | undefined {
|
||||
const reference = entry.node;
|
||||
if (getMeaningFromLocation(reference) === SemanticMeaning.Type || isExpressionWithTypeArgumentsInClassExtendsClause(reference.parent)) {
|
||||
return reference;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getFunctionDeclarationAtPosition(file: SourceFile, startPosition: number, checker: TypeChecker): ValidFunctionDeclaration | undefined {
|
||||
const node = getTouchingToken(file, startPosition);
|
||||
const functionDeclaration = getContainingFunction(node);
|
||||
if (functionDeclaration
|
||||
&& isValidFunctionDeclaration(functionDeclaration, checker)
|
||||
&& rangeContainsRange(functionDeclaration, node)
|
||||
&& !(functionDeclaration.body && rangeContainsRange(functionDeclaration.body, node))) return functionDeclaration;
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isValidFunctionDeclaration(functionDeclaration: SignatureDeclaration, checker: TypeChecker): functionDeclaration is ValidFunctionDeclaration {
|
||||
if (!isValidParameterNodeArray(functionDeclaration.parameters)) return false;
|
||||
switch (functionDeclaration.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
return !!functionDeclaration.name && !!functionDeclaration.body && !checker.isImplementationOfOverload(functionDeclaration);
|
||||
case SyntaxKind.Constructor:
|
||||
if (isClassDeclaration(functionDeclaration.parent)) {
|
||||
return !!functionDeclaration.body && !!functionDeclaration.parent.name && !checker.isImplementationOfOverload(functionDeclaration);
|
||||
}
|
||||
else {
|
||||
return isValidVariableDeclaration(functionDeclaration.parent.parent) && !!functionDeclaration.body && !checker.isImplementationOfOverload(functionDeclaration);
|
||||
}
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
return isValidVariableDeclaration(functionDeclaration.parent);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isValidParameterNodeArray(parameters: NodeArray<ParameterDeclaration>): parameters is ValidParameterNodeArray {
|
||||
return getRefactorableParametersLength(parameters) >= minimumParameterLength && every(parameters, isValidParameterDeclaration);
|
||||
}
|
||||
|
||||
function isValidParameterDeclaration(paramDeclaration: ParameterDeclaration): paramDeclaration is ValidParameterDeclaration {
|
||||
return !paramDeclaration.modifiers && !paramDeclaration.decorators && isIdentifier(paramDeclaration.name);
|
||||
}
|
||||
|
||||
function isValidVariableDeclaration(node: Node): node is ValidVariableDeclaration {
|
||||
return isVariableDeclaration(node) && isVarConst(node) && isIdentifier(node.name) && !node.type; // TODO: GH#30113
|
||||
}
|
||||
|
||||
function hasThisParameter(parameters: NodeArray<ParameterDeclaration>): boolean {
|
||||
return parameters.length > 0 && isThis(parameters[0].name);
|
||||
}
|
||||
|
||||
function getRefactorableParametersLength(parameters: NodeArray<ParameterDeclaration>): number {
|
||||
if (hasThisParameter(parameters)) {
|
||||
return parameters.length - 1;
|
||||
}
|
||||
return parameters.length;
|
||||
}
|
||||
|
||||
function getRefactorableParameters(parameters: NodeArray<ValidParameterDeclaration>): NodeArray<ValidParameterDeclaration> {
|
||||
if (hasThisParameter(parameters)) {
|
||||
parameters = createNodeArray(parameters.slice(1), parameters.hasTrailingComma);
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
function createNewArgument(functionDeclaration: ValidFunctionDeclaration, functionArguments: NodeArray<Expression>): ObjectLiteralExpression {
|
||||
const parameters = getRefactorableParameters(functionDeclaration.parameters);
|
||||
const hasRestParameter = isRestParameter(last(parameters));
|
||||
const nonRestArguments = hasRestParameter ? functionArguments.slice(0, parameters.length - 1) : functionArguments;
|
||||
const properties = map(nonRestArguments, (arg, i) => {
|
||||
const property = createPropertyAssignment(getParameterName(parameters[i]), arg);
|
||||
suppressLeadingAndTrailingTrivia(property.initializer);
|
||||
copyComments(arg, property);
|
||||
return property;
|
||||
});
|
||||
|
||||
if (hasRestParameter && functionArguments.length >= parameters.length) {
|
||||
const restArguments = functionArguments.slice(parameters.length - 1);
|
||||
const restProperty = createPropertyAssignment(getParameterName(last(parameters)), createArrayLiteral(restArguments));
|
||||
properties.push(restProperty);
|
||||
}
|
||||
|
||||
const objectLiteral = createObjectLiteral(properties, /*multiLine*/ false);
|
||||
return objectLiteral;
|
||||
}
|
||||
|
||||
function createNewParameters(functionDeclaration: ValidFunctionDeclaration, program: Program, host: LanguageServiceHost): NodeArray<ParameterDeclaration> {
|
||||
const refactorableParameters = getRefactorableParameters(functionDeclaration.parameters);
|
||||
const bindingElements = map(refactorableParameters, createBindingElementFromParameterDeclaration);
|
||||
const objectParameterName = createObjectBindingPattern(bindingElements);
|
||||
const objectParameterType = createParameterTypeNode(refactorableParameters);
|
||||
const checker = program.getTypeChecker();
|
||||
|
||||
let objectInitializer: Expression | undefined;
|
||||
// If every parameter in the original function was optional, add an empty object initializer to the new object parameter
|
||||
if (every(refactorableParameters, checker.isOptionalParameter)) {
|
||||
objectInitializer = createObjectLiteral();
|
||||
}
|
||||
|
||||
const objectParameter = createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
objectParameterName,
|
||||
/*questionToken*/ undefined,
|
||||
objectParameterType,
|
||||
objectInitializer);
|
||||
|
||||
if (hasThisParameter(functionDeclaration.parameters)) {
|
||||
const thisParameter = functionDeclaration.parameters[0];
|
||||
const newThisParameter = createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
thisParameter.name,
|
||||
/*questionToken*/ undefined,
|
||||
thisParameter.type);
|
||||
|
||||
suppressLeadingAndTrailingTrivia(newThisParameter.name);
|
||||
copyComments(thisParameter.name, newThisParameter.name);
|
||||
if (thisParameter.type) {
|
||||
suppressLeadingAndTrailingTrivia(newThisParameter.type!);
|
||||
copyComments(thisParameter.type, newThisParameter.type!);
|
||||
}
|
||||
|
||||
return createNodeArray([newThisParameter, objectParameter]);
|
||||
}
|
||||
return createNodeArray([objectParameter]);
|
||||
|
||||
function createParameterTypeNode(parameters: NodeArray<ValidParameterDeclaration>): TypeLiteralNode {
|
||||
const members = map(parameters, createPropertySignatureFromParameterDeclaration);
|
||||
const typeNode = addEmitFlags(createTypeLiteralNode(members), EmitFlags.SingleLine);
|
||||
return typeNode;
|
||||
}
|
||||
|
||||
function createPropertySignatureFromParameterDeclaration(parameterDeclaration: ValidParameterDeclaration): PropertySignature {
|
||||
let parameterType = parameterDeclaration.type;
|
||||
if (!parameterType && (parameterDeclaration.initializer || isRestParameter(parameterDeclaration))) {
|
||||
parameterType = getTypeNode(parameterDeclaration);
|
||||
}
|
||||
|
||||
const propertySignature = createPropertySignature(
|
||||
/*modifiers*/ undefined,
|
||||
getParameterName(parameterDeclaration),
|
||||
parameterDeclaration.initializer || isRestParameter(parameterDeclaration) ? createToken(SyntaxKind.QuestionToken) : parameterDeclaration.questionToken,
|
||||
parameterType,
|
||||
/*initializer*/ undefined);
|
||||
|
||||
suppressLeadingAndTrailingTrivia(propertySignature);
|
||||
copyComments(parameterDeclaration.name, propertySignature.name);
|
||||
if (parameterDeclaration.type && propertySignature.type) {
|
||||
copyComments(parameterDeclaration.type, propertySignature.type);
|
||||
}
|
||||
|
||||
return propertySignature;
|
||||
}
|
||||
|
||||
function getTypeNode(node: Node): TypeNode | undefined {
|
||||
const checker = program.getTypeChecker();
|
||||
const type = checker.getTypeAtLocation(node);
|
||||
return getTypeNodeIfAccessible(type, node, program, host);
|
||||
}
|
||||
}
|
||||
|
||||
function createBindingElementFromParameterDeclaration(parameterDeclaration: ValidParameterDeclaration): BindingElement {
|
||||
const element = createBindingElement(
|
||||
/*dotDotDotToken*/ undefined,
|
||||
/*propertyName*/ undefined,
|
||||
getParameterName(parameterDeclaration),
|
||||
isRestParameter(parameterDeclaration) ? createArrayLiteral() : parameterDeclaration.initializer);
|
||||
|
||||
suppressLeadingAndTrailingTrivia(element);
|
||||
if (parameterDeclaration.initializer && element.initializer) {
|
||||
copyComments(parameterDeclaration.initializer, element.initializer);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
function copyComments(sourceNode: Node, targetNode: Node) {
|
||||
const sourceFile = sourceNode.getSourceFile();
|
||||
const text = sourceFile.text;
|
||||
if (hasLeadingLineBreak(sourceNode, text)) {
|
||||
copyLeadingComments(sourceNode, targetNode, sourceFile);
|
||||
}
|
||||
else {
|
||||
copyTrailingAsLeadingComments(sourceNode, targetNode, sourceFile);
|
||||
}
|
||||
copyTrailingComments(sourceNode, targetNode, sourceFile);
|
||||
}
|
||||
|
||||
function hasLeadingLineBreak(node: Node, text: string) {
|
||||
const start = node.getFullStart();
|
||||
const end = node.getStart();
|
||||
for (let i = start; i < end; i++) {
|
||||
if (text.charCodeAt(i) === CharacterCodes.lineFeed) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getParameterName(paramDeclaration: ValidParameterDeclaration) {
|
||||
return getTextOfIdentifierOrLiteral(paramDeclaration.name);
|
||||
}
|
||||
|
||||
function getClassNames(constructorDeclaration: ValidConstructor): Identifier[] {
|
||||
switch (constructorDeclaration.parent.kind) {
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
const classDeclaration = constructorDeclaration.parent;
|
||||
return [classDeclaration.name];
|
||||
case SyntaxKind.ClassExpression:
|
||||
const classExpression = constructorDeclaration.parent;
|
||||
const variableDeclaration = constructorDeclaration.parent.parent;
|
||||
const className = classExpression.name;
|
||||
if (className) return [className, variableDeclaration.name];
|
||||
return [variableDeclaration.name];
|
||||
}
|
||||
}
|
||||
|
||||
function getFunctionNames(functionDeclaration: ValidFunctionDeclaration): Node[] {
|
||||
switch (functionDeclaration.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
return [functionDeclaration.name];
|
||||
case SyntaxKind.Constructor:
|
||||
const ctrKeyword = findChildOfKind(functionDeclaration, SyntaxKind.ConstructorKeyword, functionDeclaration.getSourceFile())!;
|
||||
if (functionDeclaration.parent.kind === SyntaxKind.ClassExpression) {
|
||||
const variableDeclaration = functionDeclaration.parent.parent;
|
||||
return [variableDeclaration.name, ctrKeyword];
|
||||
}
|
||||
return [ctrKeyword];
|
||||
case SyntaxKind.ArrowFunction:
|
||||
return [functionDeclaration.parent.name];
|
||||
case SyntaxKind.FunctionExpression:
|
||||
if (functionDeclaration.name) return [functionDeclaration.name, functionDeclaration.parent.name];
|
||||
return [functionDeclaration.parent.name];
|
||||
default:
|
||||
return Debug.assertNever(functionDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
type ValidParameterNodeArray = NodeArray<ValidParameterDeclaration>;
|
||||
|
||||
interface ValidVariableDeclaration extends VariableDeclaration {
|
||||
name: Identifier;
|
||||
type: undefined;
|
||||
}
|
||||
|
||||
interface ValidConstructor extends ConstructorDeclaration {
|
||||
parent: (ClassDeclaration & { name: Identifier }) | (ClassExpression & { parent: ValidVariableDeclaration });
|
||||
parameters: NodeArray<ValidParameterDeclaration>;
|
||||
body: FunctionBody;
|
||||
}
|
||||
|
||||
interface ValidFunction extends FunctionDeclaration {
|
||||
name: Identifier;
|
||||
parameters: NodeArray<ValidParameterDeclaration>;
|
||||
body: FunctionBody;
|
||||
}
|
||||
|
||||
interface ValidMethod extends MethodDeclaration {
|
||||
parameters: NodeArray<ValidParameterDeclaration>;
|
||||
body: FunctionBody;
|
||||
}
|
||||
|
||||
interface ValidFunctionExpression extends FunctionExpression {
|
||||
parent: ValidVariableDeclaration;
|
||||
parameters: NodeArray<ValidParameterDeclaration>;
|
||||
}
|
||||
|
||||
interface ValidArrowFunction extends ArrowFunction {
|
||||
parent: ValidVariableDeclaration;
|
||||
parameters: NodeArray<ValidParameterDeclaration>;
|
||||
}
|
||||
|
||||
type ValidFunctionDeclaration = ValidConstructor | ValidFunction | ValidMethod | ValidArrowFunction | ValidFunctionExpression;
|
||||
|
||||
interface ValidParameterDeclaration extends ParameterDeclaration {
|
||||
name: Identifier;
|
||||
modifiers: undefined;
|
||||
decorators: undefined;
|
||||
}
|
||||
|
||||
interface GroupedReferences {
|
||||
functionCalls: (CallExpression | NewExpression)[];
|
||||
declarations: Node[];
|
||||
classReferences?: ClassReferences;
|
||||
valid: boolean;
|
||||
}
|
||||
interface ClassReferences {
|
||||
accessExpressions: Node[];
|
||||
typeUsages: Node[];
|
||||
}
|
||||
}
|
||||
@@ -1798,7 +1798,7 @@ namespace ts {
|
||||
const span = createTextSpanFromBounds(start, end);
|
||||
const formatContext = formatting.getFormatContext(formatOptions);
|
||||
|
||||
return flatMap(deduplicate(errorCodes, equateValues, compareValues), errorCode => {
|
||||
return flatMap(deduplicate<number>(errorCodes, equateValues, compareValues), errorCode => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
return codefix.getFixes({ errorCode, sourceFile, span, program, host, cancellationToken, formatContext, preferences });
|
||||
});
|
||||
|
||||
+42
-29
@@ -28,17 +28,27 @@ namespace ts.textChanges {
|
||||
}
|
||||
|
||||
export interface ConfigurableStart {
|
||||
/** True to use getStart() (NB, not getFullStart()) without adjustment. */
|
||||
useNonAdjustedStartPosition?: boolean;
|
||||
leadingTriviaOption?: LeadingTriviaOption;
|
||||
}
|
||||
export interface ConfigurableEnd {
|
||||
/** True to use getEnd() without adjustment. */
|
||||
useNonAdjustedEndPosition?: boolean;
|
||||
trailingTriviaOption?: TrailingTriviaOption;
|
||||
}
|
||||
|
||||
export enum Position {
|
||||
FullStart,
|
||||
Start
|
||||
export enum LeadingTriviaOption {
|
||||
/** Exclude all leading trivia (use getStart()) */
|
||||
Exclude,
|
||||
/** Include leading trivia and,
|
||||
* if there are no line breaks between the node and the previous token,
|
||||
* include all trivia between the node and the previous token
|
||||
*/
|
||||
IncludeAll,
|
||||
}
|
||||
|
||||
export enum TrailingTriviaOption {
|
||||
/** Exclude all trailing trivia (use getEnd()) */
|
||||
Exclude,
|
||||
/** Include trailing trivia */
|
||||
Include,
|
||||
}
|
||||
|
||||
function skipWhitespacesAndLineBreaks(text: string, start: number) {
|
||||
@@ -68,13 +78,14 @@ namespace ts.textChanges {
|
||||
* Usually leading trivia of the variable declaration 'y' should not include trailing trivia (whitespace, comment 'this is x' and newline) from the preceding
|
||||
* variable declaration and trailing trivia for 'y' should include (whitespace, comment 'this is y', newline).
|
||||
* By default when removing nodes we adjust start and end positions to respect specification of the trivia above.
|
||||
* If pos\end should be interpreted literally 'useNonAdjustedStartPosition' or 'useNonAdjustedEndPosition' should be set to true
|
||||
* If pos\end should be interpreted literally (that is, withouth including leading and trailing trivia), `leadingTriviaOption` should be set to `LeadingTriviaOption.Exclude`
|
||||
* and `trailingTriviaOption` to `TrailingTriviaOption.Exclude`.
|
||||
*/
|
||||
export interface ConfigurableStartEnd extends ConfigurableStart, ConfigurableEnd {}
|
||||
|
||||
export const useNonAdjustedPositions: ConfigurableStartEnd = {
|
||||
useNonAdjustedStartPosition: true,
|
||||
useNonAdjustedEndPosition: true,
|
||||
const useNonAdjustedPositions: ConfigurableStartEnd = {
|
||||
leadingTriviaOption: LeadingTriviaOption.Exclude,
|
||||
trailingTriviaOption: TrailingTriviaOption.Exclude,
|
||||
};
|
||||
|
||||
export interface InsertNodeOptions {
|
||||
@@ -143,11 +154,12 @@ namespace ts.textChanges {
|
||||
}
|
||||
|
||||
function getAdjustedRange(sourceFile: SourceFile, startNode: Node, endNode: Node, options: ConfigurableStartEnd): TextRange {
|
||||
return { pos: getAdjustedStartPosition(sourceFile, startNode, options, Position.Start), end: getAdjustedEndPosition(sourceFile, endNode, options) };
|
||||
return { pos: getAdjustedStartPosition(sourceFile, startNode, options), end: getAdjustedEndPosition(sourceFile, endNode, options) };
|
||||
}
|
||||
|
||||
function getAdjustedStartPosition(sourceFile: SourceFile, node: Node, options: ConfigurableStart, position: Position) {
|
||||
if (options.useNonAdjustedStartPosition) {
|
||||
function getAdjustedStartPosition(sourceFile: SourceFile, node: Node, options: ConfigurableStart) {
|
||||
const { leadingTriviaOption } = options;
|
||||
if (leadingTriviaOption === LeadingTriviaOption.Exclude) {
|
||||
return node.getStart(sourceFile);
|
||||
}
|
||||
const fullStart = node.getFullStart();
|
||||
@@ -165,7 +177,7 @@ namespace ts.textChanges {
|
||||
// fullstart
|
||||
// when b is replaced - we usually want to keep the leading trvia
|
||||
// when b is deleted - we delete it
|
||||
return position === Position.Start ? start : fullStart;
|
||||
return leadingTriviaOption === LeadingTriviaOption.IncludeAll ? fullStart : start;
|
||||
}
|
||||
// get start position of the line following the line that contains fullstart position
|
||||
// (but only if the fullstart isn't the very beginning of the file)
|
||||
@@ -178,11 +190,12 @@ namespace ts.textChanges {
|
||||
|
||||
function getAdjustedEndPosition(sourceFile: SourceFile, node: Node, options: ConfigurableEnd) {
|
||||
const { end } = node;
|
||||
if (options.useNonAdjustedEndPosition || isExpression(node)) {
|
||||
const { trailingTriviaOption } = options;
|
||||
if (trailingTriviaOption === TrailingTriviaOption.Exclude || (isExpression(node) && trailingTriviaOption !== TrailingTriviaOption.Include)) {
|
||||
return end;
|
||||
}
|
||||
const newEnd = skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true);
|
||||
return newEnd !== end && isLineBreak(sourceFile.text.charCodeAt(newEnd - 1))
|
||||
return newEnd !== end && (trailingTriviaOption === TrailingTriviaOption.Include || isLineBreak(sourceFile.text.charCodeAt(newEnd - 1)))
|
||||
? newEnd
|
||||
: end;
|
||||
}
|
||||
@@ -240,15 +253,15 @@ namespace ts.textChanges {
|
||||
this.deleteRange(sourceFile, { pos: modifier.getStart(sourceFile), end: skipTrivia(sourceFile.text, modifier.end, /*stopAfterLineBreak*/ true) });
|
||||
}
|
||||
|
||||
public deleteNodeRange(sourceFile: SourceFile, startNode: Node, endNode: Node, options: ConfigurableStartEnd = {}): void {
|
||||
const startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.FullStart);
|
||||
public deleteNodeRange(sourceFile: SourceFile, startNode: Node, endNode: Node, options: ConfigurableStartEnd = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }): void {
|
||||
const startPosition = getAdjustedStartPosition(sourceFile, startNode, options);
|
||||
const endPosition = getAdjustedEndPosition(sourceFile, endNode, options);
|
||||
this.deleteRange(sourceFile, { pos: startPosition, end: endPosition });
|
||||
}
|
||||
|
||||
public deleteNodeRangeExcludingEnd(sourceFile: SourceFile, startNode: Node, afterEndNode: Node | undefined, options: ConfigurableStartEnd = {}): void {
|
||||
const startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.FullStart);
|
||||
const endPosition = afterEndNode === undefined ? sourceFile.text.length : getAdjustedStartPosition(sourceFile, afterEndNode, options, Position.FullStart);
|
||||
public deleteNodeRangeExcludingEnd(sourceFile: SourceFile, startNode: Node, afterEndNode: Node | undefined, options: ConfigurableStartEnd = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }): void {
|
||||
const startPosition = getAdjustedStartPosition(sourceFile, startNode, options);
|
||||
const endPosition = afterEndNode === undefined ? sourceFile.text.length : getAdjustedStartPosition(sourceFile, afterEndNode, options);
|
||||
this.deleteRange(sourceFile, { pos: startPosition, end: endPosition });
|
||||
}
|
||||
|
||||
@@ -307,7 +320,7 @@ namespace ts.textChanges {
|
||||
}
|
||||
|
||||
public insertNodeBefore(sourceFile: SourceFile, before: Node, newNode: Node, blankLineBetween = false): void {
|
||||
this.insertNodeAt(sourceFile, getAdjustedStartPosition(sourceFile, before, {}, Position.Start), newNode, this.getOptionsForInsertNodeBefore(before, blankLineBetween));
|
||||
this.insertNodeAt(sourceFile, getAdjustedStartPosition(sourceFile, before, {}), newNode, this.getOptionsForInsertNodeBefore(before, blankLineBetween));
|
||||
}
|
||||
|
||||
public insertModifierBefore(sourceFile: SourceFile, modifier: SyntaxKind, before: Node): void {
|
||||
@@ -427,7 +440,7 @@ namespace ts.textChanges {
|
||||
}
|
||||
|
||||
public insertNodeAtEndOfScope(sourceFile: SourceFile, scope: Node, newNode: Node): void {
|
||||
const pos = getAdjustedStartPosition(sourceFile, scope.getLastToken()!, {}, Position.Start);
|
||||
const pos = getAdjustedStartPosition(sourceFile, scope.getLastToken()!, {});
|
||||
this.insertNodeAt(sourceFile, pos, newNode, {
|
||||
prefix: isLineBreak(sourceFile.text.charCodeAt(scope.getLastToken()!.pos)) ? this.newLineCharacter : this.newLineCharacter + this.newLineCharacter,
|
||||
suffix: this.newLineCharacter
|
||||
@@ -736,7 +749,7 @@ namespace ts.textChanges {
|
||||
|
||||
// find first non-whitespace position in the leading trivia of the node
|
||||
function startPositionToDeleteNodeInList(sourceFile: SourceFile, node: Node): number {
|
||||
return skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, {}, Position.FullStart), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
|
||||
return skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, { leadingTriviaOption: LeadingTriviaOption.IncludeAll }), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
|
||||
}
|
||||
|
||||
function getClassOrObjectBraceEnds(cls: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression, sourceFile: SourceFile): [number, number] {
|
||||
@@ -1090,7 +1103,7 @@ namespace ts.textChanges {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
deleteNode(changes, sourceFile, node,
|
||||
// For first import, leave header comment in place
|
||||
node === sourceFile.imports[0].parent ? { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: false } : undefined);
|
||||
node === sourceFile.imports[0].parent ? { leadingTriviaOption: LeadingTriviaOption.Exclude } : undefined);
|
||||
break;
|
||||
|
||||
case SyntaxKind.BindingElement:
|
||||
@@ -1134,7 +1147,7 @@ namespace ts.textChanges {
|
||||
deleteNodeInList(changes, deletedNodesInLists, sourceFile, node);
|
||||
}
|
||||
else {
|
||||
deleteNode(changes, sourceFile, node, node.kind === SyntaxKind.SemicolonToken ? { useNonAdjustedEndPosition: true } : undefined);
|
||||
deleteNode(changes, sourceFile, node, node.kind === SyntaxKind.SemicolonToken ? { trailingTriviaOption: TrailingTriviaOption.Exclude } : undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1213,8 +1226,8 @@ namespace ts.textChanges {
|
||||
|
||||
/** Warning: This deletes comments too. See `copyComments` in `convertFunctionToEs6Class`. */
|
||||
// Exported for tests only! (TODO: improve tests to not need this)
|
||||
export function deleteNode(changes: ChangeTracker, sourceFile: SourceFile, node: Node, options: ConfigurableStartEnd = {}): void {
|
||||
const startPosition = getAdjustedStartPosition(sourceFile, node, options, Position.FullStart);
|
||||
export function deleteNode(changes: ChangeTracker, sourceFile: SourceFile, node: Node, options: ConfigurableStartEnd = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }): void {
|
||||
const startPosition = getAdjustedStartPosition(sourceFile, node, options);
|
||||
const endPosition = getAdjustedEndPosition(sourceFile, node, options);
|
||||
changes.deleteRange(sourceFile, { pos: startPosition, end: endPosition });
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@
|
||||
"refactors/generateGetAccessorAndSetAccessor.ts",
|
||||
"refactors/moveToNewFile.ts",
|
||||
"refactors/addOrRemoveBracesToArrowFunction.ts",
|
||||
"refactors/convertToNamedParameters.ts",
|
||||
"services.ts",
|
||||
"breakpoints.ts",
|
||||
"transform.ts",
|
||||
|
||||
@@ -1664,6 +1664,18 @@ namespace ts {
|
||||
return ensureScriptKind(fileName, host && host.getScriptKind && host.getScriptKind(fileName));
|
||||
}
|
||||
|
||||
export function getSymbolTarget(symbol: Symbol): Symbol {
|
||||
let next: Symbol = symbol;
|
||||
while (isTransientSymbol(next) && next.target) {
|
||||
next = next.target;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
function isTransientSymbol(symbol: Symbol): symbol is TransientSymbol {
|
||||
return (symbol.flags & SymbolFlags.Transient) !== 0;
|
||||
}
|
||||
|
||||
export function getUniqueSymbolId(symbol: Symbol, checker: TypeChecker) {
|
||||
return getSymbolId(skipAlias(symbol, checker));
|
||||
}
|
||||
@@ -1821,8 +1833,28 @@ namespace ts {
|
||||
return lastPos;
|
||||
}
|
||||
|
||||
export function copyComments(sourceNode: Node, targetNode: Node, sourceFile: SourceFile, commentKind?: CommentKind, hasTrailingNewLine?: boolean) {
|
||||
forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, (pos, end, kind, htnl) => {
|
||||
export function copyLeadingComments(sourceNode: Node, targetNode: Node, sourceFile: SourceFile, commentKind?: CommentKind, hasTrailingNewLine?: boolean) {
|
||||
forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, addSyntheticLeadingComment));
|
||||
}
|
||||
|
||||
|
||||
export function copyTrailingComments(sourceNode: Node, targetNode: Node, sourceFile: SourceFile, commentKind?: CommentKind, hasTrailingNewLine?: boolean) {
|
||||
forEachTrailingCommentRange(sourceFile.text, sourceNode.end, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, addSyntheticTrailingComment));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function copies the trailing comments for the token that comes before `sourceNode`, as leading comments of `targetNode`.
|
||||
* This is useful because sometimes a comment that refers to `sourceNode` will be a leading comment for `sourceNode`, according to the
|
||||
* notion of trivia ownership, and instead will be a trailing comment for the token before `sourceNode`, e.g.:
|
||||
* `function foo(\* not leading comment for a *\ a: string) {}`
|
||||
* The comment refers to `a` but belongs to the `(` token, but we might want to copy it.
|
||||
*/
|
||||
export function copyTrailingAsLeadingComments(sourceNode: Node, targetNode: Node, sourceFile: SourceFile, commentKind?: CommentKind, hasTrailingNewLine?: boolean) {
|
||||
forEachTrailingCommentRange(sourceFile.text, sourceNode.pos, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, addSyntheticLeadingComment));
|
||||
}
|
||||
|
||||
function getAddCommentsFunction(targetNode: Node, sourceFile: SourceFile, commentKind: CommentKind | undefined, hasTrailingNewLine: boolean | undefined, cb: (node: Node, kind: CommentKind, text: string, hasTrailingNewLine?: boolean) => void) {
|
||||
return (pos: number, end: number, kind: CommentKind, htnl: boolean) => {
|
||||
if (kind === SyntaxKind.MultiLineCommentTrivia) {
|
||||
// Remove leading /*
|
||||
pos += 2;
|
||||
@@ -1833,8 +1865,8 @@ namespace ts {
|
||||
// Remove leading //
|
||||
pos += 2;
|
||||
}
|
||||
addSyntheticLeadingComment(targetNode, commentKind || kind, sourceFile.text.slice(pos, end), hasTrailingNewLine !== undefined ? hasTrailingNewLine : htnl);
|
||||
});
|
||||
cb(targetNode, commentKind || kind, sourceFile.text.slice(pos, end), hasTrailingNewLine !== undefined ? hasTrailingNewLine : htnl);
|
||||
};
|
||||
}
|
||||
|
||||
function indexInTextChange(change: string, name: string): number {
|
||||
@@ -1914,4 +1946,28 @@ namespace ts {
|
||||
export function getSwitchedType(caseClause: CaseClause, checker: TypeChecker): Type | undefined {
|
||||
return checker.getTypeAtLocation(caseClause.parent.parent.expression);
|
||||
}
|
||||
|
||||
export function getTypeNodeIfAccessible(type: Type, enclosingScope: Node, program: Program, host: LanguageServiceHost): TypeNode | undefined {
|
||||
const checker = program.getTypeChecker();
|
||||
let typeIsAccessible = true;
|
||||
const notAccessible = () => { typeIsAccessible = false; };
|
||||
const res = checker.typeToTypeNode(type, enclosingScope, /*flags*/ undefined, {
|
||||
trackSymbol: (symbol, declaration, meaning) => {
|
||||
// TODO: GH#18217
|
||||
typeIsAccessible = typeIsAccessible && checker.isSymbolAccessible(symbol, declaration, meaning!, /*shouldComputeAliasToMarkVisible*/ false).accessibility === SymbolAccessibility.Accessible;
|
||||
},
|
||||
reportInaccessibleThisError: notAccessible,
|
||||
reportPrivateInBaseOfClassExpression: notAccessible,
|
||||
reportInaccessibleUniqueSymbolError: notAccessible,
|
||||
moduleResolverHost: {
|
||||
readFile: host.readFile,
|
||||
fileExists: host.fileExists,
|
||||
directoryExists: host.directoryExists,
|
||||
getSourceFiles: program.getSourceFiles,
|
||||
getCurrentDirectory: program.getCurrentDirectory,
|
||||
getCommonSourceDirectory: program.getCommonSourceDirectory,
|
||||
}
|
||||
});
|
||||
return typeIsAccessible ? res : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -538,25 +538,23 @@ namespace Harness.Parallel.Host {
|
||||
|
||||
let xunitReporter: import("mocha").reporters.XUnit | undefined;
|
||||
let failedTestReporter: import("../../../scripts/failed-tests") | undefined;
|
||||
if (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser) {
|
||||
if (process.env.CI === "true") {
|
||||
xunitReporter = new Mocha.reporters.XUnit(replayRunner, {
|
||||
reporterOptions: {
|
||||
suiteName: "Tests",
|
||||
output: "./TEST-results.xml"
|
||||
}
|
||||
});
|
||||
patchStats(xunitReporter.stats);
|
||||
xunitReporter.write(`<?xml version="1.0" encoding="UTF-8"?>\n`);
|
||||
}
|
||||
else {
|
||||
failedTestReporter = new FailedTestReporter(replayRunner, {
|
||||
reporterOptions: {
|
||||
file: path.resolve(".failed-tests"),
|
||||
keepFailed
|
||||
}
|
||||
});
|
||||
}
|
||||
if (process.env.CI === "true") {
|
||||
xunitReporter = new Mocha.reporters.XUnit(replayRunner, {
|
||||
reporterOptions: {
|
||||
suiteName: "Tests",
|
||||
output: "./TEST-results.xml"
|
||||
}
|
||||
});
|
||||
patchStats(xunitReporter.stats);
|
||||
xunitReporter.write(`<?xml version="1.0" encoding="UTF-8"?>\n`);
|
||||
}
|
||||
else {
|
||||
failedTestReporter = new FailedTestReporter(replayRunner, {
|
||||
reporterOptions: {
|
||||
file: path.resolve(".failed-tests"),
|
||||
keepFailed
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const savedUseColors = Base.useColors;
|
||||
|
||||
@@ -182,10 +182,7 @@ function handleTestConfig() {
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions));
|
||||
|
||||
// TODO: project tests don"t work in the browser yet
|
||||
if (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser) {
|
||||
runners.push(new project.ProjectRunner());
|
||||
}
|
||||
runners.push(new project.ProjectRunner());
|
||||
|
||||
// language services
|
||||
runners.push(new FourSlashRunner(FourSlash.FourSlashTestType.Native));
|
||||
@@ -195,7 +192,7 @@ function handleTestConfig() {
|
||||
// runners.push(new GeneratedFourslashRunner());
|
||||
|
||||
// CRON-only tests
|
||||
if (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser && process.env.TRAVIS_EVENT_TYPE === "cron") {
|
||||
if (process.env.TRAVIS_EVENT_TYPE === "cron") {
|
||||
runners.push(new UserCodeRunner());
|
||||
}
|
||||
}
|
||||
@@ -229,13 +226,11 @@ function beginTests() {
|
||||
let isWorker: boolean;
|
||||
function startTestEnvironment() {
|
||||
isWorker = handleTestConfig();
|
||||
if (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser) {
|
||||
if (isWorker) {
|
||||
return Harness.Parallel.Worker.start();
|
||||
}
|
||||
else if (taskConfigsFolder && workerCount && workerCount > 1) {
|
||||
return Harness.Parallel.Host.start();
|
||||
}
|
||||
if (isWorker) {
|
||||
return Harness.Parallel.Worker.start();
|
||||
}
|
||||
else if (taskConfigsFolder && workerCount && workerCount > 1) {
|
||||
return Harness.Parallel.Host.start();
|
||||
}
|
||||
beginTests();
|
||||
}
|
||||
|
||||
@@ -105,6 +105,7 @@
|
||||
"unittests/tscWatch/resolutionCache.ts",
|
||||
"unittests/tscWatch/watchEnvironment.ts",
|
||||
"unittests/tscWatch/watchApi.ts",
|
||||
"unittests/tsserver/applyChangesToOpenFiles.ts",
|
||||
"unittests/tsserver/cachingFileSystemInformation.ts",
|
||||
"unittests/tsserver/cancellationToken.ts",
|
||||
"unittests/tsserver/compileOnSave.ts",
|
||||
|
||||
@@ -140,13 +140,13 @@ var z = 3; // comment 4
|
||||
deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNode2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { useNonAdjustedStartPosition: true });
|
||||
deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude });
|
||||
});
|
||||
runSingleFileTest("deleteNode3", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { useNonAdjustedEndPosition: true });
|
||||
deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude });
|
||||
});
|
||||
runSingleFileTest("deleteNode4", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true });
|
||||
deleteNode(changeTracker, sourceFile, findVariableStatementContaining("y", sourceFile), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude });
|
||||
});
|
||||
runSingleFileTest("deleteNode5", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
deleteNode(changeTracker, sourceFile, findVariableStatementContaining("x", sourceFile));
|
||||
@@ -167,15 +167,15 @@ var a = 4; // comment 7
|
||||
});
|
||||
runSingleFileTest("deleteNodeRange2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile),
|
||||
{ useNonAdjustedStartPosition: true });
|
||||
{ leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude });
|
||||
});
|
||||
runSingleFileTest("deleteNodeRange3", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile),
|
||||
{ useNonAdjustedEndPosition: true });
|
||||
{ trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude });
|
||||
});
|
||||
runSingleFileTest("deleteNodeRange4", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile),
|
||||
{ useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true });
|
||||
{ leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude });
|
||||
});
|
||||
}
|
||||
function createTestVariableDeclaration(name: string) {
|
||||
@@ -254,16 +254,16 @@ var a = 4; // comment 7`;
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNode2", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, suffix: newLineCharacter, prefix: newLineCharacter });
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, suffix: newLineCharacter, prefix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNode3", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedEndPosition: true, suffix: newLineCharacter });
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude, suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNode4", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true });
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude });
|
||||
});
|
||||
runSingleFileTest("replaceNode5", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("x", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true });
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("x", sourceFile), createTestClass(), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude });
|
||||
});
|
||||
}
|
||||
{
|
||||
@@ -279,13 +279,13 @@ var a = 4; // comment 7`;
|
||||
changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNodeRange2", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, suffix: newLineCharacter, prefix: newLineCharacter });
|
||||
changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, suffix: newLineCharacter, prefix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNodeRange3", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedEndPosition: true, suffix: newLineCharacter });
|
||||
changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude, suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNodeRange4", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true });
|
||||
changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude });
|
||||
});
|
||||
}
|
||||
{
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
namespace ts.projectSystem {
|
||||
describe("unittests:: tsserver:: applyChangesToOpenFiles", () => {
|
||||
const configFile: File = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: "{}"
|
||||
};
|
||||
const file3: File = {
|
||||
path: "/a/b/file3.ts",
|
||||
content: "let xyz = 1;"
|
||||
};
|
||||
const app: File = {
|
||||
path: "/a/b/app.ts",
|
||||
content: "let z = 1;"
|
||||
};
|
||||
|
||||
function fileContentWithComment(file: File) {
|
||||
return `// some copy right notice
|
||||
${file.content}`;
|
||||
}
|
||||
|
||||
function verifyText(service: server.ProjectService, file: string, expected: string) {
|
||||
const info = service.getScriptInfo(file)!;
|
||||
const snap = info.getSnapshot();
|
||||
// Verified applied in reverse order
|
||||
assert.equal(snap.getText(0, snap.getLength()), expected, `Text of changed file: ${file}`);
|
||||
}
|
||||
|
||||
function verifyProjectVersion(project: server.Project, expected: number) {
|
||||
assert.equal(Number(project.getProjectVersion()), expected);
|
||||
}
|
||||
|
||||
function verify(applyChangesToOpen: (session: TestSession) => void) {
|
||||
const host = createServerHost([app, file3, commonFile1, commonFile2, libFile, configFile]);
|
||||
const session = createSession(host);
|
||||
session.executeCommandSeq<protocol.OpenRequest>({
|
||||
command: protocol.CommandTypes.Open,
|
||||
arguments: { file: app.path }
|
||||
});
|
||||
const service = session.getProjectService();
|
||||
const project = service.configuredProjects.get(configFile.path)!;
|
||||
assert.isDefined(project);
|
||||
verifyProjectVersion(project, 1);
|
||||
session.executeCommandSeq<protocol.OpenRequest>({
|
||||
command: protocol.CommandTypes.Open,
|
||||
arguments: {
|
||||
file: file3.path,
|
||||
fileContent: fileContentWithComment(file3)
|
||||
}
|
||||
});
|
||||
verifyProjectVersion(project, 2);
|
||||
|
||||
// Verify Texts
|
||||
verifyText(service, commonFile1.path, commonFile1.content);
|
||||
verifyText(service, commonFile2.path, commonFile2.content);
|
||||
verifyText(service, app.path, app.content);
|
||||
verifyText(service, file3.path, fileContentWithComment(file3));
|
||||
|
||||
// Apply changes
|
||||
applyChangesToOpen(session);
|
||||
|
||||
// Verify again
|
||||
verifyProjectVersion(project, 3);
|
||||
// Open file contents
|
||||
verifyText(service, commonFile1.path, fileContentWithComment(commonFile1));
|
||||
verifyText(service, commonFile2.path, fileContentWithComment(commonFile2));
|
||||
verifyText(service, app.path, "let zzz = 10;let zz = 10;let z = 1;");
|
||||
verifyText(service, file3.path, file3.content);
|
||||
}
|
||||
|
||||
it("with applyChangedToOpenFiles request", () => {
|
||||
verify(session =>
|
||||
session.executeCommandSeq<protocol.ApplyChangedToOpenFilesRequest>({
|
||||
command: protocol.CommandTypes.ApplyChangedToOpenFiles,
|
||||
arguments: {
|
||||
openFiles: [
|
||||
{
|
||||
fileName: commonFile1.path,
|
||||
content: fileContentWithComment(commonFile1)
|
||||
},
|
||||
{
|
||||
fileName: commonFile2.path,
|
||||
content: fileContentWithComment(commonFile2)
|
||||
}
|
||||
],
|
||||
changedFiles: [
|
||||
{
|
||||
fileName: app.path,
|
||||
changes: [
|
||||
{
|
||||
span: { start: 0, length: 0 },
|
||||
newText: "let zzz = 10;"
|
||||
},
|
||||
{
|
||||
span: { start: 0, length: 0 },
|
||||
newText: "let zz = 10;"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
closedFiles: [
|
||||
file3.path
|
||||
]
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it("with updateOpen request", () => {
|
||||
verify(session =>
|
||||
session.executeCommandSeq<protocol.UpdateOpenRequest>({
|
||||
command: protocol.CommandTypes.UpdateOpen,
|
||||
arguments: {
|
||||
openFiles: [
|
||||
{
|
||||
file: commonFile1.path,
|
||||
fileContent: fileContentWithComment(commonFile1)
|
||||
},
|
||||
{
|
||||
file: commonFile2.path,
|
||||
fileContent: fileContentWithComment(commonFile2)
|
||||
}
|
||||
],
|
||||
changedFiles: [
|
||||
{
|
||||
fileName: app.path,
|
||||
textChanges: [
|
||||
{
|
||||
start: { line: 1, offset: 1 },
|
||||
end: { line: 1, offset: 1 },
|
||||
newText: "let zzz = 10;",
|
||||
},
|
||||
{
|
||||
start: { line: 1, offset: 1 },
|
||||
end: { line: 1, offset: 1 },
|
||||
newText: "let zz = 10;",
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
closedFiles: [
|
||||
file3.path
|
||||
]
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -41,13 +41,13 @@ namespace ts.projectSystem {
|
||||
|
||||
function changeFileToNotImportModule(service: TestProjectService) {
|
||||
const info = service.getScriptInfo(file.path)!;
|
||||
service.applyChangesToFile(info, [{ span: { start: 0, length: importModuleContent.length }, newText: "" }]);
|
||||
service.applyChangesToFile(info, singleIterator({ span: { start: 0, length: importModuleContent.length }, newText: "" }));
|
||||
checkProject(service, /*moduleIsOrphan*/ true);
|
||||
}
|
||||
|
||||
function changeFileToImportModule(service: TestProjectService) {
|
||||
const info = service.getScriptInfo(file.path)!;
|
||||
service.applyChangesToFile(info, [{ span: { start: 0, length: 0 }, newText: importModuleContent }]);
|
||||
service.applyChangesToFile(info, singleIterator({ span: { start: 0, length: 0 }, newText: importModuleContent }));
|
||||
checkProject(service, /*moduleIsOrphan*/ false);
|
||||
}
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ namespace ts.projectSystem {
|
||||
checkNumberOfInferredProjects(projectService, 0);
|
||||
|
||||
externalFiles[0].content = "let x =1;";
|
||||
projectService.applyChangesInOpenFiles(externalFiles, [], []);
|
||||
projectService.applyChangesInOpenFiles(arrayIterator(externalFiles));
|
||||
});
|
||||
|
||||
it("external project that included config files", () => {
|
||||
@@ -790,9 +790,7 @@ namespace ts.projectSystem {
|
||||
rootFiles: [{ fileName: tsconfig.path }, { fileName: jsFilePath }],
|
||||
options: { allowJs: false }
|
||||
}]);
|
||||
service.applyChangesInOpenFiles([
|
||||
{ fileName: jsFilePath, scriptKind: ScriptKind.JS, content: "" }
|
||||
], /*changedFiles*/ undefined, /*closedFiles*/ undefined);
|
||||
service.applyChangesInOpenFiles(singleIterator({ fileName: jsFilePath, scriptKind: ScriptKind.JS, content: "" }));
|
||||
checkNumberOfProjects(service, { configuredProjects: 1, inferredProjects: 1 });
|
||||
checkProjectActualFiles(configProject, [tsconfig.path]);
|
||||
const inferredProject = service.inferredProjects[0];
|
||||
|
||||
@@ -202,7 +202,7 @@ namespace ts.projectSystem {
|
||||
|
||||
const host = createServerHost([file1, config1]);
|
||||
const projectService = createProjectService(host, { useSingleInferredProject: true }, { syntaxOnly: true });
|
||||
projectService.applyChangesInOpenFiles([{ fileName: file1.path, content: file1.content }], [], []);
|
||||
projectService.applyChangesInOpenFiles(singleIterator({ fileName: file1.path, content: file1.content }));
|
||||
|
||||
checkNumberOfProjects(projectService, { inferredProjects: 1 });
|
||||
const proj = projectService.inferredProjects[0];
|
||||
@@ -588,11 +588,11 @@ namespace ts.projectSystem {
|
||||
|
||||
const host = createServerHost([]);
|
||||
const projectService = createProjectService(host);
|
||||
projectService.applyChangesInOpenFiles([tsFile], [], []);
|
||||
projectService.applyChangesInOpenFiles(singleIterator(tsFile));
|
||||
const projs = projectService.synchronizeProjectList([]);
|
||||
projectService.findProject(projs[0].info!.projectName)!.getLanguageService().getNavigationBarItems(tsFile.fileName);
|
||||
projectService.synchronizeProjectList([projs[0].info!]);
|
||||
projectService.applyChangesInOpenFiles([jsFile], [], []);
|
||||
projectService.applyChangesInOpenFiles(singleIterator(jsFile));
|
||||
});
|
||||
|
||||
it("config file is deleted", () => {
|
||||
@@ -696,11 +696,12 @@ namespace ts.projectSystem {
|
||||
checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]);
|
||||
|
||||
// Open HTML file
|
||||
projectService.applyChangesInOpenFiles(
|
||||
/*openFiles*/[{ fileName: file2.path, hasMixedContent: true, scriptKind: ScriptKind.JS, content: `var hello = "hello";` }],
|
||||
/*changedFiles*/ undefined,
|
||||
/*closedFiles*/ undefined);
|
||||
|
||||
projectService.applyChangesInOpenFiles(singleIterator({
|
||||
fileName: file2.path,
|
||||
hasMixedContent: true,
|
||||
scriptKind: ScriptKind.JS,
|
||||
content: `var hello = "hello";`
|
||||
}));
|
||||
// Now HTML file is included in the project
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]);
|
||||
@@ -853,7 +854,7 @@ namespace ts.projectSystem {
|
||||
checkNumberOfProjects(projectService, { inferredProjects: 1 });
|
||||
projectService.applyChangesInOpenFiles(
|
||||
/*openFiles*/ undefined,
|
||||
/*changedFiles*/[{ fileName: file1.path, changes: [{ span: createTextSpan(0, file1.path.length), newText: "let y = 1" }] }],
|
||||
/*changedFiles*/singleIterator({ fileName: file1.path, changes: singleIterator({ span: createTextSpan(0, file1.path.length), newText: "let y = 1" }) }),
|
||||
/*closedFiles*/ undefined);
|
||||
|
||||
checkNumberOfProjects(projectService, { inferredProjects: 1 });
|
||||
|
||||
@@ -132,4 +132,79 @@ namespace ts.projectSystem {
|
||||
verifyRootedDirectoryWatch("c:/users/username/");
|
||||
});
|
||||
});
|
||||
|
||||
it(`unittests:: tsserver:: watchEnvironment:: tsserverProjectSystem recursive watch directory implementation does not watch files/directories in node_modules starting with "."`, () => {
|
||||
const projectFolder = "/a/username/project";
|
||||
const projectSrcFolder = `${projectFolder}/src`;
|
||||
const configFile: File = {
|
||||
path: `${projectFolder}/tsconfig.json`,
|
||||
content: "{}"
|
||||
};
|
||||
const index: File = {
|
||||
path: `${projectSrcFolder}/index.ts`,
|
||||
content: `import {} from "file"`
|
||||
};
|
||||
const file1: File = {
|
||||
path: `${projectSrcFolder}/file1.ts`,
|
||||
content: ""
|
||||
};
|
||||
const nodeModulesExistingUnusedFile: File = {
|
||||
path: `${projectFolder}/node_modules/someFile.d.ts`,
|
||||
content: ""
|
||||
};
|
||||
|
||||
const fileNames = [index, file1, configFile, libFile].map(file => file.path);
|
||||
// All closed files(files other than index), project folder, project/src folder and project/node_modules/@types folder
|
||||
const expectedWatchedFiles = arrayToMap(fileNames.slice(1), identity, () => 1);
|
||||
const expectedWatchedDirectories = arrayToMap([projectFolder, projectSrcFolder, `${projectFolder}/${nodeModules}`, `${projectFolder}/${nodeModulesAtTypes}`], identity, () => 1);
|
||||
|
||||
const environmentVariables = createMap<string>();
|
||||
environmentVariables.set("TSC_WATCHDIRECTORY", Tsc_WatchDirectory.NonRecursiveWatchDirectory);
|
||||
const host = createServerHost([index, file1, configFile, libFile, nodeModulesExistingUnusedFile], { environmentVariables });
|
||||
const projectService = createProjectService(host);
|
||||
projectService.openClientFile(index.path);
|
||||
|
||||
const project = Debug.assertDefined(projectService.configuredProjects.get(configFile.path));
|
||||
verifyProject();
|
||||
|
||||
const nodeModulesIgnoredFileFromIgnoreDirectory: File = {
|
||||
path: `${projectFolder}/node_modules/.cache/someFile.d.ts`,
|
||||
content: ""
|
||||
};
|
||||
host.ensureFileOrFolder(nodeModulesIgnoredFileFromIgnoreDirectory);
|
||||
host.checkTimeoutQueueLength(0);
|
||||
verifyProject();
|
||||
|
||||
const nodeModulesIgnoredFile: File = {
|
||||
path: `${projectFolder}/node_modules/.cacheFile.ts`,
|
||||
content: ""
|
||||
};
|
||||
host.ensureFileOrFolder(nodeModulesIgnoredFile);
|
||||
host.checkTimeoutQueueLength(0);
|
||||
verifyProject();
|
||||
|
||||
const gitIgnoredFileFromIgnoreDirectory: File = {
|
||||
path: `${projectFolder}/.git/someFile.d.ts`,
|
||||
content: ""
|
||||
};
|
||||
host.ensureFileOrFolder(gitIgnoredFileFromIgnoreDirectory);
|
||||
host.checkTimeoutQueueLength(0);
|
||||
verifyProject();
|
||||
|
||||
const gitIgnoredFile: File = {
|
||||
path: `${projectFolder}/.gitCache.d.ts`,
|
||||
content: ""
|
||||
};
|
||||
host.ensureFileOrFolder(gitIgnoredFile);
|
||||
host.checkTimeoutQueueLength(0);
|
||||
verifyProject();
|
||||
|
||||
function verifyProject() {
|
||||
checkWatchedDirectories(host, emptyArray, /*recursive*/ true);
|
||||
checkWatchedFilesDetailed(host, expectedWatchedFiles);
|
||||
checkWatchedDirectoriesDetailed(host, expectedWatchedDirectories, /*recursive*/ false);
|
||||
checkProjectActualFiles(project, fileNames);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -5769,6 +5769,7 @@ declare namespace ts.server.protocol {
|
||||
OpenExternalProject = "openExternalProject",
|
||||
OpenExternalProjects = "openExternalProjects",
|
||||
CloseExternalProject = "closeExternalProject",
|
||||
UpdateOpen = "updateOpen",
|
||||
GetOutliningSpans = "getOutliningSpans",
|
||||
TodoComments = "todoComments",
|
||||
Indentation = "indentation",
|
||||
@@ -6837,6 +6838,30 @@ declare namespace ts.server.protocol {
|
||||
*/
|
||||
interface CloseExternalProjectResponse extends Response {
|
||||
}
|
||||
/**
|
||||
* Request to synchronize list of open files with the client
|
||||
*/
|
||||
interface UpdateOpenRequest extends Request {
|
||||
command: CommandTypes.UpdateOpen;
|
||||
arguments: UpdateOpenRequestArgs;
|
||||
}
|
||||
/**
|
||||
* Arguments to UpdateOpenRequest
|
||||
*/
|
||||
interface UpdateOpenRequestArgs {
|
||||
/**
|
||||
* List of newly open files
|
||||
*/
|
||||
openFiles?: OpenRequestArgs[];
|
||||
/**
|
||||
* List of open files files that were changes
|
||||
*/
|
||||
changedFiles?: FileCodeEdits[];
|
||||
/**
|
||||
* List of files that were closed
|
||||
*/
|
||||
closedFiles?: string[];
|
||||
}
|
||||
/**
|
||||
* Request to set compiler options for inferred projects.
|
||||
* External projects are opened / closed explicitly.
|
||||
@@ -8676,6 +8701,7 @@ declare namespace ts.server {
|
||||
*/
|
||||
private onConfigFileChangeForOpenScriptInfo;
|
||||
private removeProject;
|
||||
private assignOrphanScriptInfosToInferredProject;
|
||||
/**
|
||||
* Remove this file from the set of open, non-configured files.
|
||||
* @param info The file that has been closed or newly configured
|
||||
@@ -8794,6 +8820,9 @@ declare namespace ts.server {
|
||||
*/
|
||||
openClientFile(fileName: string, fileContent?: string, scriptKind?: ScriptKind, projectRootPath?: string): OpenConfiguredProjectResult;
|
||||
private findExternalProjectContainingOpenScriptInfo;
|
||||
private getOrCreateOpenScriptInfo;
|
||||
private assignProjectToOpenedScriptInfo;
|
||||
private cleanupAfterOpeningFile;
|
||||
openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult;
|
||||
private removeOrphanConfiguredProjects;
|
||||
private removeOrphanScriptInfos;
|
||||
|
||||
@@ -15,8 +15,8 @@ var e = <K>(x: string, y?: K) => x.length;
|
||||
>length : number
|
||||
|
||||
var r99 = map(e); // should be {}[] for S since a generic lambda is not inferentially typed
|
||||
>r99 : (a: {}[]) => number[]
|
||||
>map(e) : (a: {}[]) => number[]
|
||||
>r99 : <K>(a: string[]) => number[]
|
||||
>map(e) : <K>(a: string[]) => number[]
|
||||
>map : <S, T>(f: (x: S) => T) => (a: S[]) => T[]
|
||||
>e : <K>(x: string, y?: K) => number
|
||||
|
||||
@@ -37,8 +37,8 @@ var e2 = <K>(x: string, y?: K) => x.length;
|
||||
>length : number
|
||||
|
||||
var r100 = map2(e2); // type arg inference should fail for S since a generic lambda is not inferentially typed. Falls back to { length: number }
|
||||
>r100 : (a: { length: number; }[]) => number[]
|
||||
>map2(e2) : (a: { length: number; }[]) => number[]
|
||||
>r100 : <K>(a: string[]) => number[]
|
||||
>map2(e2) : <K>(a: string[]) => number[]
|
||||
>map2 : <S extends { length: number; }, T>(f: (x: S) => T) => (a: S[]) => T[]
|
||||
>e2 : <K>(x: string, y?: K) => number
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@ var id: <T>(x:T) => T;
|
||||
>x : T
|
||||
|
||||
var r23 = dot(id)(id);
|
||||
>r23 : (_: {}) => {}
|
||||
>dot(id)(id) : (_: {}) => {}
|
||||
>r23 : <T>(_: T) => {}
|
||||
>dot(id)(id) : <T>(_: T) => {}
|
||||
>dot(id) : <U>(g: (_: U) => {}) => (_: U) => {}
|
||||
>dot : <T, S>(f: (_: T) => S) => <U>(g: (_: U) => T) => (_: U) => S
|
||||
>id : <T>(x: T) => T
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/FromFactor.ts(2,15): error TS2304: Cannot find name 'StringKeyOf'.
|
||||
/FromFactor.ts(2,15): error TS4103: Type parameter 'TName' of exported mapped object type is using private name 'StringKeyOf'.
|
||||
|
||||
|
||||
==== /Helpers.ts (0 errors) ====
|
||||
export type StringKeyOf<TObj> = Extract<string, keyof TObj>;
|
||||
|
||||
==== /FromFactor.ts (2 errors) ====
|
||||
export type RowToColumns<TColumns> = {
|
||||
[TName in StringKeyOf<TColumns>]: any;
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'StringKeyOf'.
|
||||
~~~~~~~~~~~
|
||||
!!! error TS4103: Type parameter 'TName' of exported mapped object type is using private name 'StringKeyOf'.
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
//// [tests/cases/compiler/declarationEmitMappedPrivateTypeTypeParameter.ts] ////
|
||||
|
||||
//// [Helpers.ts]
|
||||
export type StringKeyOf<TObj> = Extract<string, keyof TObj>;
|
||||
|
||||
//// [FromFactor.ts]
|
||||
export type RowToColumns<TColumns> = {
|
||||
[TName in StringKeyOf<TColumns>]: any;
|
||||
}
|
||||
|
||||
//// [Helpers.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
//// [FromFactor.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
|
||||
|
||||
//// [Helpers.d.ts]
|
||||
export declare type StringKeyOf<TObj> = Extract<string, keyof TObj>;
|
||||
@@ -0,0 +1,16 @@
|
||||
=== /Helpers.ts ===
|
||||
export type StringKeyOf<TObj> = Extract<string, keyof TObj>;
|
||||
>StringKeyOf : Symbol(StringKeyOf, Decl(Helpers.ts, 0, 0))
|
||||
>TObj : Symbol(TObj, Decl(Helpers.ts, 0, 24))
|
||||
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
|
||||
>TObj : Symbol(TObj, Decl(Helpers.ts, 0, 24))
|
||||
|
||||
=== /FromFactor.ts ===
|
||||
export type RowToColumns<TColumns> = {
|
||||
>RowToColumns : Symbol(RowToColumns, Decl(FromFactor.ts, 0, 0))
|
||||
>TColumns : Symbol(TColumns, Decl(FromFactor.ts, 0, 25))
|
||||
|
||||
[TName in StringKeyOf<TColumns>]: any;
|
||||
>TName : Symbol(TName, Decl(FromFactor.ts, 1, 5))
|
||||
>TColumns : Symbol(TColumns, Decl(FromFactor.ts, 0, 25))
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
=== /Helpers.ts ===
|
||||
export type StringKeyOf<TObj> = Extract<string, keyof TObj>;
|
||||
>StringKeyOf : Extract<string, keyof TObj>
|
||||
|
||||
=== /FromFactor.ts ===
|
||||
export type RowToColumns<TColumns> = {
|
||||
>RowToColumns : RowToColumns<TColumns>
|
||||
|
||||
[TName in StringKeyOf<TColumns>]: any;
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
tests/cases/compiler/genericFunctionInference1.ts(83,14): error TS2345: Argument of type '<a>(value: { key: a; }) => a' is not assignable to parameter of type '(value: Data) => string'.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/genericFunctionInference1.ts (1 errors) ====
|
||||
declare function pipe<A extends any[], B>(ab: (...args: A) => B): (...args: A) => B;
|
||||
declare function pipe<A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C;
|
||||
declare function pipe<A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D;
|
||||
|
||||
declare function list<T>(a: T): T[];
|
||||
declare function box<V>(x: V): { value: V };
|
||||
declare function foo<T extends { value: T }>(x: T): T;
|
||||
|
||||
const f00 = pipe(list);
|
||||
const f01 = pipe(list, box);
|
||||
const f02 = pipe(box, list);
|
||||
const f03 = pipe(x => list(x), box);
|
||||
const f04 = pipe(list, x => box(x));
|
||||
const f05 = pipe(x => list(x), x => box(x))
|
||||
const f06 = pipe(list, pipe(box));
|
||||
const f07 = pipe(x => list(x), pipe(box));
|
||||
const f08 = pipe(x => list(x), pipe(x => box(x)));
|
||||
const f09 = pipe(list, x => x.length);
|
||||
const f10 = pipe(foo);
|
||||
const f11 = pipe(foo, foo);
|
||||
|
||||
const g00: <T>(x: T) => T[] = pipe(list);
|
||||
const g01: <T>(x: T) => { value: T[] } = pipe(list, box);
|
||||
const g02: <T>(x: T) => { value: T }[] = pipe(box, list);
|
||||
const g03: <T>(x: T) => { value: T[] } = pipe(x => list(x), box);
|
||||
const g04: <T>(x: T) => { value: T[] } = pipe(list, x => box(x));
|
||||
const g05: <T>(x: T) => { value: T[] } = pipe(x => list(x), x => box(x))
|
||||
const g06: <T>(x: T) => { value: T[] } = pipe(list, pipe(box));
|
||||
const g07: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(box));
|
||||
const g08: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(x => box(x)));
|
||||
const g09: <T>(x: T) => number = pipe(list, x => x.length);
|
||||
const g10: <T extends { value: T }>(x: T) => T = pipe(foo);
|
||||
const g12: <T extends { value: T }>(x: T) => T = pipe(foo, foo);
|
||||
|
||||
declare function pipe2<A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D): (a: [A, C]) => [B, D];
|
||||
|
||||
const f20 = pipe2(list, box);
|
||||
const f21 = pipe2(box, list);
|
||||
const f22 = pipe2(list, list);
|
||||
const f23 = pipe2(box, box);
|
||||
const f24 = pipe2(f20, f20);
|
||||
const f25 = pipe2(foo, foo);
|
||||
const f26 = pipe2(f25, f25);
|
||||
|
||||
declare function pipe3<A, B, C>(ab: (a: A) => B, ac: (a: A) => C): (a: A) => [B, C];
|
||||
|
||||
const f30 = pipe3(list, box);
|
||||
const f31 = pipe3(box, list);
|
||||
const f32 = pipe3(list, list);
|
||||
|
||||
declare function pipe4<A, B, C>(funcs: [(a: A) => B, (b: B) => C]): (a: A) => C;
|
||||
|
||||
const f40 = pipe4([list, box]);
|
||||
const f41 = pipe4([box, list]);
|
||||
|
||||
declare function pipe5<A, B>(f: (a: A) => B): { f: (a: A) => B };
|
||||
|
||||
const f50 = pipe5(list); // No higher order inference
|
||||
|
||||
// #417
|
||||
|
||||
function mirror<A, B>(f: (a: A) => B): (a: A) => B { return f; }
|
||||
var identityM = mirror(identity);
|
||||
|
||||
var x = 1;
|
||||
var y = identity(x);
|
||||
var z = identityM(x);
|
||||
|
||||
// #3038
|
||||
|
||||
export function keyOf<a>(value: { key: a; }): a {
|
||||
return value.key;
|
||||
}
|
||||
export interface Data {
|
||||
key: number;
|
||||
value: Date;
|
||||
}
|
||||
|
||||
var data: Data[] = [];
|
||||
|
||||
declare function toKeys<a>(values: a[], toKey: (value: a) => string): string[];
|
||||
|
||||
toKeys(data, keyOf); // Error
|
||||
~~~~~
|
||||
!!! error TS2345: Argument of type '<a>(value: { key: a; }) => a' is not assignable to parameter of type '(value: Data) => string'.
|
||||
!!! error TS2345: Type 'number' is not assignable to type 'string'.
|
||||
|
||||
// #9366
|
||||
|
||||
function flip<a, b, c>(f: (a: a, b: b) => c): (b: b, a: a) => c {
|
||||
return (b: b, a: a) => f(a, b);
|
||||
}
|
||||
function zip<T, U>(x: T, y: U): [T, U] {
|
||||
return [x, y];
|
||||
}
|
||||
|
||||
var expected: <T, U>(y: U, x: T) => [T, U] = flip(zip);
|
||||
var actual = flip(zip);
|
||||
|
||||
// #9366
|
||||
|
||||
const map = <T, U>(transform: (t: T) => U) =>
|
||||
(arr: T[]) => arr.map(transform)
|
||||
|
||||
const identityStr = (t: string) => t;
|
||||
|
||||
const arr: string[] = map(identityStr)(['a']);
|
||||
const arr1: string[] = map(identity)(['a']);
|
||||
|
||||
// #9949
|
||||
|
||||
function of2<a, b>(one: a, two: b): [a, b] {
|
||||
return [one, two];
|
||||
}
|
||||
|
||||
const flipped = flip(of2);
|
||||
|
||||
// #29904.1
|
||||
|
||||
type Component<P> = (props: P) => {};
|
||||
|
||||
declare const myHoc1: <P>(C: Component<P>) => Component<P>;
|
||||
declare const myHoc2: <P>(C: Component<P>) => Component<P>;
|
||||
|
||||
declare const MyComponent1: Component<{ foo: 1 }>;
|
||||
|
||||
const enhance = pipe(
|
||||
myHoc1,
|
||||
myHoc2,
|
||||
);
|
||||
|
||||
const MyComponent2 = enhance(MyComponent1);
|
||||
|
||||
// #29904.2
|
||||
|
||||
const fn20 = pipe((_a?: {}) => 1);
|
||||
|
||||
// #29904.3
|
||||
|
||||
type Fn = (n: number) => number;
|
||||
const fn30: Fn = pipe(
|
||||
x => x + 1,
|
||||
x => x * 2,
|
||||
);
|
||||
|
||||
const promise = Promise.resolve(1);
|
||||
promise.then(
|
||||
pipe(
|
||||
x => x + 1,
|
||||
x => x * 2,
|
||||
),
|
||||
);
|
||||
|
||||
// #29904.4
|
||||
|
||||
declare const getString: () => string;
|
||||
declare const orUndefined: (name: string) => string | undefined;
|
||||
declare const identity: <T>(value: T) => T;
|
||||
|
||||
const fn40 = pipe(
|
||||
getString,
|
||||
string => orUndefined(string),
|
||||
identity,
|
||||
);
|
||||
|
||||
// #29904.6
|
||||
|
||||
declare const getArray: () => string[];
|
||||
declare const first: <T>(ts: T[]) => T;
|
||||
|
||||
const fn60 = pipe(
|
||||
getArray,
|
||||
x => x,
|
||||
first,
|
||||
);
|
||||
|
||||
const fn61 = pipe(
|
||||
getArray,
|
||||
identity,
|
||||
first,
|
||||
);
|
||||
|
||||
const fn62 = pipe(
|
||||
getArray,
|
||||
x => x,
|
||||
x => first(x),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
//// [genericFunctionInference1.ts]
|
||||
declare function pipe<A extends any[], B>(ab: (...args: A) => B): (...args: A) => B;
|
||||
declare function pipe<A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C;
|
||||
declare function pipe<A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D;
|
||||
|
||||
declare function list<T>(a: T): T[];
|
||||
declare function box<V>(x: V): { value: V };
|
||||
declare function foo<T extends { value: T }>(x: T): T;
|
||||
|
||||
const f00 = pipe(list);
|
||||
const f01 = pipe(list, box);
|
||||
const f02 = pipe(box, list);
|
||||
const f03 = pipe(x => list(x), box);
|
||||
const f04 = pipe(list, x => box(x));
|
||||
const f05 = pipe(x => list(x), x => box(x))
|
||||
const f06 = pipe(list, pipe(box));
|
||||
const f07 = pipe(x => list(x), pipe(box));
|
||||
const f08 = pipe(x => list(x), pipe(x => box(x)));
|
||||
const f09 = pipe(list, x => x.length);
|
||||
const f10 = pipe(foo);
|
||||
const f11 = pipe(foo, foo);
|
||||
|
||||
const g00: <T>(x: T) => T[] = pipe(list);
|
||||
const g01: <T>(x: T) => { value: T[] } = pipe(list, box);
|
||||
const g02: <T>(x: T) => { value: T }[] = pipe(box, list);
|
||||
const g03: <T>(x: T) => { value: T[] } = pipe(x => list(x), box);
|
||||
const g04: <T>(x: T) => { value: T[] } = pipe(list, x => box(x));
|
||||
const g05: <T>(x: T) => { value: T[] } = pipe(x => list(x), x => box(x))
|
||||
const g06: <T>(x: T) => { value: T[] } = pipe(list, pipe(box));
|
||||
const g07: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(box));
|
||||
const g08: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(x => box(x)));
|
||||
const g09: <T>(x: T) => number = pipe(list, x => x.length);
|
||||
const g10: <T extends { value: T }>(x: T) => T = pipe(foo);
|
||||
const g12: <T extends { value: T }>(x: T) => T = pipe(foo, foo);
|
||||
|
||||
declare function pipe2<A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D): (a: [A, C]) => [B, D];
|
||||
|
||||
const f20 = pipe2(list, box);
|
||||
const f21 = pipe2(box, list);
|
||||
const f22 = pipe2(list, list);
|
||||
const f23 = pipe2(box, box);
|
||||
const f24 = pipe2(f20, f20);
|
||||
const f25 = pipe2(foo, foo);
|
||||
const f26 = pipe2(f25, f25);
|
||||
|
||||
declare function pipe3<A, B, C>(ab: (a: A) => B, ac: (a: A) => C): (a: A) => [B, C];
|
||||
|
||||
const f30 = pipe3(list, box);
|
||||
const f31 = pipe3(box, list);
|
||||
const f32 = pipe3(list, list);
|
||||
|
||||
declare function pipe4<A, B, C>(funcs: [(a: A) => B, (b: B) => C]): (a: A) => C;
|
||||
|
||||
const f40 = pipe4([list, box]);
|
||||
const f41 = pipe4([box, list]);
|
||||
|
||||
declare function pipe5<A, B>(f: (a: A) => B): { f: (a: A) => B };
|
||||
|
||||
const f50 = pipe5(list); // No higher order inference
|
||||
|
||||
// #417
|
||||
|
||||
function mirror<A, B>(f: (a: A) => B): (a: A) => B { return f; }
|
||||
var identityM = mirror(identity);
|
||||
|
||||
var x = 1;
|
||||
var y = identity(x);
|
||||
var z = identityM(x);
|
||||
|
||||
// #3038
|
||||
|
||||
export function keyOf<a>(value: { key: a; }): a {
|
||||
return value.key;
|
||||
}
|
||||
export interface Data {
|
||||
key: number;
|
||||
value: Date;
|
||||
}
|
||||
|
||||
var data: Data[] = [];
|
||||
|
||||
declare function toKeys<a>(values: a[], toKey: (value: a) => string): string[];
|
||||
|
||||
toKeys(data, keyOf); // Error
|
||||
|
||||
// #9366
|
||||
|
||||
function flip<a, b, c>(f: (a: a, b: b) => c): (b: b, a: a) => c {
|
||||
return (b: b, a: a) => f(a, b);
|
||||
}
|
||||
function zip<T, U>(x: T, y: U): [T, U] {
|
||||
return [x, y];
|
||||
}
|
||||
|
||||
var expected: <T, U>(y: U, x: T) => [T, U] = flip(zip);
|
||||
var actual = flip(zip);
|
||||
|
||||
// #9366
|
||||
|
||||
const map = <T, U>(transform: (t: T) => U) =>
|
||||
(arr: T[]) => arr.map(transform)
|
||||
|
||||
const identityStr = (t: string) => t;
|
||||
|
||||
const arr: string[] = map(identityStr)(['a']);
|
||||
const arr1: string[] = map(identity)(['a']);
|
||||
|
||||
// #9949
|
||||
|
||||
function of2<a, b>(one: a, two: b): [a, b] {
|
||||
return [one, two];
|
||||
}
|
||||
|
||||
const flipped = flip(of2);
|
||||
|
||||
// #29904.1
|
||||
|
||||
type Component<P> = (props: P) => {};
|
||||
|
||||
declare const myHoc1: <P>(C: Component<P>) => Component<P>;
|
||||
declare const myHoc2: <P>(C: Component<P>) => Component<P>;
|
||||
|
||||
declare const MyComponent1: Component<{ foo: 1 }>;
|
||||
|
||||
const enhance = pipe(
|
||||
myHoc1,
|
||||
myHoc2,
|
||||
);
|
||||
|
||||
const MyComponent2 = enhance(MyComponent1);
|
||||
|
||||
// #29904.2
|
||||
|
||||
const fn20 = pipe((_a?: {}) => 1);
|
||||
|
||||
// #29904.3
|
||||
|
||||
type Fn = (n: number) => number;
|
||||
const fn30: Fn = pipe(
|
||||
x => x + 1,
|
||||
x => x * 2,
|
||||
);
|
||||
|
||||
const promise = Promise.resolve(1);
|
||||
promise.then(
|
||||
pipe(
|
||||
x => x + 1,
|
||||
x => x * 2,
|
||||
),
|
||||
);
|
||||
|
||||
// #29904.4
|
||||
|
||||
declare const getString: () => string;
|
||||
declare const orUndefined: (name: string) => string | undefined;
|
||||
declare const identity: <T>(value: T) => T;
|
||||
|
||||
const fn40 = pipe(
|
||||
getString,
|
||||
string => orUndefined(string),
|
||||
identity,
|
||||
);
|
||||
|
||||
// #29904.6
|
||||
|
||||
declare const getArray: () => string[];
|
||||
declare const first: <T>(ts: T[]) => T;
|
||||
|
||||
const fn60 = pipe(
|
||||
getArray,
|
||||
x => x,
|
||||
first,
|
||||
);
|
||||
|
||||
const fn61 = pipe(
|
||||
getArray,
|
||||
identity,
|
||||
first,
|
||||
);
|
||||
|
||||
const fn62 = pipe(
|
||||
getArray,
|
||||
x => x,
|
||||
x => first(x),
|
||||
);
|
||||
|
||||
|
||||
//// [genericFunctionInference1.js]
|
||||
const f00 = pipe(list);
|
||||
const f01 = pipe(list, box);
|
||||
const f02 = pipe(box, list);
|
||||
const f03 = pipe(x => list(x), box);
|
||||
const f04 = pipe(list, x => box(x));
|
||||
const f05 = pipe(x => list(x), x => box(x));
|
||||
const f06 = pipe(list, pipe(box));
|
||||
const f07 = pipe(x => list(x), pipe(box));
|
||||
const f08 = pipe(x => list(x), pipe(x => box(x)));
|
||||
const f09 = pipe(list, x => x.length);
|
||||
const f10 = pipe(foo);
|
||||
const f11 = pipe(foo, foo);
|
||||
const g00 = pipe(list);
|
||||
const g01 = pipe(list, box);
|
||||
const g02 = pipe(box, list);
|
||||
const g03 = pipe(x => list(x), box);
|
||||
const g04 = pipe(list, x => box(x));
|
||||
const g05 = pipe(x => list(x), x => box(x));
|
||||
const g06 = pipe(list, pipe(box));
|
||||
const g07 = pipe(x => list(x), pipe(box));
|
||||
const g08 = pipe(x => list(x), pipe(x => box(x)));
|
||||
const g09 = pipe(list, x => x.length);
|
||||
const g10 = pipe(foo);
|
||||
const g12 = pipe(foo, foo);
|
||||
const f20 = pipe2(list, box);
|
||||
const f21 = pipe2(box, list);
|
||||
const f22 = pipe2(list, list);
|
||||
const f23 = pipe2(box, box);
|
||||
const f24 = pipe2(f20, f20);
|
||||
const f25 = pipe2(foo, foo);
|
||||
const f26 = pipe2(f25, f25);
|
||||
const f30 = pipe3(list, box);
|
||||
const f31 = pipe3(box, list);
|
||||
const f32 = pipe3(list, list);
|
||||
const f40 = pipe4([list, box]);
|
||||
const f41 = pipe4([box, list]);
|
||||
const f50 = pipe5(list); // No higher order inference
|
||||
// #417
|
||||
function mirror(f) { return f; }
|
||||
var identityM = mirror(identity);
|
||||
var x = 1;
|
||||
var y = identity(x);
|
||||
var z = identityM(x);
|
||||
// #3038
|
||||
export function keyOf(value) {
|
||||
return value.key;
|
||||
}
|
||||
var data = [];
|
||||
toKeys(data, keyOf); // Error
|
||||
// #9366
|
||||
function flip(f) {
|
||||
return (b, a) => f(a, b);
|
||||
}
|
||||
function zip(x, y) {
|
||||
return [x, y];
|
||||
}
|
||||
var expected = flip(zip);
|
||||
var actual = flip(zip);
|
||||
// #9366
|
||||
const map = (transform) => (arr) => arr.map(transform);
|
||||
const identityStr = (t) => t;
|
||||
const arr = map(identityStr)(['a']);
|
||||
const arr1 = map(identity)(['a']);
|
||||
// #9949
|
||||
function of2(one, two) {
|
||||
return [one, two];
|
||||
}
|
||||
const flipped = flip(of2);
|
||||
const enhance = pipe(myHoc1, myHoc2);
|
||||
const MyComponent2 = enhance(MyComponent1);
|
||||
// #29904.2
|
||||
const fn20 = pipe((_a) => 1);
|
||||
const fn30 = pipe(x => x + 1, x => x * 2);
|
||||
const promise = Promise.resolve(1);
|
||||
promise.then(pipe(x => x + 1, x => x * 2));
|
||||
const fn40 = pipe(getString, string => orUndefined(string), identity);
|
||||
const fn60 = pipe(getArray, x => x, first);
|
||||
const fn61 = pipe(getArray, identity, first);
|
||||
const fn62 = pipe(getArray, x => x, x => first(x));
|
||||
@@ -0,0 +1,850 @@
|
||||
=== tests/cases/compiler/genericFunctionInference1.ts ===
|
||||
declare function pipe<A extends any[], B>(ab: (...args: A) => B): (...args: A) => B;
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 0, 22))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 0, 38))
|
||||
>ab : Symbol(ab, Decl(genericFunctionInference1.ts, 0, 42))
|
||||
>args : Symbol(args, Decl(genericFunctionInference1.ts, 0, 47))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 0, 22))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 0, 38))
|
||||
>args : Symbol(args, Decl(genericFunctionInference1.ts, 0, 67))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 0, 22))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 0, 38))
|
||||
|
||||
declare function pipe<A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C;
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 1, 22))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 1, 38))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 1, 41))
|
||||
>ab : Symbol(ab, Decl(genericFunctionInference1.ts, 1, 45))
|
||||
>args : Symbol(args, Decl(genericFunctionInference1.ts, 1, 50))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 1, 22))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 1, 38))
|
||||
>bc : Symbol(bc, Decl(genericFunctionInference1.ts, 1, 67))
|
||||
>b : Symbol(b, Decl(genericFunctionInference1.ts, 1, 73))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 1, 38))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 1, 41))
|
||||
>args : Symbol(args, Decl(genericFunctionInference1.ts, 1, 87))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 1, 22))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 1, 41))
|
||||
|
||||
declare function pipe<A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D;
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 2, 22))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 2, 38))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 2, 41))
|
||||
>D : Symbol(D, Decl(genericFunctionInference1.ts, 2, 44))
|
||||
>ab : Symbol(ab, Decl(genericFunctionInference1.ts, 2, 48))
|
||||
>args : Symbol(args, Decl(genericFunctionInference1.ts, 2, 53))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 2, 22))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 2, 38))
|
||||
>bc : Symbol(bc, Decl(genericFunctionInference1.ts, 2, 70))
|
||||
>b : Symbol(b, Decl(genericFunctionInference1.ts, 2, 76))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 2, 38))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 2, 41))
|
||||
>cd : Symbol(cd, Decl(genericFunctionInference1.ts, 2, 87))
|
||||
>c : Symbol(c, Decl(genericFunctionInference1.ts, 2, 93))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 2, 41))
|
||||
>D : Symbol(D, Decl(genericFunctionInference1.ts, 2, 44))
|
||||
>args : Symbol(args, Decl(genericFunctionInference1.ts, 2, 107))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 2, 22))
|
||||
>D : Symbol(D, Decl(genericFunctionInference1.ts, 2, 44))
|
||||
|
||||
declare function list<T>(a: T): T[];
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 4, 22))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 4, 25))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 4, 22))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 4, 22))
|
||||
|
||||
declare function box<V>(x: V): { value: V };
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
>V : Symbol(V, Decl(genericFunctionInference1.ts, 5, 21))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 5, 24))
|
||||
>V : Symbol(V, Decl(genericFunctionInference1.ts, 5, 21))
|
||||
>value : Symbol(value, Decl(genericFunctionInference1.ts, 5, 32))
|
||||
>V : Symbol(V, Decl(genericFunctionInference1.ts, 5, 21))
|
||||
|
||||
declare function foo<T extends { value: T }>(x: T): T;
|
||||
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 6, 21))
|
||||
>value : Symbol(value, Decl(genericFunctionInference1.ts, 6, 32))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 6, 21))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 6, 45))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 6, 21))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 6, 21))
|
||||
|
||||
const f00 = pipe(list);
|
||||
>f00 : Symbol(f00, Decl(genericFunctionInference1.ts, 8, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
|
||||
const f01 = pipe(list, box);
|
||||
>f01 : Symbol(f01, Decl(genericFunctionInference1.ts, 9, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
|
||||
const f02 = pipe(box, list);
|
||||
>f02 : Symbol(f02, Decl(genericFunctionInference1.ts, 10, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
|
||||
const f03 = pipe(x => list(x), box);
|
||||
>f03 : Symbol(f03, Decl(genericFunctionInference1.ts, 11, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 11, 17))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 11, 17))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
|
||||
const f04 = pipe(list, x => box(x));
|
||||
>f04 : Symbol(f04, Decl(genericFunctionInference1.ts, 12, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 12, 22))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 12, 22))
|
||||
|
||||
const f05 = pipe(x => list(x), x => box(x))
|
||||
>f05 : Symbol(f05, Decl(genericFunctionInference1.ts, 13, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 13, 17))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 13, 17))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 13, 30))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 13, 30))
|
||||
|
||||
const f06 = pipe(list, pipe(box));
|
||||
>f06 : Symbol(f06, Decl(genericFunctionInference1.ts, 14, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
|
||||
const f07 = pipe(x => list(x), pipe(box));
|
||||
>f07 : Symbol(f07, Decl(genericFunctionInference1.ts, 15, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 15, 17))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 15, 17))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
|
||||
const f08 = pipe(x => list(x), pipe(x => box(x)));
|
||||
>f08 : Symbol(f08, Decl(genericFunctionInference1.ts, 16, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 16, 17))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 16, 17))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 16, 36))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 16, 36))
|
||||
|
||||
const f09 = pipe(list, x => x.length);
|
||||
>f09 : Symbol(f09, Decl(genericFunctionInference1.ts, 17, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 17, 22))
|
||||
>x.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 17, 22))
|
||||
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
const f10 = pipe(foo);
|
||||
>f10 : Symbol(f10, Decl(genericFunctionInference1.ts, 18, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
|
||||
|
||||
const f11 = pipe(foo, foo);
|
||||
>f11 : Symbol(f11, Decl(genericFunctionInference1.ts, 19, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
|
||||
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
|
||||
|
||||
const g00: <T>(x: T) => T[] = pipe(list);
|
||||
>g00 : Symbol(g00, Decl(genericFunctionInference1.ts, 21, 5))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 21, 12))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 21, 15))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 21, 12))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 21, 12))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
|
||||
const g01: <T>(x: T) => { value: T[] } = pipe(list, box);
|
||||
>g01 : Symbol(g01, Decl(genericFunctionInference1.ts, 22, 5))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 22, 12))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 22, 15))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 22, 12))
|
||||
>value : Symbol(value, Decl(genericFunctionInference1.ts, 22, 25))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 22, 12))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
|
||||
const g02: <T>(x: T) => { value: T }[] = pipe(box, list);
|
||||
>g02 : Symbol(g02, Decl(genericFunctionInference1.ts, 23, 5))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 23, 12))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 23, 15))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 23, 12))
|
||||
>value : Symbol(value, Decl(genericFunctionInference1.ts, 23, 25))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 23, 12))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
|
||||
const g03: <T>(x: T) => { value: T[] } = pipe(x => list(x), box);
|
||||
>g03 : Symbol(g03, Decl(genericFunctionInference1.ts, 24, 5))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 24, 12))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 24, 15))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 24, 12))
|
||||
>value : Symbol(value, Decl(genericFunctionInference1.ts, 24, 25))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 24, 12))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 24, 46))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 24, 46))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
|
||||
const g04: <T>(x: T) => { value: T[] } = pipe(list, x => box(x));
|
||||
>g04 : Symbol(g04, Decl(genericFunctionInference1.ts, 25, 5))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 25, 12))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 25, 15))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 25, 12))
|
||||
>value : Symbol(value, Decl(genericFunctionInference1.ts, 25, 25))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 25, 12))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 25, 51))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 25, 51))
|
||||
|
||||
const g05: <T>(x: T) => { value: T[] } = pipe(x => list(x), x => box(x))
|
||||
>g05 : Symbol(g05, Decl(genericFunctionInference1.ts, 26, 5))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 26, 12))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 26, 15))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 26, 12))
|
||||
>value : Symbol(value, Decl(genericFunctionInference1.ts, 26, 25))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 26, 12))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 26, 46))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 26, 46))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 26, 59))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 26, 59))
|
||||
|
||||
const g06: <T>(x: T) => { value: T[] } = pipe(list, pipe(box));
|
||||
>g06 : Symbol(g06, Decl(genericFunctionInference1.ts, 27, 5))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 27, 12))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 27, 15))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 27, 12))
|
||||
>value : Symbol(value, Decl(genericFunctionInference1.ts, 27, 25))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 27, 12))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
|
||||
const g07: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(box));
|
||||
>g07 : Symbol(g07, Decl(genericFunctionInference1.ts, 28, 5))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 28, 12))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 28, 15))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 28, 12))
|
||||
>value : Symbol(value, Decl(genericFunctionInference1.ts, 28, 25))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 28, 12))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 28, 46))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 28, 46))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
|
||||
const g08: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(x => box(x)));
|
||||
>g08 : Symbol(g08, Decl(genericFunctionInference1.ts, 29, 5))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 29, 12))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 29, 15))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 29, 12))
|
||||
>value : Symbol(value, Decl(genericFunctionInference1.ts, 29, 25))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 29, 12))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 29, 46))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 29, 46))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 29, 65))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 29, 65))
|
||||
|
||||
const g09: <T>(x: T) => number = pipe(list, x => x.length);
|
||||
>g09 : Symbol(g09, Decl(genericFunctionInference1.ts, 30, 5))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 30, 12))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 30, 15))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 30, 12))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 30, 43))
|
||||
>x.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 30, 43))
|
||||
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
const g10: <T extends { value: T }>(x: T) => T = pipe(foo);
|
||||
>g10 : Symbol(g10, Decl(genericFunctionInference1.ts, 31, 5))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 31, 12))
|
||||
>value : Symbol(value, Decl(genericFunctionInference1.ts, 31, 23))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 31, 12))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 31, 36))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 31, 12))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 31, 12))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
|
||||
|
||||
const g12: <T extends { value: T }>(x: T) => T = pipe(foo, foo);
|
||||
>g12 : Symbol(g12, Decl(genericFunctionInference1.ts, 32, 5))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 32, 12))
|
||||
>value : Symbol(value, Decl(genericFunctionInference1.ts, 32, 23))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 32, 12))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 32, 36))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 32, 12))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 32, 12))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
|
||||
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
|
||||
|
||||
declare function pipe2<A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D): (a: [A, C]) => [B, D];
|
||||
>pipe2 : Symbol(pipe2, Decl(genericFunctionInference1.ts, 32, 64))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 34, 23))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 34, 25))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 34, 28))
|
||||
>D : Symbol(D, Decl(genericFunctionInference1.ts, 34, 31))
|
||||
>ab : Symbol(ab, Decl(genericFunctionInference1.ts, 34, 35))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 34, 40))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 34, 23))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 34, 25))
|
||||
>cd : Symbol(cd, Decl(genericFunctionInference1.ts, 34, 51))
|
||||
>c : Symbol(c, Decl(genericFunctionInference1.ts, 34, 57))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 34, 28))
|
||||
>D : Symbol(D, Decl(genericFunctionInference1.ts, 34, 31))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 34, 71))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 34, 23))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 34, 28))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 34, 25))
|
||||
>D : Symbol(D, Decl(genericFunctionInference1.ts, 34, 31))
|
||||
|
||||
const f20 = pipe2(list, box);
|
||||
>f20 : Symbol(f20, Decl(genericFunctionInference1.ts, 36, 5))
|
||||
>pipe2 : Symbol(pipe2, Decl(genericFunctionInference1.ts, 32, 64))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
|
||||
const f21 = pipe2(box, list);
|
||||
>f21 : Symbol(f21, Decl(genericFunctionInference1.ts, 37, 5))
|
||||
>pipe2 : Symbol(pipe2, Decl(genericFunctionInference1.ts, 32, 64))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
|
||||
const f22 = pipe2(list, list);
|
||||
>f22 : Symbol(f22, Decl(genericFunctionInference1.ts, 38, 5))
|
||||
>pipe2 : Symbol(pipe2, Decl(genericFunctionInference1.ts, 32, 64))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
|
||||
const f23 = pipe2(box, box);
|
||||
>f23 : Symbol(f23, Decl(genericFunctionInference1.ts, 39, 5))
|
||||
>pipe2 : Symbol(pipe2, Decl(genericFunctionInference1.ts, 32, 64))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
|
||||
const f24 = pipe2(f20, f20);
|
||||
>f24 : Symbol(f24, Decl(genericFunctionInference1.ts, 40, 5))
|
||||
>pipe2 : Symbol(pipe2, Decl(genericFunctionInference1.ts, 32, 64))
|
||||
>f20 : Symbol(f20, Decl(genericFunctionInference1.ts, 36, 5))
|
||||
>f20 : Symbol(f20, Decl(genericFunctionInference1.ts, 36, 5))
|
||||
|
||||
const f25 = pipe2(foo, foo);
|
||||
>f25 : Symbol(f25, Decl(genericFunctionInference1.ts, 41, 5))
|
||||
>pipe2 : Symbol(pipe2, Decl(genericFunctionInference1.ts, 32, 64))
|
||||
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
|
||||
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 5, 44))
|
||||
|
||||
const f26 = pipe2(f25, f25);
|
||||
>f26 : Symbol(f26, Decl(genericFunctionInference1.ts, 42, 5))
|
||||
>pipe2 : Symbol(pipe2, Decl(genericFunctionInference1.ts, 32, 64))
|
||||
>f25 : Symbol(f25, Decl(genericFunctionInference1.ts, 41, 5))
|
||||
>f25 : Symbol(f25, Decl(genericFunctionInference1.ts, 41, 5))
|
||||
|
||||
declare function pipe3<A, B, C>(ab: (a: A) => B, ac: (a: A) => C): (a: A) => [B, C];
|
||||
>pipe3 : Symbol(pipe3, Decl(genericFunctionInference1.ts, 42, 28))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 44, 23))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 44, 25))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 44, 28))
|
||||
>ab : Symbol(ab, Decl(genericFunctionInference1.ts, 44, 32))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 44, 37))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 44, 23))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 44, 25))
|
||||
>ac : Symbol(ac, Decl(genericFunctionInference1.ts, 44, 48))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 44, 54))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 44, 23))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 44, 28))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 44, 68))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 44, 23))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 44, 25))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 44, 28))
|
||||
|
||||
const f30 = pipe3(list, box);
|
||||
>f30 : Symbol(f30, Decl(genericFunctionInference1.ts, 46, 5))
|
||||
>pipe3 : Symbol(pipe3, Decl(genericFunctionInference1.ts, 42, 28))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
|
||||
const f31 = pipe3(box, list);
|
||||
>f31 : Symbol(f31, Decl(genericFunctionInference1.ts, 47, 5))
|
||||
>pipe3 : Symbol(pipe3, Decl(genericFunctionInference1.ts, 42, 28))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
|
||||
const f32 = pipe3(list, list);
|
||||
>f32 : Symbol(f32, Decl(genericFunctionInference1.ts, 48, 5))
|
||||
>pipe3 : Symbol(pipe3, Decl(genericFunctionInference1.ts, 42, 28))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
|
||||
declare function pipe4<A, B, C>(funcs: [(a: A) => B, (b: B) => C]): (a: A) => C;
|
||||
>pipe4 : Symbol(pipe4, Decl(genericFunctionInference1.ts, 48, 30))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 50, 23))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 50, 25))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 50, 28))
|
||||
>funcs : Symbol(funcs, Decl(genericFunctionInference1.ts, 50, 32))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 50, 41))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 50, 23))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 50, 25))
|
||||
>b : Symbol(b, Decl(genericFunctionInference1.ts, 50, 54))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 50, 25))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 50, 28))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 50, 69))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 50, 23))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 50, 28))
|
||||
|
||||
const f40 = pipe4([list, box]);
|
||||
>f40 : Symbol(f40, Decl(genericFunctionInference1.ts, 52, 5))
|
||||
>pipe4 : Symbol(pipe4, Decl(genericFunctionInference1.ts, 48, 30))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
|
||||
const f41 = pipe4([box, list]);
|
||||
>f41 : Symbol(f41, Decl(genericFunctionInference1.ts, 53, 5))
|
||||
>pipe4 : Symbol(pipe4, Decl(genericFunctionInference1.ts, 48, 30))
|
||||
>box : Symbol(box, Decl(genericFunctionInference1.ts, 4, 36))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
|
||||
declare function pipe5<A, B>(f: (a: A) => B): { f: (a: A) => B };
|
||||
>pipe5 : Symbol(pipe5, Decl(genericFunctionInference1.ts, 53, 31))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 55, 23))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 55, 25))
|
||||
>f : Symbol(f, Decl(genericFunctionInference1.ts, 55, 29))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 55, 33))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 55, 23))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 55, 25))
|
||||
>f : Symbol(f, Decl(genericFunctionInference1.ts, 55, 47))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 55, 52))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 55, 23))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 55, 25))
|
||||
|
||||
const f50 = pipe5(list); // No higher order inference
|
||||
>f50 : Symbol(f50, Decl(genericFunctionInference1.ts, 57, 5))
|
||||
>pipe5 : Symbol(pipe5, Decl(genericFunctionInference1.ts, 53, 31))
|
||||
>list : Symbol(list, Decl(genericFunctionInference1.ts, 2, 124))
|
||||
|
||||
// #417
|
||||
|
||||
function mirror<A, B>(f: (a: A) => B): (a: A) => B { return f; }
|
||||
>mirror : Symbol(mirror, Decl(genericFunctionInference1.ts, 57, 24))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 61, 16))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 61, 18))
|
||||
>f : Symbol(f, Decl(genericFunctionInference1.ts, 61, 22))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 61, 26))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 61, 16))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 61, 18))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 61, 40))
|
||||
>A : Symbol(A, Decl(genericFunctionInference1.ts, 61, 16))
|
||||
>B : Symbol(B, Decl(genericFunctionInference1.ts, 61, 18))
|
||||
>f : Symbol(f, Decl(genericFunctionInference1.ts, 61, 22))
|
||||
|
||||
var identityM = mirror(identity);
|
||||
>identityM : Symbol(identityM, Decl(genericFunctionInference1.ts, 62, 3))
|
||||
>mirror : Symbol(mirror, Decl(genericFunctionInference1.ts, 57, 24))
|
||||
>identity : Symbol(identity, Decl(genericFunctionInference1.ts, 154, 13))
|
||||
|
||||
var x = 1;
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 64, 3))
|
||||
|
||||
var y = identity(x);
|
||||
>y : Symbol(y, Decl(genericFunctionInference1.ts, 65, 3))
|
||||
>identity : Symbol(identity, Decl(genericFunctionInference1.ts, 154, 13))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 64, 3))
|
||||
|
||||
var z = identityM(x);
|
||||
>z : Symbol(z, Decl(genericFunctionInference1.ts, 66, 3))
|
||||
>identityM : Symbol(identityM, Decl(genericFunctionInference1.ts, 62, 3))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 64, 3))
|
||||
|
||||
// #3038
|
||||
|
||||
export function keyOf<a>(value: { key: a; }): a {
|
||||
>keyOf : Symbol(keyOf, Decl(genericFunctionInference1.ts, 66, 21))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 70, 22))
|
||||
>value : Symbol(value, Decl(genericFunctionInference1.ts, 70, 25))
|
||||
>key : Symbol(key, Decl(genericFunctionInference1.ts, 70, 33))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 70, 22))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 70, 22))
|
||||
|
||||
return value.key;
|
||||
>value.key : Symbol(key, Decl(genericFunctionInference1.ts, 70, 33))
|
||||
>value : Symbol(value, Decl(genericFunctionInference1.ts, 70, 25))
|
||||
>key : Symbol(key, Decl(genericFunctionInference1.ts, 70, 33))
|
||||
}
|
||||
export interface Data {
|
||||
>Data : Symbol(Data, Decl(genericFunctionInference1.ts, 72, 1))
|
||||
|
||||
key: number;
|
||||
>key : Symbol(Data.key, Decl(genericFunctionInference1.ts, 73, 23))
|
||||
|
||||
value: Date;
|
||||
>value : Symbol(Data.value, Decl(genericFunctionInference1.ts, 74, 16))
|
||||
>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
}
|
||||
|
||||
var data: Data[] = [];
|
||||
>data : Symbol(data, Decl(genericFunctionInference1.ts, 78, 3))
|
||||
>Data : Symbol(Data, Decl(genericFunctionInference1.ts, 72, 1))
|
||||
|
||||
declare function toKeys<a>(values: a[], toKey: (value: a) => string): string[];
|
||||
>toKeys : Symbol(toKeys, Decl(genericFunctionInference1.ts, 78, 22))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 80, 24))
|
||||
>values : Symbol(values, Decl(genericFunctionInference1.ts, 80, 27))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 80, 24))
|
||||
>toKey : Symbol(toKey, Decl(genericFunctionInference1.ts, 80, 39))
|
||||
>value : Symbol(value, Decl(genericFunctionInference1.ts, 80, 48))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 80, 24))
|
||||
|
||||
toKeys(data, keyOf); // Error
|
||||
>toKeys : Symbol(toKeys, Decl(genericFunctionInference1.ts, 78, 22))
|
||||
>data : Symbol(data, Decl(genericFunctionInference1.ts, 78, 3))
|
||||
>keyOf : Symbol(keyOf, Decl(genericFunctionInference1.ts, 66, 21))
|
||||
|
||||
// #9366
|
||||
|
||||
function flip<a, b, c>(f: (a: a, b: b) => c): (b: b, a: a) => c {
|
||||
>flip : Symbol(flip, Decl(genericFunctionInference1.ts, 82, 20))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 86, 14))
|
||||
>b : Symbol(b, Decl(genericFunctionInference1.ts, 86, 16))
|
||||
>c : Symbol(c, Decl(genericFunctionInference1.ts, 86, 19))
|
||||
>f : Symbol(f, Decl(genericFunctionInference1.ts, 86, 23))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 86, 27))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 86, 14))
|
||||
>b : Symbol(b, Decl(genericFunctionInference1.ts, 86, 32))
|
||||
>b : Symbol(b, Decl(genericFunctionInference1.ts, 86, 16))
|
||||
>c : Symbol(c, Decl(genericFunctionInference1.ts, 86, 19))
|
||||
>b : Symbol(b, Decl(genericFunctionInference1.ts, 86, 47))
|
||||
>b : Symbol(b, Decl(genericFunctionInference1.ts, 86, 16))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 86, 52))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 86, 14))
|
||||
>c : Symbol(c, Decl(genericFunctionInference1.ts, 86, 19))
|
||||
|
||||
return (b: b, a: a) => f(a, b);
|
||||
>b : Symbol(b, Decl(genericFunctionInference1.ts, 87, 10))
|
||||
>b : Symbol(b, Decl(genericFunctionInference1.ts, 86, 16))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 87, 15))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 86, 14))
|
||||
>f : Symbol(f, Decl(genericFunctionInference1.ts, 86, 23))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 87, 15))
|
||||
>b : Symbol(b, Decl(genericFunctionInference1.ts, 87, 10))
|
||||
}
|
||||
function zip<T, U>(x: T, y: U): [T, U] {
|
||||
>zip : Symbol(zip, Decl(genericFunctionInference1.ts, 88, 1))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 89, 13))
|
||||
>U : Symbol(U, Decl(genericFunctionInference1.ts, 89, 15))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 89, 19))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 89, 13))
|
||||
>y : Symbol(y, Decl(genericFunctionInference1.ts, 89, 24))
|
||||
>U : Symbol(U, Decl(genericFunctionInference1.ts, 89, 15))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 89, 13))
|
||||
>U : Symbol(U, Decl(genericFunctionInference1.ts, 89, 15))
|
||||
|
||||
return [x, y];
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 89, 19))
|
||||
>y : Symbol(y, Decl(genericFunctionInference1.ts, 89, 24))
|
||||
}
|
||||
|
||||
var expected: <T, U>(y: U, x: T) => [T, U] = flip(zip);
|
||||
>expected : Symbol(expected, Decl(genericFunctionInference1.ts, 93, 3))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 93, 15))
|
||||
>U : Symbol(U, Decl(genericFunctionInference1.ts, 93, 17))
|
||||
>y : Symbol(y, Decl(genericFunctionInference1.ts, 93, 21))
|
||||
>U : Symbol(U, Decl(genericFunctionInference1.ts, 93, 17))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 93, 26))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 93, 15))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 93, 15))
|
||||
>U : Symbol(U, Decl(genericFunctionInference1.ts, 93, 17))
|
||||
>flip : Symbol(flip, Decl(genericFunctionInference1.ts, 82, 20))
|
||||
>zip : Symbol(zip, Decl(genericFunctionInference1.ts, 88, 1))
|
||||
|
||||
var actual = flip(zip);
|
||||
>actual : Symbol(actual, Decl(genericFunctionInference1.ts, 94, 3))
|
||||
>flip : Symbol(flip, Decl(genericFunctionInference1.ts, 82, 20))
|
||||
>zip : Symbol(zip, Decl(genericFunctionInference1.ts, 88, 1))
|
||||
|
||||
// #9366
|
||||
|
||||
const map = <T, U>(transform: (t: T) => U) =>
|
||||
>map : Symbol(map, Decl(genericFunctionInference1.ts, 98, 5))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 98, 13))
|
||||
>U : Symbol(U, Decl(genericFunctionInference1.ts, 98, 15))
|
||||
>transform : Symbol(transform, Decl(genericFunctionInference1.ts, 98, 19))
|
||||
>t : Symbol(t, Decl(genericFunctionInference1.ts, 98, 31))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 98, 13))
|
||||
>U : Symbol(U, Decl(genericFunctionInference1.ts, 98, 15))
|
||||
|
||||
(arr: T[]) => arr.map(transform)
|
||||
>arr : Symbol(arr, Decl(genericFunctionInference1.ts, 99, 5))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 98, 13))
|
||||
>arr.map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --))
|
||||
>arr : Symbol(arr, Decl(genericFunctionInference1.ts, 99, 5))
|
||||
>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --))
|
||||
>transform : Symbol(transform, Decl(genericFunctionInference1.ts, 98, 19))
|
||||
|
||||
const identityStr = (t: string) => t;
|
||||
>identityStr : Symbol(identityStr, Decl(genericFunctionInference1.ts, 101, 5))
|
||||
>t : Symbol(t, Decl(genericFunctionInference1.ts, 101, 21))
|
||||
>t : Symbol(t, Decl(genericFunctionInference1.ts, 101, 21))
|
||||
|
||||
const arr: string[] = map(identityStr)(['a']);
|
||||
>arr : Symbol(arr, Decl(genericFunctionInference1.ts, 103, 5))
|
||||
>map : Symbol(map, Decl(genericFunctionInference1.ts, 98, 5))
|
||||
>identityStr : Symbol(identityStr, Decl(genericFunctionInference1.ts, 101, 5))
|
||||
|
||||
const arr1: string[] = map(identity)(['a']);
|
||||
>arr1 : Symbol(arr1, Decl(genericFunctionInference1.ts, 104, 5))
|
||||
>map : Symbol(map, Decl(genericFunctionInference1.ts, 98, 5))
|
||||
>identity : Symbol(identity, Decl(genericFunctionInference1.ts, 154, 13))
|
||||
|
||||
// #9949
|
||||
|
||||
function of2<a, b>(one: a, two: b): [a, b] {
|
||||
>of2 : Symbol(of2, Decl(genericFunctionInference1.ts, 104, 44))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 108, 13))
|
||||
>b : Symbol(b, Decl(genericFunctionInference1.ts, 108, 15))
|
||||
>one : Symbol(one, Decl(genericFunctionInference1.ts, 108, 19))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 108, 13))
|
||||
>two : Symbol(two, Decl(genericFunctionInference1.ts, 108, 26))
|
||||
>b : Symbol(b, Decl(genericFunctionInference1.ts, 108, 15))
|
||||
>a : Symbol(a, Decl(genericFunctionInference1.ts, 108, 13))
|
||||
>b : Symbol(b, Decl(genericFunctionInference1.ts, 108, 15))
|
||||
|
||||
return [one, two];
|
||||
>one : Symbol(one, Decl(genericFunctionInference1.ts, 108, 19))
|
||||
>two : Symbol(two, Decl(genericFunctionInference1.ts, 108, 26))
|
||||
}
|
||||
|
||||
const flipped = flip(of2);
|
||||
>flipped : Symbol(flipped, Decl(genericFunctionInference1.ts, 112, 5))
|
||||
>flip : Symbol(flip, Decl(genericFunctionInference1.ts, 82, 20))
|
||||
>of2 : Symbol(of2, Decl(genericFunctionInference1.ts, 104, 44))
|
||||
|
||||
// #29904.1
|
||||
|
||||
type Component<P> = (props: P) => {};
|
||||
>Component : Symbol(Component, Decl(genericFunctionInference1.ts, 112, 26))
|
||||
>P : Symbol(P, Decl(genericFunctionInference1.ts, 116, 15))
|
||||
>props : Symbol(props, Decl(genericFunctionInference1.ts, 116, 21))
|
||||
>P : Symbol(P, Decl(genericFunctionInference1.ts, 116, 15))
|
||||
|
||||
declare const myHoc1: <P>(C: Component<P>) => Component<P>;
|
||||
>myHoc1 : Symbol(myHoc1, Decl(genericFunctionInference1.ts, 118, 13))
|
||||
>P : Symbol(P, Decl(genericFunctionInference1.ts, 118, 23))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 118, 26))
|
||||
>Component : Symbol(Component, Decl(genericFunctionInference1.ts, 112, 26))
|
||||
>P : Symbol(P, Decl(genericFunctionInference1.ts, 118, 23))
|
||||
>Component : Symbol(Component, Decl(genericFunctionInference1.ts, 112, 26))
|
||||
>P : Symbol(P, Decl(genericFunctionInference1.ts, 118, 23))
|
||||
|
||||
declare const myHoc2: <P>(C: Component<P>) => Component<P>;
|
||||
>myHoc2 : Symbol(myHoc2, Decl(genericFunctionInference1.ts, 119, 13))
|
||||
>P : Symbol(P, Decl(genericFunctionInference1.ts, 119, 23))
|
||||
>C : Symbol(C, Decl(genericFunctionInference1.ts, 119, 26))
|
||||
>Component : Symbol(Component, Decl(genericFunctionInference1.ts, 112, 26))
|
||||
>P : Symbol(P, Decl(genericFunctionInference1.ts, 119, 23))
|
||||
>Component : Symbol(Component, Decl(genericFunctionInference1.ts, 112, 26))
|
||||
>P : Symbol(P, Decl(genericFunctionInference1.ts, 119, 23))
|
||||
|
||||
declare const MyComponent1: Component<{ foo: 1 }>;
|
||||
>MyComponent1 : Symbol(MyComponent1, Decl(genericFunctionInference1.ts, 121, 13))
|
||||
>Component : Symbol(Component, Decl(genericFunctionInference1.ts, 112, 26))
|
||||
>foo : Symbol(foo, Decl(genericFunctionInference1.ts, 121, 39))
|
||||
|
||||
const enhance = pipe(
|
||||
>enhance : Symbol(enhance, Decl(genericFunctionInference1.ts, 123, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
|
||||
myHoc1,
|
||||
>myHoc1 : Symbol(myHoc1, Decl(genericFunctionInference1.ts, 118, 13))
|
||||
|
||||
myHoc2,
|
||||
>myHoc2 : Symbol(myHoc2, Decl(genericFunctionInference1.ts, 119, 13))
|
||||
|
||||
);
|
||||
|
||||
const MyComponent2 = enhance(MyComponent1);
|
||||
>MyComponent2 : Symbol(MyComponent2, Decl(genericFunctionInference1.ts, 128, 5))
|
||||
>enhance : Symbol(enhance, Decl(genericFunctionInference1.ts, 123, 5))
|
||||
>MyComponent1 : Symbol(MyComponent1, Decl(genericFunctionInference1.ts, 121, 13))
|
||||
|
||||
// #29904.2
|
||||
|
||||
const fn20 = pipe((_a?: {}) => 1);
|
||||
>fn20 : Symbol(fn20, Decl(genericFunctionInference1.ts, 132, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
>_a : Symbol(_a, Decl(genericFunctionInference1.ts, 132, 19))
|
||||
|
||||
// #29904.3
|
||||
|
||||
type Fn = (n: number) => number;
|
||||
>Fn : Symbol(Fn, Decl(genericFunctionInference1.ts, 132, 34))
|
||||
>n : Symbol(n, Decl(genericFunctionInference1.ts, 136, 11))
|
||||
|
||||
const fn30: Fn = pipe(
|
||||
>fn30 : Symbol(fn30, Decl(genericFunctionInference1.ts, 137, 5))
|
||||
>Fn : Symbol(Fn, Decl(genericFunctionInference1.ts, 132, 34))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
|
||||
x => x + 1,
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 137, 22))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 137, 22))
|
||||
|
||||
x => x * 2,
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 138, 15))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 138, 15))
|
||||
|
||||
);
|
||||
|
||||
const promise = Promise.resolve(1);
|
||||
>promise : Symbol(promise, Decl(genericFunctionInference1.ts, 142, 5))
|
||||
>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
|
||||
|
||||
promise.then(
|
||||
>promise.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --))
|
||||
>promise : Symbol(promise, Decl(genericFunctionInference1.ts, 142, 5))
|
||||
>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
pipe(
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
|
||||
x => x + 1,
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 144, 9))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 144, 9))
|
||||
|
||||
x => x * 2,
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 145, 19))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 145, 19))
|
||||
|
||||
),
|
||||
);
|
||||
|
||||
// #29904.4
|
||||
|
||||
declare const getString: () => string;
|
||||
>getString : Symbol(getString, Decl(genericFunctionInference1.ts, 152, 13))
|
||||
|
||||
declare const orUndefined: (name: string) => string | undefined;
|
||||
>orUndefined : Symbol(orUndefined, Decl(genericFunctionInference1.ts, 153, 13))
|
||||
>name : Symbol(name, Decl(genericFunctionInference1.ts, 153, 28))
|
||||
|
||||
declare const identity: <T>(value: T) => T;
|
||||
>identity : Symbol(identity, Decl(genericFunctionInference1.ts, 154, 13))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 154, 25))
|
||||
>value : Symbol(value, Decl(genericFunctionInference1.ts, 154, 28))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 154, 25))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 154, 25))
|
||||
|
||||
const fn40 = pipe(
|
||||
>fn40 : Symbol(fn40, Decl(genericFunctionInference1.ts, 156, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
|
||||
getString,
|
||||
>getString : Symbol(getString, Decl(genericFunctionInference1.ts, 152, 13))
|
||||
|
||||
string => orUndefined(string),
|
||||
>string : Symbol(string, Decl(genericFunctionInference1.ts, 157, 14))
|
||||
>orUndefined : Symbol(orUndefined, Decl(genericFunctionInference1.ts, 153, 13))
|
||||
>string : Symbol(string, Decl(genericFunctionInference1.ts, 157, 14))
|
||||
|
||||
identity,
|
||||
>identity : Symbol(identity, Decl(genericFunctionInference1.ts, 154, 13))
|
||||
|
||||
);
|
||||
|
||||
// #29904.6
|
||||
|
||||
declare const getArray: () => string[];
|
||||
>getArray : Symbol(getArray, Decl(genericFunctionInference1.ts, 164, 13))
|
||||
|
||||
declare const first: <T>(ts: T[]) => T;
|
||||
>first : Symbol(first, Decl(genericFunctionInference1.ts, 165, 13))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 165, 22))
|
||||
>ts : Symbol(ts, Decl(genericFunctionInference1.ts, 165, 25))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 165, 22))
|
||||
>T : Symbol(T, Decl(genericFunctionInference1.ts, 165, 22))
|
||||
|
||||
const fn60 = pipe(
|
||||
>fn60 : Symbol(fn60, Decl(genericFunctionInference1.ts, 167, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
|
||||
getArray,
|
||||
>getArray : Symbol(getArray, Decl(genericFunctionInference1.ts, 164, 13))
|
||||
|
||||
x => x,
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 168, 13))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 168, 13))
|
||||
|
||||
first,
|
||||
>first : Symbol(first, Decl(genericFunctionInference1.ts, 165, 13))
|
||||
|
||||
);
|
||||
|
||||
const fn61 = pipe(
|
||||
>fn61 : Symbol(fn61, Decl(genericFunctionInference1.ts, 173, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
|
||||
getArray,
|
||||
>getArray : Symbol(getArray, Decl(genericFunctionInference1.ts, 164, 13))
|
||||
|
||||
identity,
|
||||
>identity : Symbol(identity, Decl(genericFunctionInference1.ts, 154, 13))
|
||||
|
||||
first,
|
||||
>first : Symbol(first, Decl(genericFunctionInference1.ts, 165, 13))
|
||||
|
||||
);
|
||||
|
||||
const fn62 = pipe(
|
||||
>fn62 : Symbol(fn62, Decl(genericFunctionInference1.ts, 179, 5))
|
||||
>pipe : Symbol(pipe, Decl(genericFunctionInference1.ts, 0, 0), Decl(genericFunctionInference1.ts, 0, 84), Decl(genericFunctionInference1.ts, 1, 104))
|
||||
|
||||
getArray,
|
||||
>getArray : Symbol(getArray, Decl(genericFunctionInference1.ts, 164, 13))
|
||||
|
||||
x => x,
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 180, 13))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 180, 13))
|
||||
|
||||
x => first(x),
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 181, 11))
|
||||
>first : Symbol(first, Decl(genericFunctionInference1.ts, 165, 13))
|
||||
>x : Symbol(x, Decl(genericFunctionInference1.ts, 181, 11))
|
||||
|
||||
);
|
||||
|
||||
@@ -0,0 +1,801 @@
|
||||
=== tests/cases/compiler/genericFunctionInference1.ts ===
|
||||
declare function pipe<A extends any[], B>(ab: (...args: A) => B): (...args: A) => B;
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>ab : (...args: A) => B
|
||||
>args : A
|
||||
>args : A
|
||||
|
||||
declare function pipe<A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C;
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>ab : (...args: A) => B
|
||||
>args : A
|
||||
>bc : (b: B) => C
|
||||
>b : B
|
||||
>args : A
|
||||
|
||||
declare function pipe<A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D;
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>ab : (...args: A) => B
|
||||
>args : A
|
||||
>bc : (b: B) => C
|
||||
>b : B
|
||||
>cd : (c: C) => D
|
||||
>c : C
|
||||
>args : A
|
||||
|
||||
declare function list<T>(a: T): T[];
|
||||
>list : <T>(a: T) => T[]
|
||||
>a : T
|
||||
|
||||
declare function box<V>(x: V): { value: V };
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
>x : V
|
||||
>value : V
|
||||
|
||||
declare function foo<T extends { value: T }>(x: T): T;
|
||||
>foo : <T extends { value: T; }>(x: T) => T
|
||||
>value : T
|
||||
>x : T
|
||||
|
||||
const f00 = pipe(list);
|
||||
>f00 : <T>(a: T) => T[]
|
||||
>pipe(list) : <T>(a: T) => T[]
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>list : <T>(a: T) => T[]
|
||||
|
||||
const f01 = pipe(list, box);
|
||||
>f01 : <T>(a: T) => { value: T[]; }
|
||||
>pipe(list, box) : <T>(a: T) => { value: T[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>list : <T>(a: T) => T[]
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
|
||||
const f02 = pipe(box, list);
|
||||
>f02 : <V>(x: V) => { value: V; }[]
|
||||
>pipe(box, list) : <V>(x: V) => { value: V; }[]
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
>list : <T>(a: T) => T[]
|
||||
|
||||
const f03 = pipe(x => list(x), box);
|
||||
>f03 : (x: any) => { value: any[]; }
|
||||
>pipe(x => list(x), box) : (x: any) => { value: any[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>x => list(x) : (x: any) => any[]
|
||||
>x : any
|
||||
>list(x) : any[]
|
||||
>list : <T>(a: T) => T[]
|
||||
>x : any
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
|
||||
const f04 = pipe(list, x => box(x));
|
||||
>f04 : <T>(a: T) => { value: T[]; }
|
||||
>pipe(list, x => box(x)) : <T>(a: T) => { value: T[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>list : <T>(a: T) => T[]
|
||||
>x => box(x) : (x: T[]) => { value: T[]; }
|
||||
>x : T[]
|
||||
>box(x) : { value: T[]; }
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
>x : T[]
|
||||
|
||||
const f05 = pipe(x => list(x), x => box(x))
|
||||
>f05 : (x: any) => { value: any[]; }
|
||||
>pipe(x => list(x), x => box(x)) : (x: any) => { value: any[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>x => list(x) : (x: any) => any[]
|
||||
>x : any
|
||||
>list(x) : any[]
|
||||
>list : <T>(a: T) => T[]
|
||||
>x : any
|
||||
>x => box(x) : (x: any[]) => { value: any[]; }
|
||||
>x : any[]
|
||||
>box(x) : { value: any[]; }
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
>x : any[]
|
||||
|
||||
const f06 = pipe(list, pipe(box));
|
||||
>f06 : <T>(a: T) => { value: T[]; }
|
||||
>pipe(list, pipe(box)) : <T>(a: T) => { value: T[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>list : <T>(a: T) => T[]
|
||||
>pipe(box) : (x: T[]) => { value: T[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
|
||||
const f07 = pipe(x => list(x), pipe(box));
|
||||
>f07 : (x: any) => { value: any[]; }
|
||||
>pipe(x => list(x), pipe(box)) : (x: any) => { value: any[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>x => list(x) : (x: any) => any[]
|
||||
>x : any
|
||||
>list(x) : any[]
|
||||
>list : <T>(a: T) => T[]
|
||||
>x : any
|
||||
>pipe(box) : (x: any[]) => { value: any[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
|
||||
const f08 = pipe(x => list(x), pipe(x => box(x)));
|
||||
>f08 : (x: any) => { value: any[]; }
|
||||
>pipe(x => list(x), pipe(x => box(x))) : (x: any) => { value: any[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>x => list(x) : (x: any) => any[]
|
||||
>x : any
|
||||
>list(x) : any[]
|
||||
>list : <T>(a: T) => T[]
|
||||
>x : any
|
||||
>pipe(x => box(x)) : (x: any[]) => { value: any[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>x => box(x) : (x: any[]) => { value: any[]; }
|
||||
>x : any[]
|
||||
>box(x) : { value: any[]; }
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
>x : any[]
|
||||
|
||||
const f09 = pipe(list, x => x.length);
|
||||
>f09 : <T>(a: T) => number
|
||||
>pipe(list, x => x.length) : <T>(a: T) => number
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>list : <T>(a: T) => T[]
|
||||
>x => x.length : (x: T[]) => number
|
||||
>x : T[]
|
||||
>x.length : number
|
||||
>x : T[]
|
||||
>length : number
|
||||
|
||||
const f10 = pipe(foo);
|
||||
>f10 : <T extends { value: T; }>(x: T) => T
|
||||
>pipe(foo) : <T extends { value: T; }>(x: T) => T
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>foo : <T extends { value: T; }>(x: T) => T
|
||||
|
||||
const f11 = pipe(foo, foo);
|
||||
>f11 : <T extends { value: T; }>(x: T) => T
|
||||
>pipe(foo, foo) : <T extends { value: T; }>(x: T) => T
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>foo : <T extends { value: T; }>(x: T) => T
|
||||
>foo : <T extends { value: T; }>(x: T) => T
|
||||
|
||||
const g00: <T>(x: T) => T[] = pipe(list);
|
||||
>g00 : <T>(x: T) => T[]
|
||||
>x : T
|
||||
>pipe(list) : (a: T) => T[]
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>list : <T>(a: T) => T[]
|
||||
|
||||
const g01: <T>(x: T) => { value: T[] } = pipe(list, box);
|
||||
>g01 : <T>(x: T) => { value: T[]; }
|
||||
>x : T
|
||||
>value : T[]
|
||||
>pipe(list, box) : (a: T) => { value: T[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>list : <T>(a: T) => T[]
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
|
||||
const g02: <T>(x: T) => { value: T }[] = pipe(box, list);
|
||||
>g02 : <T>(x: T) => { value: T; }[]
|
||||
>x : T
|
||||
>value : T
|
||||
>pipe(box, list) : (x: T) => { value: T; }[]
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
>list : <T>(a: T) => T[]
|
||||
|
||||
const g03: <T>(x: T) => { value: T[] } = pipe(x => list(x), box);
|
||||
>g03 : <T>(x: T) => { value: T[]; }
|
||||
>x : T
|
||||
>value : T[]
|
||||
>pipe(x => list(x), box) : (x: T) => { value: T[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>x => list(x) : (x: T) => T[]
|
||||
>x : T
|
||||
>list(x) : T[]
|
||||
>list : <T>(a: T) => T[]
|
||||
>x : T
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
|
||||
const g04: <T>(x: T) => { value: T[] } = pipe(list, x => box(x));
|
||||
>g04 : <T>(x: T) => { value: T[]; }
|
||||
>x : T
|
||||
>value : T[]
|
||||
>pipe(list, x => box(x)) : (a: T) => { value: T[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>list : <T>(a: T) => T[]
|
||||
>x => box(x) : (x: T[]) => { value: T[]; }
|
||||
>x : T[]
|
||||
>box(x) : { value: T[]; }
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
>x : T[]
|
||||
|
||||
const g05: <T>(x: T) => { value: T[] } = pipe(x => list(x), x => box(x))
|
||||
>g05 : <T>(x: T) => { value: T[]; }
|
||||
>x : T
|
||||
>value : T[]
|
||||
>pipe(x => list(x), x => box(x)) : (x: T) => { value: T[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>x => list(x) : (x: T) => T[]
|
||||
>x : T
|
||||
>list(x) : T[]
|
||||
>list : <T>(a: T) => T[]
|
||||
>x : T
|
||||
>x => box(x) : (x: T[]) => { value: T[]; }
|
||||
>x : T[]
|
||||
>box(x) : { value: T[]; }
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
>x : T[]
|
||||
|
||||
const g06: <T>(x: T) => { value: T[] } = pipe(list, pipe(box));
|
||||
>g06 : <T>(x: T) => { value: T[]; }
|
||||
>x : T
|
||||
>value : T[]
|
||||
>pipe(list, pipe(box)) : (a: T) => { value: T[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>list : <T>(a: T) => T[]
|
||||
>pipe(box) : (x: T[]) => { value: T[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
|
||||
const g07: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(box));
|
||||
>g07 : <T>(x: T) => { value: T[]; }
|
||||
>x : T
|
||||
>value : T[]
|
||||
>pipe(x => list(x), pipe(box)) : (x: T) => { value: T[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>x => list(x) : (x: T) => T[]
|
||||
>x : T
|
||||
>list(x) : T[]
|
||||
>list : <T>(a: T) => T[]
|
||||
>x : T
|
||||
>pipe(box) : (x: T[]) => { value: T[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
|
||||
const g08: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(x => box(x)));
|
||||
>g08 : <T>(x: T) => { value: T[]; }
|
||||
>x : T
|
||||
>value : T[]
|
||||
>pipe(x => list(x), pipe(x => box(x))) : (x: T) => { value: T[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>x => list(x) : (x: T) => T[]
|
||||
>x : T
|
||||
>list(x) : T[]
|
||||
>list : <T>(a: T) => T[]
|
||||
>x : T
|
||||
>pipe(x => box(x)) : (x: T[]) => { value: T[]; }
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>x => box(x) : (x: T[]) => { value: T[]; }
|
||||
>x : T[]
|
||||
>box(x) : { value: T[]; }
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
>x : T[]
|
||||
|
||||
const g09: <T>(x: T) => number = pipe(list, x => x.length);
|
||||
>g09 : <T>(x: T) => number
|
||||
>x : T
|
||||
>pipe(list, x => x.length) : (a: T) => number
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>list : <T>(a: T) => T[]
|
||||
>x => x.length : (x: T[]) => number
|
||||
>x : T[]
|
||||
>x.length : number
|
||||
>x : T[]
|
||||
>length : number
|
||||
|
||||
const g10: <T extends { value: T }>(x: T) => T = pipe(foo);
|
||||
>g10 : <T extends { value: T; }>(x: T) => T
|
||||
>value : T
|
||||
>x : T
|
||||
>pipe(foo) : (x: T) => T
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>foo : <T extends { value: T; }>(x: T) => T
|
||||
|
||||
const g12: <T extends { value: T }>(x: T) => T = pipe(foo, foo);
|
||||
>g12 : <T extends { value: T; }>(x: T) => T
|
||||
>value : T
|
||||
>x : T
|
||||
>pipe(foo, foo) : (x: T) => T
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>foo : <T extends { value: T; }>(x: T) => T
|
||||
>foo : <T extends { value: T; }>(x: T) => T
|
||||
|
||||
declare function pipe2<A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D): (a: [A, C]) => [B, D];
|
||||
>pipe2 : <A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D) => (a: [A, C]) => [B, D]
|
||||
>ab : (a: A) => B
|
||||
>a : A
|
||||
>cd : (c: C) => D
|
||||
>c : C
|
||||
>a : [A, C]
|
||||
|
||||
const f20 = pipe2(list, box);
|
||||
>f20 : <T, V>(a: [T, V]) => [T[], { value: V; }]
|
||||
>pipe2(list, box) : <T, V>(a: [T, V]) => [T[], { value: V; }]
|
||||
>pipe2 : <A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D) => (a: [A, C]) => [B, D]
|
||||
>list : <T>(a: T) => T[]
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
|
||||
const f21 = pipe2(box, list);
|
||||
>f21 : <V, T>(a: [V, T]) => [{ value: V; }, T[]]
|
||||
>pipe2(box, list) : <V, T>(a: [V, T]) => [{ value: V; }, T[]]
|
||||
>pipe2 : <A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D) => (a: [A, C]) => [B, D]
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
>list : <T>(a: T) => T[]
|
||||
|
||||
const f22 = pipe2(list, list);
|
||||
>f22 : <T, T1>(a: [T, T1]) => [T[], T1[]]
|
||||
>pipe2(list, list) : <T, T1>(a: [T, T1]) => [T[], T1[]]
|
||||
>pipe2 : <A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D) => (a: [A, C]) => [B, D]
|
||||
>list : <T>(a: T) => T[]
|
||||
>list : <T>(a: T) => T[]
|
||||
|
||||
const f23 = pipe2(box, box);
|
||||
>f23 : <V, V1>(a: [V, V1]) => [{ value: V; }, { value: V1; }]
|
||||
>pipe2(box, box) : <V, V1>(a: [V, V1]) => [{ value: V; }, { value: V1; }]
|
||||
>pipe2 : <A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D) => (a: [A, C]) => [B, D]
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
|
||||
const f24 = pipe2(f20, f20);
|
||||
>f24 : <T, V, T1, V1>(a: [[T, V], [T1, V1]]) => [[T[], { value: V; }], [T1[], { value: V1; }]]
|
||||
>pipe2(f20, f20) : <T, V, T1, V1>(a: [[T, V], [T1, V1]]) => [[T[], { value: V; }], [T1[], { value: V1; }]]
|
||||
>pipe2 : <A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D) => (a: [A, C]) => [B, D]
|
||||
>f20 : <T, V>(a: [T, V]) => [T[], { value: V; }]
|
||||
>f20 : <T, V>(a: [T, V]) => [T[], { value: V; }]
|
||||
|
||||
const f25 = pipe2(foo, foo);
|
||||
>f25 : <T extends { value: T; }, T1 extends { value: T1; }>(a: [T, T1]) => [T, T1]
|
||||
>pipe2(foo, foo) : <T extends { value: T; }, T1 extends { value: T1; }>(a: [T, T1]) => [T, T1]
|
||||
>pipe2 : <A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D) => (a: [A, C]) => [B, D]
|
||||
>foo : <T extends { value: T; }>(x: T) => T
|
||||
>foo : <T extends { value: T; }>(x: T) => T
|
||||
|
||||
const f26 = pipe2(f25, f25);
|
||||
>f26 : <T extends { value: T; }, T1 extends { value: T1; }, T2 extends { value: T2; }, T3 extends { value: T3; }>(a: [[T, T1], [T2, T3]]) => [[T, T1], [T2, T3]]
|
||||
>pipe2(f25, f25) : <T extends { value: T; }, T1 extends { value: T1; }, T2 extends { value: T2; }, T3 extends { value: T3; }>(a: [[T, T1], [T2, T3]]) => [[T, T1], [T2, T3]]
|
||||
>pipe2 : <A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D) => (a: [A, C]) => [B, D]
|
||||
>f25 : <T extends { value: T; }, T1 extends { value: T1; }>(a: [T, T1]) => [T, T1]
|
||||
>f25 : <T extends { value: T; }, T1 extends { value: T1; }>(a: [T, T1]) => [T, T1]
|
||||
|
||||
declare function pipe3<A, B, C>(ab: (a: A) => B, ac: (a: A) => C): (a: A) => [B, C];
|
||||
>pipe3 : <A, B, C>(ab: (a: A) => B, ac: (a: A) => C) => (a: A) => [B, C]
|
||||
>ab : (a: A) => B
|
||||
>a : A
|
||||
>ac : (a: A) => C
|
||||
>a : A
|
||||
>a : A
|
||||
|
||||
const f30 = pipe3(list, box);
|
||||
>f30 : <T>(a: T) => [T[], { value: T; }]
|
||||
>pipe3(list, box) : <T>(a: T) => [T[], { value: T; }]
|
||||
>pipe3 : <A, B, C>(ab: (a: A) => B, ac: (a: A) => C) => (a: A) => [B, C]
|
||||
>list : <T>(a: T) => T[]
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
|
||||
const f31 = pipe3(box, list);
|
||||
>f31 : <V>(a: V) => [{ value: V; }, V[]]
|
||||
>pipe3(box, list) : <V>(a: V) => [{ value: V; }, V[]]
|
||||
>pipe3 : <A, B, C>(ab: (a: A) => B, ac: (a: A) => C) => (a: A) => [B, C]
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
>list : <T>(a: T) => T[]
|
||||
|
||||
const f32 = pipe3(list, list);
|
||||
>f32 : <T>(a: T) => [T[], T[]]
|
||||
>pipe3(list, list) : <T>(a: T) => [T[], T[]]
|
||||
>pipe3 : <A, B, C>(ab: (a: A) => B, ac: (a: A) => C) => (a: A) => [B, C]
|
||||
>list : <T>(a: T) => T[]
|
||||
>list : <T>(a: T) => T[]
|
||||
|
||||
declare function pipe4<A, B, C>(funcs: [(a: A) => B, (b: B) => C]): (a: A) => C;
|
||||
>pipe4 : <A, B, C>(funcs: [(a: A) => B, (b: B) => C]) => (a: A) => C
|
||||
>funcs : [(a: A) => B, (b: B) => C]
|
||||
>a : A
|
||||
>b : B
|
||||
>a : A
|
||||
|
||||
const f40 = pipe4([list, box]);
|
||||
>f40 : <T>(a: T) => { value: T[]; }
|
||||
>pipe4([list, box]) : <T>(a: T) => { value: T[]; }
|
||||
>pipe4 : <A, B, C>(funcs: [(a: A) => B, (b: B) => C]) => (a: A) => C
|
||||
>[list, box] : [<T>(a: T) => T[], <V>(x: V) => { value: V; }]
|
||||
>list : <T>(a: T) => T[]
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
|
||||
const f41 = pipe4([box, list]);
|
||||
>f41 : <V>(a: V) => { value: V; }[]
|
||||
>pipe4([box, list]) : <V>(a: V) => { value: V; }[]
|
||||
>pipe4 : <A, B, C>(funcs: [(a: A) => B, (b: B) => C]) => (a: A) => C
|
||||
>[box, list] : [<V>(x: V) => { value: V; }, <T>(a: T) => T[]]
|
||||
>box : <V>(x: V) => { value: V; }
|
||||
>list : <T>(a: T) => T[]
|
||||
|
||||
declare function pipe5<A, B>(f: (a: A) => B): { f: (a: A) => B };
|
||||
>pipe5 : <A, B>(f: (a: A) => B) => { f: (a: A) => B; }
|
||||
>f : (a: A) => B
|
||||
>a : A
|
||||
>f : (a: A) => B
|
||||
>a : A
|
||||
|
||||
const f50 = pipe5(list); // No higher order inference
|
||||
>f50 : { f: (a: {}) => {}[]; }
|
||||
>pipe5(list) : { f: (a: {}) => {}[]; }
|
||||
>pipe5 : <A, B>(f: (a: A) => B) => { f: (a: A) => B; }
|
||||
>list : <T>(a: T) => T[]
|
||||
|
||||
// #417
|
||||
|
||||
function mirror<A, B>(f: (a: A) => B): (a: A) => B { return f; }
|
||||
>mirror : <A, B>(f: (a: A) => B) => (a: A) => B
|
||||
>f : (a: A) => B
|
||||
>a : A
|
||||
>a : A
|
||||
>f : (a: A) => B
|
||||
|
||||
var identityM = mirror(identity);
|
||||
>identityM : <T>(a: T) => T
|
||||
>mirror(identity) : <T>(a: T) => T
|
||||
>mirror : <A, B>(f: (a: A) => B) => (a: A) => B
|
||||
>identity : <T>(value: T) => T
|
||||
|
||||
var x = 1;
|
||||
>x : number
|
||||
>1 : 1
|
||||
|
||||
var y = identity(x);
|
||||
>y : number
|
||||
>identity(x) : number
|
||||
>identity : <T>(value: T) => T
|
||||
>x : number
|
||||
|
||||
var z = identityM(x);
|
||||
>z : number
|
||||
>identityM(x) : number
|
||||
>identityM : <T>(a: T) => T
|
||||
>x : number
|
||||
|
||||
// #3038
|
||||
|
||||
export function keyOf<a>(value: { key: a; }): a {
|
||||
>keyOf : <a>(value: { key: a; }) => a
|
||||
>value : { key: a; }
|
||||
>key : a
|
||||
|
||||
return value.key;
|
||||
>value.key : a
|
||||
>value : { key: a; }
|
||||
>key : a
|
||||
}
|
||||
export interface Data {
|
||||
key: number;
|
||||
>key : number
|
||||
|
||||
value: Date;
|
||||
>value : Date
|
||||
}
|
||||
|
||||
var data: Data[] = [];
|
||||
>data : Data[]
|
||||
>[] : never[]
|
||||
|
||||
declare function toKeys<a>(values: a[], toKey: (value: a) => string): string[];
|
||||
>toKeys : <a>(values: a[], toKey: (value: a) => string) => string[]
|
||||
>values : a[]
|
||||
>toKey : (value: a) => string
|
||||
>value : a
|
||||
|
||||
toKeys(data, keyOf); // Error
|
||||
>toKeys(data, keyOf) : any
|
||||
>toKeys : <a>(values: a[], toKey: (value: a) => string) => string[]
|
||||
>data : Data[]
|
||||
>keyOf : <a>(value: { key: a; }) => a
|
||||
|
||||
// #9366
|
||||
|
||||
function flip<a, b, c>(f: (a: a, b: b) => c): (b: b, a: a) => c {
|
||||
>flip : <a, b, c>(f: (a: a, b: b) => c) => (b: b, a: a) => c
|
||||
>f : (a: a, b: b) => c
|
||||
>a : a
|
||||
>b : b
|
||||
>b : b
|
||||
>a : a
|
||||
|
||||
return (b: b, a: a) => f(a, b);
|
||||
>(b: b, a: a) => f(a, b) : (b: b, a: a) => c
|
||||
>b : b
|
||||
>a : a
|
||||
>f(a, b) : c
|
||||
>f : (a: a, b: b) => c
|
||||
>a : a
|
||||
>b : b
|
||||
}
|
||||
function zip<T, U>(x: T, y: U): [T, U] {
|
||||
>zip : <T, U>(x: T, y: U) => [T, U]
|
||||
>x : T
|
||||
>y : U
|
||||
|
||||
return [x, y];
|
||||
>[x, y] : [T, U]
|
||||
>x : T
|
||||
>y : U
|
||||
}
|
||||
|
||||
var expected: <T, U>(y: U, x: T) => [T, U] = flip(zip);
|
||||
>expected : <T, U>(y: U, x: T) => [T, U]
|
||||
>y : U
|
||||
>x : T
|
||||
>flip(zip) : (b: U, a: T) => [T, U]
|
||||
>flip : <a, b, c>(f: (a: a, b: b) => c) => (b: b, a: a) => c
|
||||
>zip : <T, U>(x: T, y: U) => [T, U]
|
||||
|
||||
var actual = flip(zip);
|
||||
>actual : <T, U>(b: U, a: T) => [T, U]
|
||||
>flip(zip) : <T, U>(b: U, a: T) => [T, U]
|
||||
>flip : <a, b, c>(f: (a: a, b: b) => c) => (b: b, a: a) => c
|
||||
>zip : <T, U>(x: T, y: U) => [T, U]
|
||||
|
||||
// #9366
|
||||
|
||||
const map = <T, U>(transform: (t: T) => U) =>
|
||||
>map : <T, U>(transform: (t: T) => U) => (arr: T[]) => U[]
|
||||
><T, U>(transform: (t: T) => U) => (arr: T[]) => arr.map(transform) : <T, U>(transform: (t: T) => U) => (arr: T[]) => U[]
|
||||
>transform : (t: T) => U
|
||||
>t : T
|
||||
|
||||
(arr: T[]) => arr.map(transform)
|
||||
>(arr: T[]) => arr.map(transform) : (arr: T[]) => U[]
|
||||
>arr : T[]
|
||||
>arr.map(transform) : U[]
|
||||
>arr.map : <U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any) => U[]
|
||||
>arr : T[]
|
||||
>map : <U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any) => U[]
|
||||
>transform : (t: T) => U
|
||||
|
||||
const identityStr = (t: string) => t;
|
||||
>identityStr : (t: string) => string
|
||||
>(t: string) => t : (t: string) => string
|
||||
>t : string
|
||||
>t : string
|
||||
|
||||
const arr: string[] = map(identityStr)(['a']);
|
||||
>arr : string[]
|
||||
>map(identityStr)(['a']) : string[]
|
||||
>map(identityStr) : (arr: string[]) => string[]
|
||||
>map : <T, U>(transform: (t: T) => U) => (arr: T[]) => U[]
|
||||
>identityStr : (t: string) => string
|
||||
>['a'] : string[]
|
||||
>'a' : "a"
|
||||
|
||||
const arr1: string[] = map(identity)(['a']);
|
||||
>arr1 : string[]
|
||||
>map(identity)(['a']) : string[]
|
||||
>map(identity) : <T>(arr: T[]) => T[]
|
||||
>map : <T, U>(transform: (t: T) => U) => (arr: T[]) => U[]
|
||||
>identity : <T>(value: T) => T
|
||||
>['a'] : string[]
|
||||
>'a' : "a"
|
||||
|
||||
// #9949
|
||||
|
||||
function of2<a, b>(one: a, two: b): [a, b] {
|
||||
>of2 : <a, b>(one: a, two: b) => [a, b]
|
||||
>one : a
|
||||
>two : b
|
||||
|
||||
return [one, two];
|
||||
>[one, two] : [a, b]
|
||||
>one : a
|
||||
>two : b
|
||||
}
|
||||
|
||||
const flipped = flip(of2);
|
||||
>flipped : <a, b>(b: b, a: a) => [a, b]
|
||||
>flip(of2) : <a, b>(b: b, a: a) => [a, b]
|
||||
>flip : <a, b, c>(f: (a: a, b: b) => c) => (b: b, a: a) => c
|
||||
>of2 : <a, b>(one: a, two: b) => [a, b]
|
||||
|
||||
// #29904.1
|
||||
|
||||
type Component<P> = (props: P) => {};
|
||||
>Component : Component<P>
|
||||
>props : P
|
||||
|
||||
declare const myHoc1: <P>(C: Component<P>) => Component<P>;
|
||||
>myHoc1 : <P>(C: Component<P>) => Component<P>
|
||||
>C : Component<P>
|
||||
|
||||
declare const myHoc2: <P>(C: Component<P>) => Component<P>;
|
||||
>myHoc2 : <P>(C: Component<P>) => Component<P>
|
||||
>C : Component<P>
|
||||
|
||||
declare const MyComponent1: Component<{ foo: 1 }>;
|
||||
>MyComponent1 : Component<{ foo: 1; }>
|
||||
>foo : 1
|
||||
|
||||
const enhance = pipe(
|
||||
>enhance : <P>(C: Component<P>) => Component<P>
|
||||
>pipe( myHoc1, myHoc2,) : <P>(C: Component<P>) => Component<P>
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
|
||||
myHoc1,
|
||||
>myHoc1 : <P>(C: Component<P>) => Component<P>
|
||||
|
||||
myHoc2,
|
||||
>myHoc2 : <P>(C: Component<P>) => Component<P>
|
||||
|
||||
);
|
||||
|
||||
const MyComponent2 = enhance(MyComponent1);
|
||||
>MyComponent2 : Component<{ foo: 1; }>
|
||||
>enhance(MyComponent1) : Component<{ foo: 1; }>
|
||||
>enhance : <P>(C: Component<P>) => Component<P>
|
||||
>MyComponent1 : Component<{ foo: 1; }>
|
||||
|
||||
// #29904.2
|
||||
|
||||
const fn20 = pipe((_a?: {}) => 1);
|
||||
>fn20 : (_a?: {} | undefined) => number
|
||||
>pipe((_a?: {}) => 1) : (_a?: {} | undefined) => number
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
>(_a?: {}) => 1 : (_a?: {} | undefined) => number
|
||||
>_a : {} | undefined
|
||||
>1 : 1
|
||||
|
||||
// #29904.3
|
||||
|
||||
type Fn = (n: number) => number;
|
||||
>Fn : Fn
|
||||
>n : number
|
||||
|
||||
const fn30: Fn = pipe(
|
||||
>fn30 : Fn
|
||||
>pipe( x => x + 1, x => x * 2,) : (x: number) => number
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
|
||||
x => x + 1,
|
||||
>x => x + 1 : (x: number) => number
|
||||
>x : number
|
||||
>x + 1 : number
|
||||
>x : number
|
||||
>1 : 1
|
||||
|
||||
x => x * 2,
|
||||
>x => x * 2 : (x: number) => number
|
||||
>x : number
|
||||
>x * 2 : number
|
||||
>x : number
|
||||
>2 : 2
|
||||
|
||||
);
|
||||
|
||||
const promise = Promise.resolve(1);
|
||||
>promise : Promise<number>
|
||||
>Promise.resolve(1) : Promise<number>
|
||||
>Promise.resolve : { <T>(value: T | PromiseLike<T>): Promise<T>; (): Promise<void>; }
|
||||
>Promise : PromiseConstructor
|
||||
>resolve : { <T>(value: T | PromiseLike<T>): Promise<T>; (): Promise<void>; }
|
||||
>1 : 1
|
||||
|
||||
promise.then(
|
||||
>promise.then( pipe( x => x + 1, x => x * 2, ),) : Promise<number>
|
||||
>promise.then : <TResult1 = number, TResult2 = never>(onfulfilled?: ((value: number) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => Promise<TResult1 | TResult2>
|
||||
>promise : Promise<number>
|
||||
>then : <TResult1 = number, TResult2 = never>(onfulfilled?: ((value: number) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => Promise<TResult1 | TResult2>
|
||||
|
||||
pipe(
|
||||
>pipe( x => x + 1, x => x * 2, ) : (x: number) => number
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
|
||||
x => x + 1,
|
||||
>x => x + 1 : (x: number) => number
|
||||
>x : number
|
||||
>x + 1 : number
|
||||
>x : number
|
||||
>1 : 1
|
||||
|
||||
x => x * 2,
|
||||
>x => x * 2 : (x: number) => number
|
||||
>x : number
|
||||
>x * 2 : number
|
||||
>x : number
|
||||
>2 : 2
|
||||
|
||||
),
|
||||
);
|
||||
|
||||
// #29904.4
|
||||
|
||||
declare const getString: () => string;
|
||||
>getString : () => string
|
||||
|
||||
declare const orUndefined: (name: string) => string | undefined;
|
||||
>orUndefined : (name: string) => string | undefined
|
||||
>name : string
|
||||
|
||||
declare const identity: <T>(value: T) => T;
|
||||
>identity : <T>(value: T) => T
|
||||
>value : T
|
||||
|
||||
const fn40 = pipe(
|
||||
>fn40 : () => string | undefined
|
||||
>pipe( getString, string => orUndefined(string), identity,) : () => string | undefined
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
|
||||
getString,
|
||||
>getString : () => string
|
||||
|
||||
string => orUndefined(string),
|
||||
>string => orUndefined(string) : (string: string) => string | undefined
|
||||
>string : string
|
||||
>orUndefined(string) : string | undefined
|
||||
>orUndefined : (name: string) => string | undefined
|
||||
>string : string
|
||||
|
||||
identity,
|
||||
>identity : <T>(value: T) => T
|
||||
|
||||
);
|
||||
|
||||
// #29904.6
|
||||
|
||||
declare const getArray: () => string[];
|
||||
>getArray : () => string[]
|
||||
|
||||
declare const first: <T>(ts: T[]) => T;
|
||||
>first : <T>(ts: T[]) => T
|
||||
>ts : T[]
|
||||
|
||||
const fn60 = pipe(
|
||||
>fn60 : () => string
|
||||
>pipe( getArray, x => x, first,) : () => string
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
|
||||
getArray,
|
||||
>getArray : () => string[]
|
||||
|
||||
x => x,
|
||||
>x => x : (x: string[]) => string[]
|
||||
>x : string[]
|
||||
>x : string[]
|
||||
|
||||
first,
|
||||
>first : <T>(ts: T[]) => T
|
||||
|
||||
);
|
||||
|
||||
const fn61 = pipe(
|
||||
>fn61 : () => string
|
||||
>pipe( getArray, identity, first,) : () => string
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
|
||||
getArray,
|
||||
>getArray : () => string[]
|
||||
|
||||
identity,
|
||||
>identity : <T>(value: T) => T
|
||||
|
||||
first,
|
||||
>first : <T>(ts: T[]) => T
|
||||
|
||||
);
|
||||
|
||||
const fn62 = pipe(
|
||||
>fn62 : () => string
|
||||
>pipe( getArray, x => x, x => first(x),) : () => string
|
||||
>pipe : { <A extends any[], B>(ab: (...args: A) => B): (...args: A) => B; <A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C; <A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D; }
|
||||
|
||||
getArray,
|
||||
>getArray : () => string[]
|
||||
|
||||
x => x,
|
||||
>x => x : (x: string[]) => string[]
|
||||
>x : string[]
|
||||
>x : string[]
|
||||
|
||||
x => first(x),
|
||||
>x => first(x) : (x: string[]) => string
|
||||
>x : string[]
|
||||
>first(x) : string
|
||||
>first : <T>(ts: T[]) => T
|
||||
>x : string[]
|
||||
|
||||
);
|
||||
|
||||
@@ -309,7 +309,7 @@ declare function f16<A, B>(a: A, b: B): A | B;
|
||||
declare let x20: number;
|
||||
declare let x21: string;
|
||||
declare let x22: string | number;
|
||||
declare let x23: unknown;
|
||||
declare let x23: string | number;
|
||||
declare let x24: string | number;
|
||||
declare let x30: string;
|
||||
declare let x31: string | number;
|
||||
|
||||
@@ -462,8 +462,8 @@ let x22 = call(f15, "hello", 42); // string | number
|
||||
>42 : 42
|
||||
|
||||
let x23 = call(f16, "hello", 42); // unknown
|
||||
>x23 : unknown
|
||||
>call(f16, "hello", 42) : unknown
|
||||
>x23 : string | number
|
||||
>call(f16, "hello", 42) : string | number
|
||||
>call : <T extends unknown[], U>(f: (...args: T) => U, ...args: T) => U
|
||||
>f16 : <A, B>(a: A, b: B) => A | B
|
||||
>"hello" : "hello"
|
||||
|
||||
@@ -129,8 +129,8 @@ function curry1<A, B, C>(f: (a: A, b: B) => C): (ax: A) => (bx: B) => C {
|
||||
}
|
||||
|
||||
var cfilter = curry1(filter);
|
||||
>cfilter : (ax: {}) => (bx: {}) => {}[]
|
||||
>curry1(filter) : (ax: {}) => (bx: {}) => {}[]
|
||||
>cfilter : <A>(ax: (a: A) => boolean) => (bx: A[]) => A[]
|
||||
>curry1(filter) : <A>(ax: (a: A) => boolean) => (bx: A[]) => A[]
|
||||
>curry1 : <A, B, C>(f: (a: A, b: B) => C) => (ax: A) => (bx: B) => C
|
||||
>filter : <A>(f: (a: A) => boolean, ar: A[]) => A[]
|
||||
|
||||
@@ -149,11 +149,11 @@ function countWhere_1<A>(pred: (a: A) => boolean): (a: A[]) => number {
|
||||
>a : A[]
|
||||
|
||||
return compose(length2, cfilter(pred));
|
||||
>compose(length2, cfilter(pred)) : (a: {}) => number
|
||||
>compose(length2, cfilter(pred)) : (a: A[]) => number
|
||||
>compose : <A, B, C>(f: (b: B) => C, g: (a: A) => B) => (a: A) => C
|
||||
>length2 : <A>(ar: A[]) => number
|
||||
>cfilter(pred) : (bx: {}) => {}[]
|
||||
>cfilter : (ax: {}) => (bx: {}) => {}[]
|
||||
>cfilter(pred) : (bx: A[]) => A[]
|
||||
>cfilter : <A>(ax: (a: A) => boolean) => (bx: A[]) => A[]
|
||||
>pred : (a: A) => boolean
|
||||
}
|
||||
|
||||
@@ -164,14 +164,14 @@ function countWhere_2<A>(pred: (a: A) => boolean): (a: A[]) => number {
|
||||
>a : A[]
|
||||
|
||||
var where = cfilter(pred);
|
||||
>where : (bx: {}) => {}[]
|
||||
>cfilter(pred) : (bx: {}) => {}[]
|
||||
>cfilter : (ax: {}) => (bx: {}) => {}[]
|
||||
>where : (bx: A[]) => A[]
|
||||
>cfilter(pred) : (bx: A[]) => A[]
|
||||
>cfilter : <A>(ax: (a: A) => boolean) => (bx: A[]) => A[]
|
||||
>pred : (a: A) => boolean
|
||||
|
||||
return compose(length2, where);
|
||||
>compose(length2, where) : (a: {}) => number
|
||||
>compose(length2, where) : (a: A[]) => number
|
||||
>compose : <A, B, C>(f: (b: B) => C, g: (a: A) => B) => (a: A) => C
|
||||
>length2 : <A>(ar: A[]) => number
|
||||
>where : (bx: {}) => {}[]
|
||||
>where : (bx: A[]) => A[]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
//// [tests/cases/compiler/noCrashUMDMergedWithGlobalValue.ts] ////
|
||||
|
||||
//// [other.d.ts]
|
||||
export as namespace SomeInterface;
|
||||
export type Action = "PUSH" | "POP" | "REPLACE";
|
||||
|
||||
//// [main.ts]
|
||||
interface SomeInterface {
|
||||
readonly length: number;
|
||||
}
|
||||
declare const value: SomeInterface;
|
||||
|
||||
|
||||
//// [main.js]
|
||||
@@ -0,0 +1,18 @@
|
||||
=== /other.d.ts ===
|
||||
export as namespace SomeInterface;
|
||||
>SomeInterface : Symbol(SomeInterface, Decl(other.d.ts, 0, 0))
|
||||
|
||||
export type Action = "PUSH" | "POP" | "REPLACE";
|
||||
>Action : Symbol(Action, Decl(other.d.ts, 0, 34))
|
||||
|
||||
=== /main.ts ===
|
||||
interface SomeInterface {
|
||||
>SomeInterface : Symbol("/other", Decl(other.d.ts, 0, 0), Decl(main.ts, 0, 0))
|
||||
|
||||
readonly length: number;
|
||||
>length : Symbol(length, Decl(main.ts, 0, 25))
|
||||
}
|
||||
declare const value: SomeInterface;
|
||||
>value : Symbol(value, Decl(main.ts, 3, 13))
|
||||
>SomeInterface : Symbol("/other", Decl(other.d.ts, 0, 0), Decl(main.ts, 0, 0))
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
=== /other.d.ts ===
|
||||
export as namespace SomeInterface;
|
||||
>SomeInterface : typeof import("/other")
|
||||
|
||||
export type Action = "PUSH" | "POP" | "REPLACE";
|
||||
>Action : Action
|
||||
|
||||
=== /main.ts ===
|
||||
interface SomeInterface {
|
||||
readonly length: number;
|
||||
>length : number
|
||||
}
|
||||
declare const value: SomeInterface;
|
||||
>value : import("/other")
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
//// [returnTypePredicateIsInstantiateInContextOfTarget.tsx]
|
||||
/// <reference path="/.lib/react16.d.ts" />
|
||||
import * as React from "react";
|
||||
class TestComponent extends React.Component<{ isAny: <T>(obj: any) => obj is T }> {
|
||||
static defaultProps = {
|
||||
isAny: TestComponent.isAny
|
||||
}
|
||||
|
||||
// Type guard is defined as a static class property
|
||||
static isAny<T>(obj: any): obj is T {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const TestRender = () => <TestComponent />;
|
||||
|
||||
//// [returnTypePredicateIsInstantiateInContextOfTarget.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
/// <reference path="react16.d.ts" />
|
||||
var React = require("react");
|
||||
var TestComponent = /** @class */ (function (_super) {
|
||||
__extends(TestComponent, _super);
|
||||
function TestComponent() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
// Type guard is defined as a static class property
|
||||
TestComponent.isAny = function (obj) {
|
||||
return true;
|
||||
};
|
||||
TestComponent.defaultProps = {
|
||||
isAny: TestComponent.isAny
|
||||
};
|
||||
return TestComponent;
|
||||
}(React.Component));
|
||||
var TestRender = function () { return React.createElement(TestComponent, null); };
|
||||
@@ -0,0 +1,42 @@
|
||||
=== tests/cases/compiler/returnTypePredicateIsInstantiateInContextOfTarget.tsx ===
|
||||
/// <reference path="react16.d.ts" />
|
||||
import * as React from "react";
|
||||
>React : Symbol(React, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 1, 6))
|
||||
|
||||
class TestComponent extends React.Component<{ isAny: <T>(obj: any) => obj is T }> {
|
||||
>TestComponent : Symbol(TestComponent, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 1, 31))
|
||||
>React.Component : Symbol(React.Component, Decl(react16.d.ts, 345, 54), Decl(react16.d.ts, 349, 94))
|
||||
>React : Symbol(React, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 1, 6))
|
||||
>Component : Symbol(React.Component, Decl(react16.d.ts, 345, 54), Decl(react16.d.ts, 349, 94))
|
||||
>isAny : Symbol(isAny, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 2, 45))
|
||||
>T : Symbol(T, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 2, 54))
|
||||
>obj : Symbol(obj, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 2, 57))
|
||||
>obj : Symbol(obj, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 2, 57))
|
||||
>T : Symbol(T, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 2, 54))
|
||||
|
||||
static defaultProps = {
|
||||
>defaultProps : Symbol(TestComponent.defaultProps, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 2, 83))
|
||||
|
||||
isAny: TestComponent.isAny
|
||||
>isAny : Symbol(isAny, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 3, 27))
|
||||
>TestComponent.isAny : Symbol(TestComponent.isAny, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 5, 5))
|
||||
>TestComponent : Symbol(TestComponent, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 1, 31))
|
||||
>isAny : Symbol(TestComponent.isAny, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 5, 5))
|
||||
}
|
||||
|
||||
// Type guard is defined as a static class property
|
||||
static isAny<T>(obj: any): obj is T {
|
||||
>isAny : Symbol(TestComponent.isAny, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 5, 5))
|
||||
>T : Symbol(T, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 8, 17))
|
||||
>obj : Symbol(obj, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 8, 20))
|
||||
>obj : Symbol(obj, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 8, 20))
|
||||
>T : Symbol(T, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 8, 17))
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const TestRender = () => <TestComponent />;
|
||||
>TestRender : Symbol(TestRender, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 13, 5))
|
||||
>TestComponent : Symbol(TestComponent, Decl(returnTypePredicateIsInstantiateInContextOfTarget.tsx, 1, 31))
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
=== tests/cases/compiler/returnTypePredicateIsInstantiateInContextOfTarget.tsx ===
|
||||
/// <reference path="react16.d.ts" />
|
||||
import * as React from "react";
|
||||
>React : typeof React
|
||||
|
||||
class TestComponent extends React.Component<{ isAny: <T>(obj: any) => obj is T }> {
|
||||
>TestComponent : TestComponent
|
||||
>React.Component : React.Component<{ isAny: <T>(obj: any) => obj is T; }, {}, any>
|
||||
>React : typeof React
|
||||
>Component : typeof React.Component
|
||||
>isAny : <T>(obj: any) => obj is T
|
||||
>obj : any
|
||||
|
||||
static defaultProps = {
|
||||
>defaultProps : { isAny: <T>(obj: any) => obj is T; }
|
||||
>{ isAny: TestComponent.isAny } : { isAny: <T>(obj: any) => obj is T; }
|
||||
|
||||
isAny: TestComponent.isAny
|
||||
>isAny : <T>(obj: any) => obj is T
|
||||
>TestComponent.isAny : <T>(obj: any) => obj is T
|
||||
>TestComponent : typeof TestComponent
|
||||
>isAny : <T>(obj: any) => obj is T
|
||||
}
|
||||
|
||||
// Type guard is defined as a static class property
|
||||
static isAny<T>(obj: any): obj is T {
|
||||
>isAny : <T>(obj: any) => obj is T
|
||||
>obj : any
|
||||
|
||||
return true;
|
||||
>true : true
|
||||
}
|
||||
}
|
||||
|
||||
const TestRender = () => <TestComponent />;
|
||||
>TestRender : () => JSX.Element
|
||||
>() => <TestComponent /> : () => JSX.Element
|
||||
><TestComponent /> : JSX.Element
|
||||
>TestComponent : typeof TestComponent
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// @declaration: true
|
||||
// @filename: /Helpers.ts
|
||||
export type StringKeyOf<TObj> = Extract<string, keyof TObj>;
|
||||
|
||||
// @filename: /FromFactor.ts
|
||||
export type RowToColumns<TColumns> = {
|
||||
[TName in StringKeyOf<TColumns>]: any;
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
// @strict: true
|
||||
// @target: es2015
|
||||
|
||||
declare function pipe<A extends any[], B>(ab: (...args: A) => B): (...args: A) => B;
|
||||
declare function pipe<A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C;
|
||||
declare function pipe<A extends any[], B, C, D>(ab: (...args: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...args: A) => D;
|
||||
|
||||
declare function list<T>(a: T): T[];
|
||||
declare function box<V>(x: V): { value: V };
|
||||
declare function foo<T extends { value: T }>(x: T): T;
|
||||
|
||||
const f00 = pipe(list);
|
||||
const f01 = pipe(list, box);
|
||||
const f02 = pipe(box, list);
|
||||
const f03 = pipe(x => list(x), box);
|
||||
const f04 = pipe(list, x => box(x));
|
||||
const f05 = pipe(x => list(x), x => box(x))
|
||||
const f06 = pipe(list, pipe(box));
|
||||
const f07 = pipe(x => list(x), pipe(box));
|
||||
const f08 = pipe(x => list(x), pipe(x => box(x)));
|
||||
const f09 = pipe(list, x => x.length);
|
||||
const f10 = pipe(foo);
|
||||
const f11 = pipe(foo, foo);
|
||||
|
||||
const g00: <T>(x: T) => T[] = pipe(list);
|
||||
const g01: <T>(x: T) => { value: T[] } = pipe(list, box);
|
||||
const g02: <T>(x: T) => { value: T }[] = pipe(box, list);
|
||||
const g03: <T>(x: T) => { value: T[] } = pipe(x => list(x), box);
|
||||
const g04: <T>(x: T) => { value: T[] } = pipe(list, x => box(x));
|
||||
const g05: <T>(x: T) => { value: T[] } = pipe(x => list(x), x => box(x))
|
||||
const g06: <T>(x: T) => { value: T[] } = pipe(list, pipe(box));
|
||||
const g07: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(box));
|
||||
const g08: <T>(x: T) => { value: T[] } = pipe(x => list(x), pipe(x => box(x)));
|
||||
const g09: <T>(x: T) => number = pipe(list, x => x.length);
|
||||
const g10: <T extends { value: T }>(x: T) => T = pipe(foo);
|
||||
const g12: <T extends { value: T }>(x: T) => T = pipe(foo, foo);
|
||||
|
||||
declare function pipe2<A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D): (a: [A, C]) => [B, D];
|
||||
|
||||
const f20 = pipe2(list, box);
|
||||
const f21 = pipe2(box, list);
|
||||
const f22 = pipe2(list, list);
|
||||
const f23 = pipe2(box, box);
|
||||
const f24 = pipe2(f20, f20);
|
||||
const f25 = pipe2(foo, foo);
|
||||
const f26 = pipe2(f25, f25);
|
||||
|
||||
declare function pipe3<A, B, C>(ab: (a: A) => B, ac: (a: A) => C): (a: A) => [B, C];
|
||||
|
||||
const f30 = pipe3(list, box);
|
||||
const f31 = pipe3(box, list);
|
||||
const f32 = pipe3(list, list);
|
||||
|
||||
declare function pipe4<A, B, C>(funcs: [(a: A) => B, (b: B) => C]): (a: A) => C;
|
||||
|
||||
const f40 = pipe4([list, box]);
|
||||
const f41 = pipe4([box, list]);
|
||||
|
||||
declare function pipe5<A, B>(f: (a: A) => B): { f: (a: A) => B };
|
||||
|
||||
const f50 = pipe5(list); // No higher order inference
|
||||
|
||||
// #417
|
||||
|
||||
function mirror<A, B>(f: (a: A) => B): (a: A) => B { return f; }
|
||||
var identityM = mirror(identity);
|
||||
|
||||
var x = 1;
|
||||
var y = identity(x);
|
||||
var z = identityM(x);
|
||||
|
||||
// #3038
|
||||
|
||||
export function keyOf<a>(value: { key: a; }): a {
|
||||
return value.key;
|
||||
}
|
||||
export interface Data {
|
||||
key: number;
|
||||
value: Date;
|
||||
}
|
||||
|
||||
var data: Data[] = [];
|
||||
|
||||
declare function toKeys<a>(values: a[], toKey: (value: a) => string): string[];
|
||||
|
||||
toKeys(data, keyOf); // Error
|
||||
|
||||
// #9366
|
||||
|
||||
function flip<a, b, c>(f: (a: a, b: b) => c): (b: b, a: a) => c {
|
||||
return (b: b, a: a) => f(a, b);
|
||||
}
|
||||
function zip<T, U>(x: T, y: U): [T, U] {
|
||||
return [x, y];
|
||||
}
|
||||
|
||||
var expected: <T, U>(y: U, x: T) => [T, U] = flip(zip);
|
||||
var actual = flip(zip);
|
||||
|
||||
// #9366
|
||||
|
||||
const map = <T, U>(transform: (t: T) => U) =>
|
||||
(arr: T[]) => arr.map(transform)
|
||||
|
||||
const identityStr = (t: string) => t;
|
||||
|
||||
const arr: string[] = map(identityStr)(['a']);
|
||||
const arr1: string[] = map(identity)(['a']);
|
||||
|
||||
// #9949
|
||||
|
||||
function of2<a, b>(one: a, two: b): [a, b] {
|
||||
return [one, two];
|
||||
}
|
||||
|
||||
const flipped = flip(of2);
|
||||
|
||||
// #29904.1
|
||||
|
||||
type Component<P> = (props: P) => {};
|
||||
|
||||
declare const myHoc1: <P>(C: Component<P>) => Component<P>;
|
||||
declare const myHoc2: <P>(C: Component<P>) => Component<P>;
|
||||
|
||||
declare const MyComponent1: Component<{ foo: 1 }>;
|
||||
|
||||
const enhance = pipe(
|
||||
myHoc1,
|
||||
myHoc2,
|
||||
);
|
||||
|
||||
const MyComponent2 = enhance(MyComponent1);
|
||||
|
||||
// #29904.2
|
||||
|
||||
const fn20 = pipe((_a?: {}) => 1);
|
||||
|
||||
// #29904.3
|
||||
|
||||
type Fn = (n: number) => number;
|
||||
const fn30: Fn = pipe(
|
||||
x => x + 1,
|
||||
x => x * 2,
|
||||
);
|
||||
|
||||
const promise = Promise.resolve(1);
|
||||
promise.then(
|
||||
pipe(
|
||||
x => x + 1,
|
||||
x => x * 2,
|
||||
),
|
||||
);
|
||||
|
||||
// #29904.4
|
||||
|
||||
declare const getString: () => string;
|
||||
declare const orUndefined: (name: string) => string | undefined;
|
||||
declare const identity: <T>(value: T) => T;
|
||||
|
||||
const fn40 = pipe(
|
||||
getString,
|
||||
string => orUndefined(string),
|
||||
identity,
|
||||
);
|
||||
|
||||
// #29904.6
|
||||
|
||||
declare const getArray: () => string[];
|
||||
declare const first: <T>(ts: T[]) => T;
|
||||
|
||||
const fn60 = pipe(
|
||||
getArray,
|
||||
x => x,
|
||||
first,
|
||||
);
|
||||
|
||||
const fn61 = pipe(
|
||||
getArray,
|
||||
identity,
|
||||
first,
|
||||
);
|
||||
|
||||
const fn62 = pipe(
|
||||
getArray,
|
||||
x => x,
|
||||
x => first(x),
|
||||
);
|
||||
@@ -0,0 +1,9 @@
|
||||
//@filename: /other.d.ts
|
||||
export as namespace SomeInterface;
|
||||
export type Action = "PUSH" | "POP" | "REPLACE";
|
||||
|
||||
//@filename: /main.ts
|
||||
interface SomeInterface {
|
||||
readonly length: number;
|
||||
}
|
||||
declare const value: SomeInterface;
|
||||
@@ -0,0 +1,16 @@
|
||||
// @jsx: react
|
||||
// @strict: true
|
||||
/// <reference path="/.lib/react16.d.ts" />
|
||||
import * as React from "react";
|
||||
class TestComponent extends React.Component<{ isAny: <T>(obj: any) => obj is T }> {
|
||||
static defaultProps = {
|
||||
isAny: TestComponent.isAny
|
||||
}
|
||||
|
||||
// Type guard is defined as a static class property
|
||||
static isAny<T>(obj: any): obj is T {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const TestRender = () => <TestComponent />;
|
||||
@@ -0,0 +1,17 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function f(/*a*/a?: number, b: string = "1"/*b*/): string {
|
||||
//// return b;
|
||||
////}
|
||||
////f();
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `function f({ a, b = "1" }: { a?: number; b?: string; } = {}): string {
|
||||
return b;
|
||||
}
|
||||
f();`
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const foo = /*a*/(a: number, b: number)/*b*/ => { };
|
||||
////foo(1, 2);
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `const foo = ({ a, b }: { a: number; b: number; }) => { };
|
||||
foo({ a: 1, b: 2 });`
|
||||
});
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const foo: (a: number, b: number) => number = /*a*/(a: number, b: number)/*b*/ => a + b;
|
||||
////foo(1, 2);
|
||||
|
||||
goTo.select("a", "b");
|
||||
verify.not.refactorAvailable("Convert to named parameters");
|
||||
@@ -0,0 +1,17 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function /*a*/foo/*b*/(a: number, b: number, ...rest: number[]) {
|
||||
//// return a + b;
|
||||
////}
|
||||
////foo(/**a*/ 1 /**b*/, /**c*/ 2 /**d*/, /**e*/ 3 /**f*/, /**g*/ 4 /**h*/);
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `function foo({ a, b, rest = [] }: { a: number; b: number; rest?: number[]; }) {
|
||||
return a + b;
|
||||
}
|
||||
foo({ /**a*/ a: 1 /**b*/, /**c*/ b: 2 /**d*/, rest: [/**e*/ 3 /**f*/, /**g*/ 4 /**h*/] });`
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function /*a*/foo/*b*/(a: number, b: number, ...rest: number[]) {
|
||||
//// return a + b;
|
||||
////}
|
||||
////foo(
|
||||
//// /**a*/
|
||||
//// 1,
|
||||
//// /**c*/
|
||||
//// 2,
|
||||
//// /**e*/
|
||||
//// 3,
|
||||
//// /**g*/
|
||||
//// 4);
|
||||
|
||||
goTo.select("a", "b");
|
||||
/* The expected content is currently wrong. The new argument object has the wrong formatting. */
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `function foo({ a, b, rest = [] }: { a: number; b: number; rest?: number[]; }) {
|
||||
return a + b;
|
||||
}
|
||||
foo(
|
||||
{ /**a*/
|
||||
a: 1, /**c*/
|
||||
b: 2, rest: [
|
||||
/**e*/
|
||||
3,
|
||||
/**g*/
|
||||
4]
|
||||
});`
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function foo(/*a*/a: number, b: number/*b*/) {
|
||||
//// return { bar: () => a + b };
|
||||
////}
|
||||
////var x = foo(1, 2).bar();
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `function foo({ a, b }: { a: number; b: number; }) {
|
||||
return { bar: () => a + b };
|
||||
}
|
||||
var x = foo({ a: 1, b: 2 }).bar();`
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////class Foo {
|
||||
//// /*a*/constructor/*b*/(a: number, b: number) { }
|
||||
////}
|
||||
////const fooAlias = Foo;
|
||||
////const newFoo = new fooAlias(1, 2);
|
||||
|
||||
goTo.select("a", "b");
|
||||
// Refactor should not make changes
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `class Foo {
|
||||
constructor(a: number, b: number) { }
|
||||
}
|
||||
const fooAlias = Foo;
|
||||
const newFoo = new fooAlias(1, 2);`
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////class C {
|
||||
//// static a: number = 2;
|
||||
//// /*a*/constructor/*b*/(a: number, b: number) { }
|
||||
////}
|
||||
////const newC = new C(1, 2);
|
||||
////const b = C.a;
|
||||
////C["a"] = 3;
|
||||
////let c: C;
|
||||
////function f(c: C) { }
|
||||
////class B extends C { }
|
||||
////class A implements C { }
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `class C {
|
||||
static a: number = 2;
|
||||
constructor({ a, b }: { a: number; b: number; }) { }
|
||||
}
|
||||
const newC = new C({ a: 1, b: 2 });
|
||||
const b = C.a;
|
||||
C["a"] = 3;
|
||||
let c: C;
|
||||
function f(c: C) { }
|
||||
class B extends C { }
|
||||
class A implements C { }`
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const c = class {
|
||||
//// constructor(/*a*/a: number, b = { x: 1 }/*b*/) { }
|
||||
////}
|
||||
////var x = new c(2);
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `const c = class {
|
||||
constructor({ a, b = { x: 1 } }: { a: number; b?: { x: number; }; }) { }
|
||||
}
|
||||
var x = new c({ a: 2 });`
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const c = class C {
|
||||
//// static a: number = 2;
|
||||
//// /*a*/constructor/*b*/(a: number, b: number) { }
|
||||
////}
|
||||
////const a = new c(0, 1);
|
||||
////const b = c.a;
|
||||
////c["a"] = 3;
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `const c = class C {
|
||||
static a: number = 2;
|
||||
constructor({ a, b }: { a: number; b: number; }) { }
|
||||
}
|
||||
const a = new c({ a: 0, b: 1 });
|
||||
const b = c.a;
|
||||
c["a"] = 3;`
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const foo = class Foo {
|
||||
//// /*a*/constructor/*b*/(a: number, b: number) { }
|
||||
////}
|
||||
////class Bar extends foo {
|
||||
//// constructor() {
|
||||
//// super(1, 2);
|
||||
//// }
|
||||
////}
|
||||
|
||||
goTo.select("a", "b");
|
||||
// Refactor should not make changes
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `const foo = class Foo {
|
||||
constructor(a: number, b: number) { }
|
||||
}
|
||||
class Bar extends foo {
|
||||
constructor() {
|
||||
super(1, 2);
|
||||
}
|
||||
}`
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////class Foo<T> {
|
||||
//// /*a*/bar/*b*/(t: T, s: T) {
|
||||
//// return s;
|
||||
//// }
|
||||
////}
|
||||
////var foo = new Foo();
|
||||
////foo.bar("a", "b");
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `class Foo<T> {
|
||||
bar({ t, s }: { t: T; s: T; }) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
var foo = new Foo();
|
||||
foo.bar({ t: "a", s: "b" });`
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////class Foo {
|
||||
//// t: string;
|
||||
//// s: string;
|
||||
//// /*a*/constructor/*b*/(t: string, s: string) {
|
||||
//// this.t = t;
|
||||
//// this.s = s;
|
||||
//// }
|
||||
////}
|
||||
////var foo = new Foo("a", "b");
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `class Foo {
|
||||
t: string;
|
||||
s: string;
|
||||
constructor({ t, s }: { t: string; s: string; }) {
|
||||
this.t = t;
|
||||
this.s = s;
|
||||
}
|
||||
}
|
||||
var foo = new Foo({ t: "a", s: "b" });`
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
/////export default class {
|
||||
//// constructor(/*a*/a: number, b = { x: 1 }/*b*/) {}
|
||||
////}
|
||||
|
||||
goTo.select("a", "b");
|
||||
verify.not.refactorAvailable("Convert to named parameters");
|
||||
@@ -0,0 +1,17 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function f(/*a*/a: number, b: string/*b*/): string {
|
||||
//// return b;
|
||||
////}
|
||||
////f(4, "b");
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `function f({ a, b }: { a: number; b: string; }): string {
|
||||
return b;
|
||||
}
|
||||
f({ a: 4, b: "b" });`
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////foo(1, 2); /**a*/
|
||||
/////**b*/ function /*a*/foo/*b*/(/**this1*/ this /**this2*/: /**void1*/ void /**void2*/, /**c*/ a /**d*/: /**e*/ number /**f*/, /**g*/ b /**h*/: /**i*/ number /**j*/ = /**k*/ 1 /**l*/) {
|
||||
//// // m
|
||||
//// /**n*/ return a + b; // o
|
||||
//// // p
|
||||
////} // q
|
||||
/////**r*/ foo(1);
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `foo({ a: 1, b: 2 }); /**a*/
|
||||
/**b*/ function foo(/**this1*/ this /**this2*/: /**void1*/ void /**void2*/, { a, b = /**k*/ 1 /**l*/ }: { /**c*/ a /**d*/: /**e*/ number /**f*/; /**g*/ b /**h*/?: /**i*/ number /**j*/; }) {
|
||||
// m
|
||||
/**n*/ return a + b; // o
|
||||
// p
|
||||
} // q
|
||||
/**r*/ foo({ a: 1 });`
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function /*a*/foo/*b*/(a: number /** a */, b: number /** b */) {
|
||||
//// return a + b;
|
||||
////}
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `function foo({ a, b }: { a: number /** a */; b: number /** b */; }) {
|
||||
return a + b;
|
||||
}`
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function /*a*/foo/*b*/(// comment
|
||||
//// // a comment
|
||||
//// a: number,
|
||||
//// // b comment
|
||||
//// b: number
|
||||
////) {
|
||||
//// return a + b;
|
||||
////}
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `function foo(// comment
|
||||
{ a, b }: {
|
||||
// a comment
|
||||
a: number;
|
||||
// b comment
|
||||
b: number;
|
||||
}) {
|
||||
return a + b;
|
||||
}`
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const foo = /*a*/function/*b*/(a: number, b: number) { };
|
||||
////foo(1, 2);
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `const foo = function({ a, b }: { a: number; b: number; }) { };
|
||||
foo({ a: 1, b: 2 });`
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function foo<T, S>(/*a*/t: T, s: S/*b*/) {
|
||||
//// return s;
|
||||
////}
|
||||
////foo("a", "b");
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `function foo<T, S>({ t, s }: { t: T; s: S; }) {
|
||||
return s;
|
||||
}
|
||||
foo({ t: "a", s: "b" });`
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////class Foo {
|
||||
//// /*a*/constructor/*b*/(t: string, s: string) { }
|
||||
////}
|
||||
////class Bar extends Foo { }
|
||||
////var bar = new Bar("a", "b");
|
||||
////var foo = new Foo("c", "d");
|
||||
|
||||
goTo.select("a", "b");
|
||||
/* The expected new content is currently wrong.
|
||||
`new Bar("a", "b")` should be modified by the refactor to be `new Bar({ t: "a", s: "b" })`
|
||||
*/
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `class Foo {
|
||||
constructor({ t, s }: { t: string; s: string; }) { }
|
||||
}
|
||||
class Bar extends Foo { }
|
||||
var bar = new Bar("a", "b");
|
||||
var foo = new Foo({ t: "c", s: "d" });`
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////class Foo {
|
||||
//// /*a*/bar/*b*/(t: string, s: string): string {
|
||||
//// return s + t;
|
||||
//// }
|
||||
////}
|
||||
////class Bar extends Foo { }
|
||||
////var bar = new Bar();
|
||||
////bar.bar("a", "b");
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `class Foo {
|
||||
bar({ t, s }: { t: string; s: string; }): string {
|
||||
return s + t;
|
||||
}
|
||||
}
|
||||
class Bar extends Foo { }
|
||||
var bar = new Bar();
|
||||
bar.bar({ t: "a", s: "b" });`
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function f(/*a*/a: number, b: string = "1"/*b*/): string {
|
||||
//// return b;
|
||||
////}
|
||||
////f(4, "b");
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `function f({ a, b = "1" }: { a: number; b?: string; }): string {
|
||||
return b;
|
||||
}
|
||||
f({ a: 4, b: "b" });`
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function f(/*a*/a: number, b = { x: 1, z: { s: true } }/*b*/) {
|
||||
//// return b;
|
||||
////}
|
||||
////f(2);
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `function f({ a, b = { x: 1, z: { s: true } } }: { a: number; b?: { x: number; z: { s: boolean; }; }; }) {
|
||||
return b;
|
||||
}
|
||||
f({ a: 2 });`
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////class Foo {
|
||||
//// /*a*/bar/*b*/(t: string, s: string): string {
|
||||
//// return s + t;
|
||||
//// }
|
||||
////}
|
||||
////var foo = new Foo();
|
||||
////foo.bar("a", "b");
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `class Foo {
|
||||
bar({ t, s }: { t: string; s: string; }): string {
|
||||
return s + t;
|
||||
}
|
||||
}
|
||||
var foo = new Foo();
|
||||
foo.bar({ t: "a", s: "b" });`
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////class A {
|
||||
//// /*a*/foo/*b*/(a: number, b: number) { return a + b; }
|
||||
////}
|
||||
////class B {
|
||||
//// foo(c: number, d: number) { return c + d; }
|
||||
////}
|
||||
////function foo(ab: A | B) {
|
||||
//// return ab.foo(1, 2);
|
||||
////}
|
||||
|
||||
|
||||
goTo.select("a", "b");
|
||||
// Refactor should not make changes
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `class A {
|
||||
foo(a: number, b: number) { return a + b; }
|
||||
}
|
||||
class B {
|
||||
foo(c: number, d: number) { return c + d; }
|
||||
}
|
||||
function foo(ab: A | B) {
|
||||
return ab.foo(1, 2);
|
||||
}`
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////class Foo {
|
||||
//// /*a*/bar/*b*/(t: string, s: string): string {
|
||||
//// return s + t;
|
||||
//// }
|
||||
////}
|
||||
////var foo = new Foo();
|
||||
////foo['bar']("a", "b");
|
||||
////foo.bar("a", "b");
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `class Foo {
|
||||
bar({ t, s }: { t: string; s: string; }): string {
|
||||
return s + t;
|
||||
}
|
||||
}
|
||||
var foo = new Foo();
|
||||
foo['bar']({ t: "a", s: "b" });
|
||||
foo.bar({ t: "a", s: "b" });`
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////class A {
|
||||
//// /*a*/foo/*b*/(a: number, b: number) { }
|
||||
////}
|
||||
////class B extends A {
|
||||
//// /*c*/foo/*d*/(c: number, d: number) { }
|
||||
////}
|
||||
////var a = new A();
|
||||
////a.foo(3, 4);
|
||||
////var b = new B();
|
||||
////b.foo(5, 6);
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `class A {
|
||||
foo(a: number, b: number) { }
|
||||
}
|
||||
class B extends A {
|
||||
foo(c: number, d: number) { }
|
||||
}
|
||||
var a = new A();
|
||||
a.foo(3, 4);
|
||||
var b = new B();
|
||||
b.foo(5, 6);`
|
||||
});
|
||||
goTo.select("c", "d");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `class A {
|
||||
foo(a: number, b: number) { }
|
||||
}
|
||||
class B extends A {
|
||||
foo(c: number, d: number) { }
|
||||
}
|
||||
var a = new A();
|
||||
a.foo(3, 4);
|
||||
var b = new B();
|
||||
b.foo(5, 6);`
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function f(a: number, b: number);
|
||||
////function f(/*a*/a: number, b = 1/*b*/) {
|
||||
//// return b;
|
||||
////}
|
||||
////f(2);
|
||||
|
||||
goTo.select("a", "b");
|
||||
verify.not.refactorAvailable("Convert to named parameters");
|
||||
@@ -0,0 +1,11 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////declare function required(target: Object, propertyKey: string | symbol, parameterIndex: number)
|
||||
////class C {
|
||||
//// /*a*/bar/*b*/(@required a: number, b: number) {
|
||||
////
|
||||
//// }
|
||||
////}
|
||||
|
||||
goTo.select("a", "b");
|
||||
verify.not.refactorAvailable("Convert to named parameters");
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const f = function foo(/*a*/a: number, b: number/*b*/) {
|
||||
//// foo(1, 2);
|
||||
////}
|
||||
////function foo(a: number, b: number) { }
|
||||
////foo(3, 4);
|
||||
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `const f = function foo({ a, b }: { a: number; b: number; }) {
|
||||
foo({ a: 1, b: 2 });
|
||||
}
|
||||
function foo(a: number, b: number) { }
|
||||
foo(3, 4);`
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function log(/*a*/a: number, b: number, ...args/*b*/) { }
|
||||
////let l = log(-1, -2, 3, 4, 5);
|
||||
////let k = log(1, 2);
|
||||
|
||||
goTo.select("a", "b");
|
||||
edit.applyRefactor({
|
||||
refactorName: "Convert to named parameters",
|
||||
actionName: "Convert to named parameters",
|
||||
actionDescription: "Convert to named parameters",
|
||||
newContent: `function log({ a, b, args = [] }: { a: number; b: number; args?: any[]; }) { }
|
||||
let l = log({ a: -1, b: -2, args: [3, 4, 5] });
|
||||
let k = log({ a: 1, b: 2 });`
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user