mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-24 04:30:53 -06:00
Merge branch 'master' into multi_map_add
This commit is contained in:
commit
13b63c5838
@ -551,7 +551,7 @@ function restoreSavedNodeEnv() {
|
||||
process.env.NODE_ENV = savedNodeEnv;
|
||||
}
|
||||
|
||||
let testTimeout = 20000;
|
||||
let testTimeout = 40000;
|
||||
function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: (e?: any) => void) {
|
||||
const lintFlag = cmdLineOptions["lint"];
|
||||
cleanTestDirs((err) => {
|
||||
|
||||
323
Jakefile.js
323
Jakefile.js
@ -27,9 +27,9 @@ var thirdParty = "ThirdPartyNoticeText.txt";
|
||||
// add node_modules to path so we don't need global modules, prefer the modules by adding them first
|
||||
var nodeModulesPathPrefix = path.resolve("./node_modules/.bin/") + path.delimiter;
|
||||
if (process.env.path !== undefined) {
|
||||
process.env.path = nodeModulesPathPrefix + process.env.path;
|
||||
process.env.path = nodeModulesPathPrefix + process.env.path;
|
||||
} else if (process.env.PATH !== undefined) {
|
||||
process.env.PATH = nodeModulesPathPrefix + process.env.PATH;
|
||||
process.env.PATH = nodeModulesPathPrefix + process.env.PATH;
|
||||
}
|
||||
|
||||
function toNs(diff) {
|
||||
@ -205,11 +205,11 @@ var es2015LibrarySources = [
|
||||
"es2015.symbol.wellknown.d.ts"
|
||||
];
|
||||
|
||||
var es2015LibrarySourceMap = es2015LibrarySources.map(function(source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
var es2015LibrarySourceMap = es2015LibrarySources.map(function (source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
});
|
||||
|
||||
var es2016LibrarySource = [ "es2016.array.include.d.ts" ];
|
||||
var es2016LibrarySource = ["es2016.array.include.d.ts"];
|
||||
|
||||
var es2016LibrarySourceMap = es2016LibrarySource.map(function (source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
@ -227,21 +227,21 @@ var es2017LibrarySourceMap = es2017LibrarySource.map(function (source) {
|
||||
var hostsLibrarySources = ["dom.generated.d.ts", "webworker.importscripts.d.ts", "scripthost.d.ts"];
|
||||
|
||||
var librarySourceMap = [
|
||||
// Host library
|
||||
{ target: "lib.dom.d.ts", sources: ["header.d.ts", "dom.generated.d.ts"] },
|
||||
{ target: "lib.dom.iterable.d.ts", sources: ["header.d.ts", "dom.iterable.d.ts"] },
|
||||
{ target: "lib.webworker.d.ts", sources: ["header.d.ts", "webworker.generated.d.ts"] },
|
||||
{ target: "lib.scripthost.d.ts", sources: ["header.d.ts", "scripthost.d.ts"] },
|
||||
// Host library
|
||||
{ target: "lib.dom.d.ts", sources: ["header.d.ts", "dom.generated.d.ts"] },
|
||||
{ target: "lib.dom.iterable.d.ts", sources: ["header.d.ts", "dom.iterable.d.ts"] },
|
||||
{ target: "lib.webworker.d.ts", sources: ["header.d.ts", "webworker.generated.d.ts"] },
|
||||
{ target: "lib.scripthost.d.ts", sources: ["header.d.ts", "scripthost.d.ts"] },
|
||||
|
||||
// JavaScript library
|
||||
{ target: "lib.es5.d.ts", sources: ["header.d.ts", "es5.d.ts"] },
|
||||
{ target: "lib.es2015.d.ts", sources: ["header.d.ts", "es2015.d.ts"] },
|
||||
{ target: "lib.es2016.d.ts", sources: ["header.d.ts", "es2016.d.ts"] },
|
||||
{ target: "lib.es2017.d.ts", sources: ["header.d.ts", "es2017.d.ts"] },
|
||||
// JavaScript library
|
||||
{ target: "lib.es5.d.ts", sources: ["header.d.ts", "es5.d.ts"] },
|
||||
{ target: "lib.es2015.d.ts", sources: ["header.d.ts", "es2015.d.ts"] },
|
||||
{ target: "lib.es2016.d.ts", sources: ["header.d.ts", "es2016.d.ts"] },
|
||||
{ target: "lib.es2017.d.ts", sources: ["header.d.ts", "es2017.d.ts"] },
|
||||
|
||||
// JavaScript + all host library
|
||||
{ target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources) },
|
||||
{ target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") }
|
||||
// JavaScript + all host library
|
||||
{ target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources) },
|
||||
{ target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") }
|
||||
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap);
|
||||
|
||||
var libraryTargets = librarySourceMap.map(function (f) {
|
||||
@ -257,7 +257,7 @@ function prependFile(prefixFile, destinationFile) {
|
||||
fail(destinationFile + " failed to be created!");
|
||||
}
|
||||
var temp = "temptemp";
|
||||
jake.cpR(prefixFile, temp, {silent: true});
|
||||
jake.cpR(prefixFile, temp, { silent: true });
|
||||
fs.appendFileSync(temp, fs.readFileSync(destinationFile));
|
||||
fs.renameSync(temp, destinationFile);
|
||||
}
|
||||
@ -269,11 +269,11 @@ function concatenateFiles(destinationFile, sourceFiles) {
|
||||
if (!fs.existsSync(sourceFiles[0])) {
|
||||
fail(sourceFiles[0] + " does not exist!");
|
||||
}
|
||||
jake.cpR(sourceFiles[0], temp, {silent: true});
|
||||
jake.cpR(sourceFiles[0], temp, { silent: true });
|
||||
// append all files in sequence
|
||||
for (var i = 1; i < sourceFiles.length; i++) {
|
||||
if (!fs.existsSync(sourceFiles[i])) {
|
||||
fail(sourceFiles[i] + " does not exist!");
|
||||
fail(sourceFiles[i] + " does not exist!");
|
||||
}
|
||||
fs.appendFileSync(temp, fs.readFileSync(sourceFiles[i]));
|
||||
}
|
||||
@ -307,11 +307,11 @@ var builtLocalCompiler = path.join(builtLocalDirectory, compilerFilename);
|
||||
* @param callback: a function to execute after the compilation process ends
|
||||
*/
|
||||
function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts, callback) {
|
||||
file(outFile, prereqs, function() {
|
||||
file(outFile, prereqs, function () {
|
||||
var startCompileTime = mark();
|
||||
opts = opts || {};
|
||||
var compilerPath = useBuiltCompiler ? builtLocalCompiler : LKGCompiler;
|
||||
var options = "--noImplicitAny --noImplicitThis --noEmitOnError --types "
|
||||
var options = "--noImplicitAny --noImplicitThis --noEmitOnError --types "
|
||||
if (opts.types) {
|
||||
options += opts.types.join(",");
|
||||
}
|
||||
@ -341,7 +341,7 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts
|
||||
options += " --module commonjs";
|
||||
}
|
||||
|
||||
if(opts.noResolve) {
|
||||
if (opts.noResolve) {
|
||||
options += " --noResolve";
|
||||
}
|
||||
|
||||
@ -368,13 +368,13 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts
|
||||
|
||||
var ex = jake.createExec([cmd]);
|
||||
// Add listeners for output and error
|
||||
ex.addListener("stdout", function(output) {
|
||||
ex.addListener("stdout", function (output) {
|
||||
process.stdout.write(output);
|
||||
});
|
||||
ex.addListener("stderr", function(error) {
|
||||
ex.addListener("stderr", function (error) {
|
||||
process.stderr.write(error);
|
||||
});
|
||||
ex.addListener("cmdEnd", function() {
|
||||
ex.addListener("cmdEnd", function () {
|
||||
if (!useDebugMode && prefixes && fs.existsSync(outFile)) {
|
||||
for (var i in prefixes) {
|
||||
prependFile(prefixes[i], outFile);
|
||||
@ -388,13 +388,13 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts
|
||||
measure(startCompileTime);
|
||||
complete();
|
||||
});
|
||||
ex.addListener("error", function() {
|
||||
ex.addListener("error", function () {
|
||||
fs.unlinkSync(outFile);
|
||||
fail("Compilation of " + outFile + " unsuccessful");
|
||||
measure(startCompileTime);
|
||||
});
|
||||
ex.run();
|
||||
}, {async: true});
|
||||
}, { async: true });
|
||||
}
|
||||
|
||||
// Prerequisite task for built directory and library typings
|
||||
@ -407,7 +407,7 @@ for (var i in libraryTargets) {
|
||||
var sources = [copyright].concat(entry.sources.map(function (s) {
|
||||
return path.join(libraryDirectory, s);
|
||||
}));
|
||||
file(target, [builtLocalDirectory].concat(sources), function() {
|
||||
file(target, [builtLocalDirectory].concat(sources), function () {
|
||||
concatenateFiles(target, sources);
|
||||
});
|
||||
})(i);
|
||||
@ -430,30 +430,30 @@ file(processDiagnosticMessagesTs);
|
||||
|
||||
// processDiagnosticMessages script
|
||||
compileFile(processDiagnosticMessagesJs,
|
||||
[processDiagnosticMessagesTs],
|
||||
[processDiagnosticMessagesTs],
|
||||
[],
|
||||
[processDiagnosticMessagesTs],
|
||||
[processDiagnosticMessagesTs],
|
||||
[],
|
||||
/*useBuiltCompiler*/ false);
|
||||
|
||||
// The generated diagnostics map; built for the compiler and for the 'generate-diagnostics' task
|
||||
file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson], function () {
|
||||
var cmd = host + " " + processDiagnosticMessagesJs + " " + diagnosticMessagesJson;
|
||||
var cmd = host + " " + processDiagnosticMessagesJs + " " + diagnosticMessagesJson;
|
||||
console.log(cmd);
|
||||
var ex = jake.createExec([cmd]);
|
||||
// Add listeners for output and error
|
||||
ex.addListener("stdout", function(output) {
|
||||
ex.addListener("stdout", function (output) {
|
||||
process.stdout.write(output);
|
||||
});
|
||||
ex.addListener("stderr", function(error) {
|
||||
ex.addListener("stderr", function (error) {
|
||||
process.stderr.write(error);
|
||||
});
|
||||
ex.addListener("cmdEnd", function() {
|
||||
ex.addListener("cmdEnd", function () {
|
||||
complete();
|
||||
});
|
||||
ex.run();
|
||||
}, {async: true});
|
||||
}, { async: true });
|
||||
|
||||
file(builtGeneratedDiagnosticMessagesJSON,[generatedDiagnosticMessagesJSON], function() {
|
||||
file(builtGeneratedDiagnosticMessagesJSON, [generatedDiagnosticMessagesJSON], function () {
|
||||
if (fs.existsSync(builtLocalDirectory)) {
|
||||
jake.cpR(generatedDiagnosticMessagesJSON, builtGeneratedDiagnosticMessagesJSON);
|
||||
}
|
||||
@ -471,17 +471,17 @@ var programTs = path.join(compilerDirectory, "program.ts");
|
||||
file(configureNightlyTs);
|
||||
|
||||
compileFile(/*outfile*/configureNightlyJs,
|
||||
/*sources*/ [configureNightlyTs],
|
||||
/*prereqs*/ [configureNightlyTs],
|
||||
/*prefixes*/ [],
|
||||
/*sources*/[configureNightlyTs],
|
||||
/*prereqs*/[configureNightlyTs],
|
||||
/*prefixes*/[],
|
||||
/*useBuiltCompiler*/ false,
|
||||
{ noOutFile: false, generateDeclarations: false, keepComments: false, noResolve: false, stripInternal: false });
|
||||
{ noOutFile: false, generateDeclarations: false, keepComments: false, noResolve: false, stripInternal: false });
|
||||
|
||||
task("setDebugMode", function() {
|
||||
task("setDebugMode", function () {
|
||||
useDebugMode = true;
|
||||
});
|
||||
|
||||
task("configure-nightly", [configureNightlyJs], function() {
|
||||
task("configure-nightly", [configureNightlyJs], function () {
|
||||
var cmd = host + " " + configureNightlyJs + " " + packageJson + " " + programTs;
|
||||
console.log(cmd);
|
||||
exec(cmd);
|
||||
@ -522,63 +522,65 @@ var nodePackageFile = path.join(builtLocalDirectory, "typescript.js");
|
||||
var nodeDefinitionsFile = path.join(builtLocalDirectory, "typescript.d.ts");
|
||||
var nodeStandaloneDefinitionsFile = path.join(builtLocalDirectory, "typescript_standalone.d.ts");
|
||||
|
||||
compileFile(servicesFile, servicesSources,[builtLocalDirectory, copyright].concat(servicesSources),
|
||||
/*prefixes*/ [copyright],
|
||||
compileFile(servicesFile, servicesSources, [builtLocalDirectory, copyright].concat(servicesSources),
|
||||
/*prefixes*/[copyright],
|
||||
/*useBuiltCompiler*/ true,
|
||||
/*opts*/ { noOutFile: false,
|
||||
generateDeclarations: true,
|
||||
preserveConstEnums: true,
|
||||
keepComments: true,
|
||||
noResolve: false,
|
||||
stripInternal: true
|
||||
},
|
||||
/*opts*/ {
|
||||
noOutFile: false,
|
||||
generateDeclarations: true,
|
||||
preserveConstEnums: true,
|
||||
keepComments: true,
|
||||
noResolve: false,
|
||||
stripInternal: true
|
||||
},
|
||||
/*callback*/ function () {
|
||||
jake.cpR(servicesFile, nodePackageFile, {silent: true});
|
||||
jake.cpR(servicesFile, nodePackageFile, { silent: true });
|
||||
|
||||
prependFile(copyright, standaloneDefinitionsFile);
|
||||
prependFile(copyright, standaloneDefinitionsFile);
|
||||
|
||||
// Stanalone/web definition file using global 'ts' namespace
|
||||
jake.cpR(standaloneDefinitionsFile, nodeDefinitionsFile, {silent: true});
|
||||
var definitionFileContents = fs.readFileSync(nodeDefinitionsFile).toString();
|
||||
definitionFileContents = definitionFileContents.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, '$1$2enum $3 {$4');
|
||||
fs.writeFileSync(standaloneDefinitionsFile, definitionFileContents);
|
||||
// Stanalone/web definition file using global 'ts' namespace
|
||||
jake.cpR(standaloneDefinitionsFile, nodeDefinitionsFile, { silent: true });
|
||||
var definitionFileContents = fs.readFileSync(nodeDefinitionsFile).toString();
|
||||
definitionFileContents = definitionFileContents.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, '$1$2enum $3 {$4');
|
||||
fs.writeFileSync(standaloneDefinitionsFile, definitionFileContents);
|
||||
|
||||
// Official node package definition file, pointed to by 'typings' in package.json
|
||||
// Created by appending 'export = ts;' at the end of the standalone file to turn it into an external module
|
||||
var nodeDefinitionsFileContents = definitionFileContents + "\r\nexport = ts;";
|
||||
fs.writeFileSync(nodeDefinitionsFile, nodeDefinitionsFileContents);
|
||||
// Official node package definition file, pointed to by 'typings' in package.json
|
||||
// Created by appending 'export = ts;' at the end of the standalone file to turn it into an external module
|
||||
var nodeDefinitionsFileContents = definitionFileContents + "\r\nexport = ts;";
|
||||
fs.writeFileSync(nodeDefinitionsFile, nodeDefinitionsFileContents);
|
||||
|
||||
// Node package definition file to be distributed without the package. Created by replacing
|
||||
// 'ts' namespace with '"typescript"' as a module.
|
||||
var nodeStandaloneDefinitionsFileContents = definitionFileContents.replace(/declare (namespace|module) ts/g, 'declare module "typescript"');
|
||||
fs.writeFileSync(nodeStandaloneDefinitionsFile, nodeStandaloneDefinitionsFileContents);
|
||||
});
|
||||
// Node package definition file to be distributed without the package. Created by replacing
|
||||
// 'ts' namespace with '"typescript"' as a module.
|
||||
var nodeStandaloneDefinitionsFileContents = definitionFileContents.replace(/declare (namespace|module) ts/g, 'declare module "typescript"');
|
||||
fs.writeFileSync(nodeStandaloneDefinitionsFile, nodeStandaloneDefinitionsFileContents);
|
||||
});
|
||||
|
||||
compileFile(
|
||||
servicesFileInBrowserTest,
|
||||
servicesSources,
|
||||
[builtLocalDirectory, copyright].concat(servicesSources),
|
||||
/*prefixes*/ [copyright],
|
||||
/*prefixes*/[copyright],
|
||||
/*useBuiltCompiler*/ true,
|
||||
{ noOutFile: false,
|
||||
generateDeclarations: true,
|
||||
preserveConstEnums: true,
|
||||
keepComments: true,
|
||||
noResolve: false,
|
||||
stripInternal: true,
|
||||
noMapRoot: true,
|
||||
inlineSourceMap: true
|
||||
});
|
||||
{
|
||||
noOutFile: false,
|
||||
generateDeclarations: true,
|
||||
preserveConstEnums: true,
|
||||
keepComments: true,
|
||||
noResolve: false,
|
||||
stripInternal: true,
|
||||
noMapRoot: true,
|
||||
inlineSourceMap: true
|
||||
});
|
||||
|
||||
var serverFile = path.join(builtLocalDirectory, "tsserver.js");
|
||||
compileFile(serverFile, serverSources,[builtLocalDirectory, copyright].concat(serverSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { types: ["node"] });
|
||||
compileFile(serverFile, serverSources, [builtLocalDirectory, copyright].concat(serverSources), /*prefixes*/[copyright], /*useBuiltCompiler*/ true, { types: ["node"] });
|
||||
var tsserverLibraryFile = path.join(builtLocalDirectory, "tsserverlibrary.js");
|
||||
var tsserverLibraryDefinitionFile = path.join(builtLocalDirectory, "tsserverlibrary.d.ts");
|
||||
compileFile(
|
||||
tsserverLibraryFile,
|
||||
languageServiceLibrarySources,
|
||||
[builtLocalDirectory, copyright, builtLocalCompiler].concat(languageServiceLibrarySources).concat(libraryTargets),
|
||||
/*prefixes*/ [copyright],
|
||||
/*prefixes*/[copyright],
|
||||
/*useBuiltCompiler*/ true,
|
||||
{ noOutFile: false, generateDeclarations: true });
|
||||
|
||||
@ -587,12 +589,12 @@ desc("Builds language service server library");
|
||||
task("lssl", [tsserverLibraryFile, tsserverLibraryDefinitionFile]);
|
||||
|
||||
desc("Emit the start of the build fold");
|
||||
task("build-fold-start", [] , function() {
|
||||
task("build-fold-start", [], function () {
|
||||
if (fold.isTravis()) console.log(fold.start("build"));
|
||||
});
|
||||
|
||||
desc("Emit the end of the build fold");
|
||||
task("build-fold-end", [] , function() {
|
||||
task("build-fold-end", [], function () {
|
||||
if (fold.isTravis()) console.log(fold.end("build"));
|
||||
});
|
||||
|
||||
@ -606,7 +608,7 @@ task("tsc", ["generate-diagnostics", "lib", tscFile]);
|
||||
|
||||
// Local target to build the compiler and services
|
||||
desc("Sets release mode flag");
|
||||
task("release", function() {
|
||||
task("release", function () {
|
||||
useDebugMode = false;
|
||||
});
|
||||
|
||||
@ -616,7 +618,7 @@ task("default", ["local"]);
|
||||
|
||||
// Cleans the built directory
|
||||
desc("Cleans the compiler output, declare files, and tests");
|
||||
task("clean", function() {
|
||||
task("clean", function () {
|
||||
jake.rmRf(builtDirectory);
|
||||
});
|
||||
|
||||
@ -630,9 +632,9 @@ file(word2mdTs);
|
||||
|
||||
// word2md script
|
||||
compileFile(word2mdJs,
|
||||
[word2mdTs],
|
||||
[word2mdTs],
|
||||
[],
|
||||
[word2mdTs],
|
||||
[word2mdTs],
|
||||
[],
|
||||
/*useBuiltCompiler*/ false);
|
||||
|
||||
// The generated spec.md; built for the 'generate-spec' task
|
||||
@ -644,7 +646,7 @@ file(specMd, [word2mdJs, specWord], function () {
|
||||
child_process.exec(cmd, function () {
|
||||
complete();
|
||||
});
|
||||
}, {async: true});
|
||||
}, { async: true });
|
||||
|
||||
|
||||
desc("Generates a Markdown version of the Language Specification");
|
||||
@ -653,14 +655,14 @@ task("generate-spec", [specMd]);
|
||||
|
||||
// Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory
|
||||
desc("Makes a new LKG out of the built js files");
|
||||
task("LKG", ["clean", "release", "local"].concat(libraryTargets), function() {
|
||||
task("LKG", ["clean", "release", "local"].concat(libraryTargets), function () {
|
||||
var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile].concat(libraryTargets);
|
||||
var missingFiles = expectedFiles.filter(function (f) {
|
||||
return !fs.existsSync(f);
|
||||
});
|
||||
if (missingFiles.length > 0) {
|
||||
fail("Cannot replace the LKG unless all built targets are present in directory " + builtLocalDirectory +
|
||||
". The following files are missing:\n" + missingFiles.join("\n"));
|
||||
". The following files are missing:\n" + missingFiles.join("\n"));
|
||||
}
|
||||
// Copy all the targets into the LKG directory
|
||||
jake.mkdirP(LKGDirectory);
|
||||
@ -681,8 +683,8 @@ var run = path.join(builtLocalDirectory, "run.js");
|
||||
compileFile(
|
||||
/*outFile*/ run,
|
||||
/*source*/ harnessSources,
|
||||
/*prereqs*/ [builtLocalDirectory, tscFile].concat(libraryTargets).concat(servicesSources).concat(harnessSources),
|
||||
/*prefixes*/ [],
|
||||
/*prereqs*/[builtLocalDirectory, tscFile].concat(libraryTargets).concat(servicesSources).concat(harnessSources),
|
||||
/*prefixes*/[],
|
||||
/*useBuiltCompiler:*/ true,
|
||||
/*opts*/ { inlineSourceMap: true, types: ["node", "mocha", "chai"] });
|
||||
|
||||
@ -701,22 +703,22 @@ desc("Builds the test infrastructure using the built compiler");
|
||||
task("tests", ["local", run].concat(libraryTargets));
|
||||
|
||||
function exec(cmd, completeHandler, errorHandler) {
|
||||
var ex = jake.createExec([cmd], {windowsVerbatimArguments: true});
|
||||
var ex = jake.createExec([cmd], { windowsVerbatimArguments: true });
|
||||
// Add listeners for output and error
|
||||
ex.addListener("stdout", function(output) {
|
||||
ex.addListener("stdout", function (output) {
|
||||
process.stdout.write(output);
|
||||
});
|
||||
ex.addListener("stderr", function(error) {
|
||||
ex.addListener("stderr", function (error) {
|
||||
process.stderr.write(error);
|
||||
});
|
||||
ex.addListener("cmdEnd", function() {
|
||||
ex.addListener("cmdEnd", function () {
|
||||
if (completeHandler) {
|
||||
completeHandler();
|
||||
}
|
||||
complete();
|
||||
});
|
||||
ex.addListener("error", function(e, status) {
|
||||
if(errorHandler) {
|
||||
ex.addListener("error", function (e, status) {
|
||||
if (errorHandler) {
|
||||
errorHandler(e, status);
|
||||
} else {
|
||||
fail("Process exited with code " + status);
|
||||
@ -760,7 +762,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
tests = process.env.test || process.env.tests || process.env.t;
|
||||
var light = process.env.light || false;
|
||||
var testConfigFile = 'test.config';
|
||||
if(fs.existsSync(testConfigFile)) {
|
||||
if (fs.existsSync(testConfigFile)) {
|
||||
fs.unlinkSync(testConfigFile);
|
||||
}
|
||||
var workerCount, taskConfigsFolder;
|
||||
@ -793,7 +795,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
|
||||
// timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally
|
||||
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
|
||||
if(!runInParallel) {
|
||||
if (!runInParallel) {
|
||||
var startTime = mark();
|
||||
tests = tests ? ' -g "' + tests + '"' : '';
|
||||
var cmd = "mocha" + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + bail + ' -t ' + testTimeout + ' ' + run;
|
||||
@ -806,7 +808,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
measure(startTime);
|
||||
runLinter();
|
||||
finish();
|
||||
}, function(e, status) {
|
||||
}, function (e, status) {
|
||||
process.env.NODE_ENV = savedNodeEnv;
|
||||
measure(startTime);
|
||||
finish(status);
|
||||
@ -860,14 +862,14 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
|
||||
var testTimeout = 20000;
|
||||
desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... d[ebug]=true.");
|
||||
task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], function() {
|
||||
task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], function () {
|
||||
runConsoleTests('min', /*runInParallel*/ true);
|
||||
}, {async: true});
|
||||
}, { async: true });
|
||||
|
||||
desc("Runs the tests using the built run.js file. Optional arguments are: t[ests]=regex r[eporter]=[list|spec|json|<more>] d[ebug]=true color[s]=false lint=true bail=false.");
|
||||
task("runtests", ["build-rules", "tests", builtLocalDirectory], function() {
|
||||
task("runtests", ["build-rules", "tests", builtLocalDirectory], function () {
|
||||
runConsoleTests('mocha-fivemat-progress-reporter', /*runInParallel*/ false);
|
||||
}, {async: true});
|
||||
}, { async: true });
|
||||
|
||||
desc("Generates code coverage data via instanbul");
|
||||
task("generate-code-coverage", ["tests", builtLocalDirectory], function () {
|
||||
@ -882,23 +884,23 @@ var nodeServerInFile = "tests/webTestServer.ts";
|
||||
compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, { noOutFile: true });
|
||||
|
||||
desc("Runs browserify on run.js to produce a file suitable for running tests in the browser");
|
||||
task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function() {
|
||||
task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function () {
|
||||
var cmd = 'browserify built/local/run.js -d -o built/local/bundle.js';
|
||||
exec(cmd);
|
||||
}, {async: true});
|
||||
}, { async: true });
|
||||
|
||||
desc("Runs the tests using the built run.js file like 'jake runtests'. Syntax is jake runtests-browser. Additional optional parameters tests=[regex], browser=[chrome|IE]");
|
||||
task("runtests-browser", ["tests", "browserify", builtLocalDirectory, servicesFileInBrowserTest], function() {
|
||||
task("runtests-browser", ["tests", "browserify", builtLocalDirectory, servicesFileInBrowserTest], function () {
|
||||
cleanTestDirs();
|
||||
host = "node";
|
||||
browser = process.env.browser || process.env.b || "IE";
|
||||
tests = process.env.test || process.env.tests || process.env.t;
|
||||
var light = process.env.light || false;
|
||||
var testConfigFile = 'test.config';
|
||||
if(fs.existsSync(testConfigFile)) {
|
||||
if (fs.existsSync(testConfigFile)) {
|
||||
fs.unlinkSync(testConfigFile);
|
||||
}
|
||||
if(tests || light) {
|
||||
if (tests || light) {
|
||||
writeTestConfigFile(tests, light);
|
||||
}
|
||||
|
||||
@ -906,7 +908,7 @@ task("runtests-browser", ["tests", "browserify", builtLocalDirectory, servicesFi
|
||||
var cmd = host + " tests/webTestServer.js " + browser + " " + JSON.stringify(tests);
|
||||
console.log(cmd);
|
||||
exec(cmd);
|
||||
}, {async: true});
|
||||
}, { async: true });
|
||||
|
||||
function getDiffTool() {
|
||||
var program = process.env['DIFF'];
|
||||
@ -919,17 +921,17 @@ function getDiffTool() {
|
||||
// Baseline Diff
|
||||
desc("Diffs the compiler baselines using the diff tool specified by the 'DIFF' environment variable");
|
||||
task('diff', function () {
|
||||
var cmd = '"' + getDiffTool() + '" ' + refBaseline + ' ' + localBaseline;
|
||||
var cmd = '"' + getDiffTool() + '" ' + refBaseline + ' ' + localBaseline;
|
||||
console.log(cmd);
|
||||
exec(cmd);
|
||||
}, {async: true});
|
||||
}, { async: true });
|
||||
|
||||
desc("Diffs the RWC baselines using the diff tool specified by the 'DIFF' environment variable");
|
||||
task('diff-rwc', function () {
|
||||
var cmd = '"' + getDiffTool() + '" ' + refRwcBaseline + ' ' + localRwcBaseline;
|
||||
var cmd = '"' + getDiffTool() + '" ' + refRwcBaseline + ' ' + localRwcBaseline;
|
||||
console.log(cmd);
|
||||
exec(cmd);
|
||||
}, {async: true});
|
||||
}, { async: true });
|
||||
|
||||
desc("Builds the test sources and automation in debug mode");
|
||||
task("tests-debug", ["setDebugMode", "tests"]);
|
||||
@ -937,30 +939,39 @@ task("tests-debug", ["setDebugMode", "tests"]);
|
||||
|
||||
// Makes the test results the new baseline
|
||||
desc("Makes the most recent test results the new baseline, overwriting the old baseline");
|
||||
task("baseline-accept", function(hardOrSoft) {
|
||||
var files = jake.readdirR(localBaseline);
|
||||
var deleteEnding = '.delete';
|
||||
for (var i in files) {
|
||||
if (files[i].substr(files[i].length - deleteEnding.length) === deleteEnding) {
|
||||
var filename = path.basename(files[i]);
|
||||
filename = filename.substr(0, filename.length - deleteEnding.length);
|
||||
fs.unlink(path.join(refBaseline, filename));
|
||||
} else {
|
||||
jake.cpR(files[i], refBaseline);
|
||||
}
|
||||
}
|
||||
task("baseline-accept", function () {
|
||||
acceptBaseline("");
|
||||
});
|
||||
|
||||
function acceptBaseline(containerFolder) {
|
||||
var sourceFolder = path.join(localBaseline, containerFolder);
|
||||
var targetFolder = path.join(refBaseline, containerFolder);
|
||||
console.log('Accept baselines from ' + sourceFolder + ' to ' + targetFolder);
|
||||
var files = fs.readdirSync(sourceFolder);
|
||||
var deleteEnding = '.delete';
|
||||
for (var i in files) {
|
||||
var filename = files[i];
|
||||
if (filename.substr(filename.length - deleteEnding.length) === deleteEnding) {
|
||||
filename = filename.substr(0, filename.length - deleteEnding.length);
|
||||
fs.unlinkSync(path.join(targetFolder, filename));
|
||||
} else {
|
||||
var target = path.join(targetFolder, filename);
|
||||
if (fs.existsSync(target)) {
|
||||
fs.unlinkSync(target);
|
||||
}
|
||||
fs.renameSync(path.join(sourceFolder, filename), target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
desc("Makes the most recent rwc test results the new baseline, overwriting the old baseline");
|
||||
task("baseline-accept-rwc", function() {
|
||||
jake.rmRf(refRwcBaseline);
|
||||
fs.renameSync(localRwcBaseline, refRwcBaseline);
|
||||
task("baseline-accept-rwc", function () {
|
||||
acceptBaseline("rwc");
|
||||
});
|
||||
|
||||
desc("Makes the most recent test262 test results the new baseline, overwriting the old baseline");
|
||||
task("baseline-accept-test262", function() {
|
||||
jake.rmRf(refTest262Baseline);
|
||||
fs.renameSync(localTest262Baseline, refTest262Baseline);
|
||||
task("baseline-accept-test262", function () {
|
||||
acceptBaseline("test262");
|
||||
});
|
||||
|
||||
|
||||
@ -970,8 +981,8 @@ var webhostJsPath = "tests/webhost/webtsc.js";
|
||||
compileFile(webhostJsPath, [webhostPath], [tscFile, webhostPath].concat(libraryTargets), [], /*useBuiltCompiler*/true);
|
||||
|
||||
desc("Builds the tsc web host");
|
||||
task("webhost", [webhostJsPath], function() {
|
||||
jake.cpR(path.join(builtLocalDirectory, "lib.d.ts"), "tests/webhost/", {silent: true});
|
||||
task("webhost", [webhostJsPath], function () {
|
||||
jake.cpR(path.join(builtLocalDirectory, "lib.d.ts"), "tests/webhost/", { silent: true });
|
||||
});
|
||||
|
||||
// Perf compiler
|
||||
@ -984,38 +995,38 @@ task("perftsc", [perftscJsPath]);
|
||||
// Instrumented compiler
|
||||
var loggedIOpath = harnessDirectory + 'loggedIO.ts';
|
||||
var loggedIOJsPath = builtLocalDirectory + 'loggedIO.js';
|
||||
file(loggedIOJsPath, [builtLocalDirectory, loggedIOpath], function() {
|
||||
file(loggedIOJsPath, [builtLocalDirectory, loggedIOpath], function () {
|
||||
var temp = builtLocalDirectory + 'temp';
|
||||
jake.mkdirP(temp);
|
||||
var options = "--outdir " + temp + ' ' + loggedIOpath;
|
||||
var cmd = host + " " + LKGDirectory + compilerFilename + " " + options + " ";
|
||||
console.log(cmd + "\n");
|
||||
var ex = jake.createExec([cmd]);
|
||||
ex.addListener("cmdEnd", function() {
|
||||
ex.addListener("cmdEnd", function () {
|
||||
fs.renameSync(temp + '/harness/loggedIO.js', loggedIOJsPath);
|
||||
jake.rmRf(temp);
|
||||
complete();
|
||||
});
|
||||
ex.run();
|
||||
}, {async: true});
|
||||
}, { async: true });
|
||||
|
||||
var instrumenterPath = harnessDirectory + 'instrumenter.ts';
|
||||
var instrumenterJsPath = builtLocalDirectory + 'instrumenter.js';
|
||||
compileFile(instrumenterJsPath, [instrumenterPath], [tscFile, instrumenterPath].concat(libraryTargets), [], /*useBuiltCompiler*/ true);
|
||||
|
||||
desc("Builds an instrumented tsc.js");
|
||||
task('tsc-instrumented', [loggedIOJsPath, instrumenterJsPath, tscFile], function() {
|
||||
task('tsc-instrumented', [loggedIOJsPath, instrumenterJsPath, tscFile], function () {
|
||||
var cmd = host + ' ' + instrumenterJsPath + ' record iocapture ' + builtLocalDirectory + compilerFilename;
|
||||
console.log(cmd);
|
||||
var ex = jake.createExec([cmd]);
|
||||
ex.addListener("cmdEnd", function() {
|
||||
ex.addListener("cmdEnd", function () {
|
||||
complete();
|
||||
});
|
||||
ex.run();
|
||||
}, { async: true });
|
||||
|
||||
desc("Updates the sublime plugin's tsserver");
|
||||
task("update-sublime", ["local", serverFile], function() {
|
||||
task("update-sublime", ["local", serverFile], function () {
|
||||
jake.cpR(serverFile, "../TypeScript-Sublime-Plugin/tsserver/");
|
||||
jake.cpR(serverFile + ".map", "../TypeScript-Sublime-Plugin/tsserver/");
|
||||
});
|
||||
@ -1031,33 +1042,33 @@ var tslintRules = [
|
||||
"objectLiteralSurroundingSpaceRule",
|
||||
"noTypeAssertionWhitespaceRule"
|
||||
];
|
||||
var tslintRulesFiles = tslintRules.map(function(p) {
|
||||
var tslintRulesFiles = tslintRules.map(function (p) {
|
||||
return path.join(tslintRuleDir, p + ".ts");
|
||||
});
|
||||
var tslintRulesOutFiles = tslintRules.map(function(p) {
|
||||
var tslintRulesOutFiles = tslintRules.map(function (p) {
|
||||
return path.join(builtLocalDirectory, "tslint", p + ".js");
|
||||
});
|
||||
desc("Compiles tslint rules to js");
|
||||
task("build-rules", ["build-rules-start"].concat(tslintRulesOutFiles).concat(["build-rules-end"]));
|
||||
tslintRulesFiles.forEach(function(ruleFile, i) {
|
||||
tslintRulesFiles.forEach(function (ruleFile, i) {
|
||||
compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ false,
|
||||
{ noOutFile: true, generateDeclarations: false, outDir: path.join(builtLocalDirectory, "tslint")});
|
||||
{ noOutFile: true, generateDeclarations: false, outDir: path.join(builtLocalDirectory, "tslint") });
|
||||
});
|
||||
|
||||
desc("Emit the start of the build-rules fold");
|
||||
task("build-rules-start", [] , function() {
|
||||
task("build-rules-start", [], function () {
|
||||
if (fold.isTravis()) console.log(fold.start("build-rules"));
|
||||
});
|
||||
|
||||
desc("Emit the end of the build-rules fold");
|
||||
task("build-rules-end", [] , function() {
|
||||
task("build-rules-end", [], function () {
|
||||
if (fold.isTravis()) console.log(fold.end("build-rules"));
|
||||
});
|
||||
|
||||
var lintTargets = compilerSources
|
||||
.concat(harnessSources)
|
||||
// Other harness sources
|
||||
.concat(["instrumenter.ts"].map(function(f) { return path.join(harnessDirectory, f) }))
|
||||
.concat(["instrumenter.ts"].map(function (f) { return path.join(harnessDirectory, f) }))
|
||||
.concat(serverCoreSources)
|
||||
.concat(tslintRulesFiles)
|
||||
.concat(servicesSources)
|
||||
@ -1068,10 +1079,10 @@ function sendNextFile(files, child, callback, failures) {
|
||||
var file = files.pop();
|
||||
if (file) {
|
||||
console.log("Linting '" + file + "'.");
|
||||
child.send({kind: "file", name: file});
|
||||
child.send({ kind: "file", name: file });
|
||||
}
|
||||
else {
|
||||
child.send({kind: "close"});
|
||||
child.send({ kind: "close" });
|
||||
callback(failures);
|
||||
}
|
||||
}
|
||||
@ -1079,7 +1090,7 @@ function sendNextFile(files, child, callback, failures) {
|
||||
function spawnLintWorker(files, callback) {
|
||||
var child = child_process.fork("./scripts/parallel-lint");
|
||||
var failures = 0;
|
||||
child.on("message", function(data) {
|
||||
child.on("message", function (data) {
|
||||
switch (data.kind) {
|
||||
case "result":
|
||||
if (data.failures > 0) {
|
||||
@ -1099,7 +1110,7 @@ function spawnLintWorker(files, callback) {
|
||||
}
|
||||
|
||||
desc("Runs tslint on the compiler sources. Optional arguments are: f[iles]=regex");
|
||||
task("lint", ["build-rules"], function() {
|
||||
task("lint", ["build-rules"], function () {
|
||||
if (fold.isTravis()) console.log(fold.start("lint"));
|
||||
var startTime = mark();
|
||||
var failed = 0;
|
||||
@ -1114,7 +1125,7 @@ task("lint", ["build-rules"], function() {
|
||||
|
||||
var workerCount = (process.env.workerCount && +process.env.workerCount) || os.cpus().length;
|
||||
|
||||
var names = Object.keys(done).sort(function(namea, nameb) {
|
||||
var names = Object.keys(done).sort(function (namea, nameb) {
|
||||
return done[namea] - done[nameb];
|
||||
});
|
||||
|
||||
@ -1138,4 +1149,4 @@ task("lint", ["build-rules"], function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {async: true});
|
||||
}, { async: true });
|
||||
|
||||
@ -106,7 +106,7 @@ namespace ts {
|
||||
isOptionalParameter
|
||||
};
|
||||
|
||||
const tupleTypes = createMap<TupleType>();
|
||||
const tupleTypes: GenericType[] = [];
|
||||
const unionTypes = createMap<UnionType>();
|
||||
const intersectionTypes = createMap<IntersectionType>();
|
||||
const stringLiteralTypes = createMap<LiteralType>();
|
||||
@ -1023,8 +1023,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getDeclarationOfAliasSymbol(symbol: Symbol): Declaration {
|
||||
return findMap(symbol.declarations, d => isAliasSymbolDeclaration(d) ? d : undefined);
|
||||
function getDeclarationOfAliasSymbol(symbol: Symbol): Declaration | undefined {
|
||||
return forEach(symbol.declarations, d => isAliasSymbolDeclaration(d) ? d : undefined);
|
||||
}
|
||||
|
||||
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration): Symbol {
|
||||
@ -1126,13 +1126,13 @@ namespace ts {
|
||||
else {
|
||||
symbolFromVariable = getPropertyOfVariable(targetSymbol, name.text);
|
||||
}
|
||||
// If the export member we're looking for is default, and there is no real default but allowSyntheticDefaultImports is on, return the entire module as the default
|
||||
if (!symbolFromVariable && allowSyntheticDefaultImports && name.text === "default") {
|
||||
symbolFromVariable = resolveExternalModuleSymbol(moduleSymbol) || resolveSymbol(moduleSymbol);
|
||||
}
|
||||
// if symbolFromVariable is export - get its final target
|
||||
symbolFromVariable = resolveSymbol(symbolFromVariable);
|
||||
const symbolFromModule = getExportOfModule(targetSymbol, name.text);
|
||||
let symbolFromModule = getExportOfModule(targetSymbol, name.text);
|
||||
// If the export member we're looking for is default, and there is no real default but allowSyntheticDefaultImports is on, return the entire module as the default
|
||||
if (!symbolFromModule && allowSyntheticDefaultImports && name.text === "default") {
|
||||
symbolFromModule = resolveExternalModuleSymbol(moduleSymbol) || resolveSymbol(moduleSymbol);
|
||||
}
|
||||
const symbol = symbolFromModule && symbolFromVariable ?
|
||||
combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) :
|
||||
symbolFromModule || symbolFromVariable;
|
||||
@ -1191,6 +1191,7 @@ namespace ts {
|
||||
if (!links.target) {
|
||||
links.target = resolvingSymbol;
|
||||
const node = getDeclarationOfAliasSymbol(symbol);
|
||||
Debug.assert(!!node);
|
||||
const target = getTargetOfAliasDeclaration(node);
|
||||
if (links.target === resolvingSymbol) {
|
||||
links.target = target || unknownSymbol;
|
||||
@ -1226,6 +1227,7 @@ namespace ts {
|
||||
if (!links.referenced) {
|
||||
links.referenced = true;
|
||||
const node = getDeclarationOfAliasSymbol(symbol);
|
||||
Debug.assert(!!node);
|
||||
if (node.kind === SyntaxKind.ExportAssignment) {
|
||||
// export default <symbol>
|
||||
checkExpressionCached((<ExportAssignment>node).expression);
|
||||
@ -2145,9 +2147,6 @@ namespace ts {
|
||||
// The specified symbol flags need to be reinterpreted as type flags
|
||||
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
|
||||
}
|
||||
else if (type.flags & TypeFlags.Tuple) {
|
||||
writeTupleType(<TupleType>type);
|
||||
}
|
||||
else if (!(flags & TypeFormatFlags.InTypeAlias) && type.flags & (TypeFlags.Anonymous | TypeFlags.UnionOrIntersection) && type.aliasSymbol) {
|
||||
const typeArguments = type.aliasTypeArguments;
|
||||
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags);
|
||||
@ -2214,6 +2213,11 @@ namespace ts {
|
||||
writePunctuation(writer, SyntaxKind.OpenBracketToken);
|
||||
writePunctuation(writer, SyntaxKind.CloseBracketToken);
|
||||
}
|
||||
else if (type.target.flags & TypeFlags.Tuple) {
|
||||
writePunctuation(writer, SyntaxKind.OpenBracketToken);
|
||||
writeTypeList(type.typeArguments.slice(0, getTypeReferenceArity(type)), SyntaxKind.CommaToken);
|
||||
writePunctuation(writer, SyntaxKind.CloseBracketToken);
|
||||
}
|
||||
else {
|
||||
// Write the type reference in the format f<A>.g<B>.C<X, Y> where A and B are type arguments
|
||||
// for outer type parameters, and f and g are the respective declaring containers of those
|
||||
@ -2242,12 +2246,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function writeTupleType(type: TupleType) {
|
||||
writePunctuation(writer, SyntaxKind.OpenBracketToken);
|
||||
writeTypeList(type.elementTypes, SyntaxKind.CommaToken);
|
||||
writePunctuation(writer, SyntaxKind.CloseBracketToken);
|
||||
}
|
||||
|
||||
function writeUnionOrIntersectionType(type: UnionOrIntersectionType, flags: TypeFormatFlags) {
|
||||
if (flags & TypeFormatFlags.InElementType) {
|
||||
writePunctuation(writer, SyntaxKind.OpenParenToken);
|
||||
@ -2958,7 +2956,7 @@ namespace ts {
|
||||
: elementType;
|
||||
if (!type) {
|
||||
if (isTupleType(parentType)) {
|
||||
error(declaration, Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(parentType), (<TupleType>parentType).elementTypes.length, pattern.elements.length);
|
||||
error(declaration, Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(parentType), getTypeReferenceArity(<TypeReference>parentType), pattern.elements.length);
|
||||
}
|
||||
else {
|
||||
error(declaration, Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName);
|
||||
@ -3070,9 +3068,14 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
// Use contextual parameter type if one is available
|
||||
const type = declaration.symbol.name === "this"
|
||||
? getContextuallyTypedThisType(func)
|
||||
: getContextuallyTypedParameterType(<ParameterDeclaration>declaration);
|
||||
let type: Type;
|
||||
if (declaration.symbol.name === "this") {
|
||||
const thisParameter = getContextualThisParameter(func);
|
||||
type = thisParameter ? getTypeOfSymbol(thisParameter) : undefined;
|
||||
}
|
||||
else {
|
||||
type = getContextuallyTypedParameterType(<ParameterDeclaration>declaration);
|
||||
}
|
||||
if (type) {
|
||||
return addOptionality(type, /*optional*/ declaration.questionToken && includeOptionality);
|
||||
}
|
||||
@ -3150,12 +3153,12 @@ namespace ts {
|
||||
}
|
||||
// If the pattern has at least one element, and no rest element, then it should imply a tuple type.
|
||||
const elementTypes = map(elements, e => e.kind === SyntaxKind.OmittedExpression ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors));
|
||||
let result = createTupleType(elementTypes);
|
||||
if (includePatternInType) {
|
||||
const result = createNewTupleType(elementTypes);
|
||||
result = cloneTypeReference(result);
|
||||
result.pattern = pattern;
|
||||
return result;
|
||||
}
|
||||
return createTupleType(elementTypes);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Return the type implied by a binding pattern. This is the type implied purely by the binding pattern itself
|
||||
@ -3343,7 +3346,13 @@ namespace ts {
|
||||
// Otherwise, fall back to 'any'.
|
||||
else {
|
||||
if (compilerOptions.noImplicitAny) {
|
||||
error(setter, Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_type_annotation, symbolToString(symbol));
|
||||
if (setter) {
|
||||
error(setter, Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol));
|
||||
}
|
||||
else {
|
||||
Debug.assert(!!getter, "there must existed getter as we are current checking either setter or getter in this function");
|
||||
error(getter, Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation, symbolToString(symbol));
|
||||
}
|
||||
}
|
||||
type = anyType;
|
||||
}
|
||||
@ -3564,18 +3573,21 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getBaseTypes(type: InterfaceType): ObjectType[] {
|
||||
const isClass = type.symbol.flags & SymbolFlags.Class;
|
||||
const isInterface = type.symbol.flags & SymbolFlags.Interface;
|
||||
if (!type.resolvedBaseTypes) {
|
||||
if (!isClass && !isInterface) {
|
||||
if (type.flags & TypeFlags.Tuple) {
|
||||
type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters))];
|
||||
}
|
||||
else if (type.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
if (type.symbol.flags & SymbolFlags.Class) {
|
||||
resolveBaseTypesOfClass(type);
|
||||
}
|
||||
if (type.symbol.flags & SymbolFlags.Interface) {
|
||||
resolveBaseTypesOfInterface(type);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Debug.fail("type must be class or interface");
|
||||
}
|
||||
if (isClass) {
|
||||
resolveBaseTypesOfClass(type);
|
||||
}
|
||||
if (isInterface) {
|
||||
resolveBaseTypesOfInterface(type);
|
||||
}
|
||||
}
|
||||
return type.resolvedBaseTypes;
|
||||
}
|
||||
@ -4001,20 +4013,25 @@ namespace ts {
|
||||
return createTypeReference((<TypeReference>type).target,
|
||||
concatenate((<TypeReference>type).typeArguments, [thisArgument || (<TypeReference>type).target.thisType]));
|
||||
}
|
||||
if (type.flags & TypeFlags.Tuple) {
|
||||
return createTupleType((type as TupleType).elementTypes, thisArgument);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function resolveObjectTypeMembers(type: ObjectType, source: InterfaceTypeWithDeclaredMembers, typeParameters: TypeParameter[], typeArguments: Type[]) {
|
||||
let mapper = identityMapper;
|
||||
let members = source.symbol.members;
|
||||
let callSignatures = source.declaredCallSignatures;
|
||||
let constructSignatures = source.declaredConstructSignatures;
|
||||
let stringIndexInfo = source.declaredStringIndexInfo;
|
||||
let numberIndexInfo = source.declaredNumberIndexInfo;
|
||||
if (!rangeEquals(typeParameters, typeArguments, 0, typeParameters.length)) {
|
||||
let mapper: TypeMapper;
|
||||
let members: SymbolTable;
|
||||
let callSignatures: Signature[];
|
||||
let constructSignatures: Signature[];
|
||||
let stringIndexInfo: IndexInfo;
|
||||
let numberIndexInfo: IndexInfo;
|
||||
if (rangeEquals(typeParameters, typeArguments, 0, typeParameters.length)) {
|
||||
mapper = identityMapper;
|
||||
members = source.symbol ? source.symbol.members : createSymbolTable(source.declaredProperties);
|
||||
callSignatures = source.declaredCallSignatures;
|
||||
constructSignatures = source.declaredConstructSignatures;
|
||||
stringIndexInfo = source.declaredStringIndexInfo;
|
||||
numberIndexInfo = source.declaredNumberIndexInfo;
|
||||
}
|
||||
else {
|
||||
mapper = createTypeMapper(typeParameters, typeArguments);
|
||||
members = createInstantiatedSymbolTable(source.declaredProperties, mapper, /*mappingThisOnly*/ typeParameters.length === 1);
|
||||
callSignatures = instantiateList(source.declaredCallSignatures, mapper, instantiateSignature);
|
||||
@ -4024,7 +4041,7 @@ namespace ts {
|
||||
}
|
||||
const baseTypes = getBaseTypes(source);
|
||||
if (baseTypes.length) {
|
||||
if (members === source.symbol.members) {
|
||||
if (source.symbol && members === source.symbol.members) {
|
||||
members = createSymbolTable(source.declaredProperties);
|
||||
}
|
||||
const thisArgument = lastOrUndefined(typeArguments);
|
||||
@ -4094,26 +4111,6 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function createTupleTypeMemberSymbols(memberTypes: Type[]): SymbolTable {
|
||||
const members = createMap<Symbol>();
|
||||
for (let i = 0; i < memberTypes.length; i++) {
|
||||
const symbol = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "" + i);
|
||||
symbol.type = memberTypes[i];
|
||||
members[i] = symbol;
|
||||
}
|
||||
return members;
|
||||
}
|
||||
|
||||
function resolveTupleTypeMembers(type: TupleType) {
|
||||
const arrayElementType = getUnionType(type.elementTypes);
|
||||
// Make the tuple type itself the 'this' type by including an extra type argument
|
||||
// (Unless it's provided in the case that the tuple is a type parameter constraint)
|
||||
const arrayType = resolveStructuredTypeMembers(createTypeFromGenericGlobalType(globalArrayType, [arrayElementType, type.thisType || type]));
|
||||
const members = createTupleTypeMemberSymbols(type.elementTypes);
|
||||
addInheritedMembers(members, arrayType.properties);
|
||||
setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexInfo, arrayType.numberIndexInfo);
|
||||
}
|
||||
|
||||
function findMatchingSignature(signatureList: Signature[], signature: Signature, partialMatch: boolean, ignoreThisTypes: boolean, ignoreReturnTypes: boolean): Signature {
|
||||
for (const s of signatureList) {
|
||||
if (compareSignaturesIdentical(s, signature, partialMatch, ignoreThisTypes, ignoreReturnTypes, compareTypesIdentical)) {
|
||||
@ -4292,9 +4289,6 @@ namespace ts {
|
||||
else if (type.flags & TypeFlags.Anonymous) {
|
||||
resolveAnonymousTypeMembers(<AnonymousType>type);
|
||||
}
|
||||
else if (type.flags & TypeFlags.Tuple) {
|
||||
resolveTupleTypeMembers(<TupleType>type);
|
||||
}
|
||||
else if (type.flags & TypeFlags.Union) {
|
||||
resolveUnionTypeMembers(<UnionType>type);
|
||||
}
|
||||
@ -4694,6 +4688,9 @@ namespace ts {
|
||||
if (isJSConstructSignature) {
|
||||
minArgumentCount--;
|
||||
}
|
||||
if (!thisParameter && isObjectLiteralMethod(declaration)) {
|
||||
thisParameter = getContextualThisParameter(declaration);
|
||||
}
|
||||
|
||||
const classType = declaration.kind === SyntaxKind.Constructor ?
|
||||
getDeclaredTypeOfClassOrInterface(getMergedSymbol((<ClassDeclaration>declaration.parent).symbol))
|
||||
@ -4992,6 +4989,17 @@ namespace ts {
|
||||
return type;
|
||||
}
|
||||
|
||||
function cloneTypeReference(source: TypeReference): TypeReference {
|
||||
const type = <TypeReference>createObjectType(source.flags, source.symbol);
|
||||
type.target = source.target;
|
||||
type.typeArguments = source.typeArguments;
|
||||
return type;
|
||||
}
|
||||
|
||||
function getTypeReferenceArity(type: TypeReference): number {
|
||||
return type.target.typeParameters ? type.target.typeParameters.length : 0;
|
||||
}
|
||||
|
||||
// Get type from reference to class or interface
|
||||
function getTypeFromClassOrInterfaceReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol): Type {
|
||||
const type = <InterfaceType>getDeclaredTypeOfSymbol(getMergedSymbol(symbol));
|
||||
@ -5234,17 +5242,47 @@ namespace ts {
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function createTupleType(elementTypes: Type[], thisType?: Type) {
|
||||
const id = getTypeListId(elementTypes) + "," + (thisType ? thisType.id : 0);
|
||||
return tupleTypes[id] || (tupleTypes[id] = createNewTupleType(elementTypes, thisType));
|
||||
// We represent tuple types as type references to synthesized generic interface types created by
|
||||
// this function. The types are of the form:
|
||||
//
|
||||
// interface Tuple<T0, T1, T2, ...> extends Array<T0 | T1 | T2 | ...> { 0: T0, 1: T1, 2: T2, ... }
|
||||
//
|
||||
// Note that the generic type created by this function has no symbol associated with it. The same
|
||||
// is true for each of the synthesized type parameters.
|
||||
function createTupleTypeOfArity(arity: number): GenericType {
|
||||
const typeParameters: TypeParameter[] = [];
|
||||
const properties: Symbol[] = [];
|
||||
for (let i = 0; i < arity; i++) {
|
||||
const typeParameter = <TypeParameter>createType(TypeFlags.TypeParameter);
|
||||
typeParameters.push(typeParameter);
|
||||
const property = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "" + i);
|
||||
property.type = typeParameter;
|
||||
properties.push(property);
|
||||
}
|
||||
const type = <GenericType & InterfaceTypeWithDeclaredMembers>createObjectType(TypeFlags.Tuple | TypeFlags.Reference);
|
||||
type.typeParameters = typeParameters;
|
||||
type.outerTypeParameters = undefined;
|
||||
type.localTypeParameters = typeParameters;
|
||||
type.instantiations = createMap<TypeReference>();
|
||||
type.instantiations[getTypeListId(type.typeParameters)] = <GenericType>type;
|
||||
type.target = <GenericType>type;
|
||||
type.typeArguments = type.typeParameters;
|
||||
type.thisType = <TypeParameter>createType(TypeFlags.TypeParameter | TypeFlags.ThisType);
|
||||
type.thisType.constraint = type;
|
||||
type.declaredProperties = properties;
|
||||
type.declaredCallSignatures = emptyArray;
|
||||
type.declaredConstructSignatures = emptyArray;
|
||||
type.declaredStringIndexInfo = undefined;
|
||||
type.declaredNumberIndexInfo = undefined;
|
||||
return type;
|
||||
}
|
||||
|
||||
function createNewTupleType(elementTypes: Type[], thisType?: Type) {
|
||||
const propagatedFlags = getPropagatingFlagsOfTypes(elementTypes, /*excludeKinds*/ 0);
|
||||
const type = <TupleType>createObjectType(TypeFlags.Tuple | propagatedFlags);
|
||||
type.elementTypes = elementTypes;
|
||||
type.thisType = thisType;
|
||||
return type;
|
||||
function getTupleTypeOfArity(arity: number): GenericType {
|
||||
return tupleTypes[arity] || (tupleTypes[arity] = createTupleTypeOfArity(arity));
|
||||
}
|
||||
|
||||
function createTupleType(elementTypes: Type[]) {
|
||||
return createTypeReference(getTupleTypeOfArity(elementTypes.length), elementTypes);
|
||||
}
|
||||
|
||||
function getTypeFromTupleTypeNode(node: TupleTypeNode): Type {
|
||||
@ -5340,7 +5378,7 @@ namespace ts {
|
||||
while (i > 0) {
|
||||
i--;
|
||||
if (isSubtypeOfAny(types[i], types)) {
|
||||
types.splice(i, 1);
|
||||
orderedRemoveItemAt(types, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5552,6 +5590,12 @@ namespace ts {
|
||||
return nullType;
|
||||
case SyntaxKind.NeverKeyword:
|
||||
return neverType;
|
||||
case SyntaxKind.JSDocNullKeyword:
|
||||
return nullType;
|
||||
case SyntaxKind.JSDocUndefinedKeyword:
|
||||
return undefinedType;
|
||||
case SyntaxKind.JSDocNeverKeyword:
|
||||
return neverType;
|
||||
case SyntaxKind.ThisType:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
return getTypeFromThisTypeNode(node);
|
||||
@ -5845,9 +5889,6 @@ namespace ts {
|
||||
if (type.flags & TypeFlags.Reference) {
|
||||
return createTypeReference((<TypeReference>type).target, instantiateList((<TypeReference>type).typeArguments, mapper, instantiateType));
|
||||
}
|
||||
if (type.flags & TypeFlags.Tuple) {
|
||||
return createTupleType(instantiateList((<TupleType>type).elementTypes, mapper, instantiateType));
|
||||
}
|
||||
if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Primitive)) {
|
||||
return getUnionType(instantiateList((<UnionType>type).types, mapper, instantiateType), /*subtypeReduction*/ false, type.aliasSymbol, mapper.targetTypes);
|
||||
}
|
||||
@ -6267,6 +6308,18 @@ namespace ts {
|
||||
reportError(message, sourceType, targetType);
|
||||
}
|
||||
|
||||
function tryElaborateErrorsForPrimitivesAndObjects(source: Type, target: Type) {
|
||||
const sourceType = typeToString(source);
|
||||
const targetType = typeToString(target);
|
||||
|
||||
if ((globalStringType === source && stringType === target) ||
|
||||
(globalNumberType === source && numberType === target) ||
|
||||
(globalBooleanType === source && booleanType === target) ||
|
||||
(getGlobalESSymbolType() === source && esSymbolType === target)) {
|
||||
reportError(Diagnostics._0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible, targetType, sourceType);
|
||||
}
|
||||
}
|
||||
|
||||
// Compare two types and return
|
||||
// Ternary.True if they are related with no assumptions,
|
||||
// Ternary.Maybe if they are related with assumptions of other relationships, or
|
||||
@ -6390,6 +6443,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (reportErrors) {
|
||||
if (source.flags & TypeFlags.ObjectType && target.flags & TypeFlags.Primitive) {
|
||||
tryElaborateErrorsForPrimitivesAndObjects(source, target);
|
||||
}
|
||||
reportRelationError(headMessage, source, target);
|
||||
}
|
||||
return Ternary.False;
|
||||
@ -7168,8 +7224,8 @@ namespace ts {
|
||||
* Check if a Type was written as a tuple type literal.
|
||||
* Prefer using isTupleLikeType() unless the use of `elementTypes` is required.
|
||||
*/
|
||||
function isTupleType(type: Type): type is TupleType {
|
||||
return !!(type.flags & TypeFlags.Tuple);
|
||||
function isTupleType(type: Type): boolean {
|
||||
return !!(type.flags & TypeFlags.Reference && (<TypeReference>type).target.flags & TypeFlags.Tuple);
|
||||
}
|
||||
|
||||
function getFalsyFlagsOfTypes(types: Type[]): TypeFlags {
|
||||
@ -7301,11 +7357,8 @@ namespace ts {
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
return getUnionType(map((<UnionType>type).types, getWidenedConstituentType));
|
||||
}
|
||||
if (isArrayType(type)) {
|
||||
return createArrayType(getWidenedType((<TypeReference>type).typeArguments[0]));
|
||||
}
|
||||
if (isTupleType(type)) {
|
||||
return createTupleType(map(type.elementTypes, getWidenedType));
|
||||
if (isArrayType(type) || isTupleType(type)) {
|
||||
return createTypeReference((<TypeReference>type).target, map((<TypeReference>type).typeArguments, getWidenedType));
|
||||
}
|
||||
}
|
||||
return type;
|
||||
@ -7331,11 +7384,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isArrayType(type)) {
|
||||
return reportWideningErrorsInType((<TypeReference>type).typeArguments[0]);
|
||||
}
|
||||
if (isTupleType(type)) {
|
||||
for (const t of type.elementTypes) {
|
||||
if (isArrayType(type) || isTupleType(type)) {
|
||||
for (const t of (<TypeReference>type).typeArguments) {
|
||||
if (reportWideningErrorsInType(t)) {
|
||||
errorReported = true;
|
||||
}
|
||||
@ -7445,7 +7495,6 @@ namespace ts {
|
||||
function couldContainTypeParameters(type: Type): boolean {
|
||||
return !!(type.flags & TypeFlags.TypeParameter ||
|
||||
type.flags & TypeFlags.Reference && forEach((<TypeReference>type).typeArguments, couldContainTypeParameters) ||
|
||||
type.flags & TypeFlags.Tuple && forEach((<TupleType>type).elementTypes, couldContainTypeParameters) ||
|
||||
type.flags & TypeFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) ||
|
||||
type.flags & TypeFlags.UnionOrIntersection && couldUnionOrIntersectionContainTypeParameters(<UnionOrIntersectionType>type));
|
||||
}
|
||||
@ -7548,14 +7597,6 @@ namespace ts {
|
||||
inferFromTypes(sourceTypes[i], targetTypes[i]);
|
||||
}
|
||||
}
|
||||
else if (source.flags & TypeFlags.Tuple && target.flags & TypeFlags.Tuple && (<TupleType>source).elementTypes.length === (<TupleType>target).elementTypes.length) {
|
||||
// If source and target are tuples of the same size, infer from element types
|
||||
const sourceTypes = (<TupleType>source).elementTypes;
|
||||
const targetTypes = (<TupleType>target).elementTypes;
|
||||
for (let i = 0; i < sourceTypes.length; i++) {
|
||||
inferFromTypes(sourceTypes[i], targetTypes[i]);
|
||||
}
|
||||
}
|
||||
else if (target.flags & TypeFlags.UnionOrIntersection) {
|
||||
const targetTypes = (<UnionOrIntersectionType>target).types;
|
||||
let typeParameterCount = 0;
|
||||
@ -8717,7 +8758,7 @@ namespace ts {
|
||||
// The location isn't a reference to the given symbol, meaning we're being asked
|
||||
// a hypothetical question of what type the symbol would have if there was a reference
|
||||
// to it at the given location. Since we have no control flow information for the
|
||||
// hypotherical reference (control flow information is created and attached by the
|
||||
// hypothetical reference (control flow information is created and attached by the
|
||||
// binder), we simply return the declared type of the symbol.
|
||||
return getTypeOfSymbol(symbol);
|
||||
}
|
||||
@ -9100,10 +9141,6 @@ namespace ts {
|
||||
return getInferredClassType(classSymbol);
|
||||
}
|
||||
}
|
||||
const type = getContextuallyTypedThisType(container);
|
||||
if (type) {
|
||||
return type;
|
||||
}
|
||||
|
||||
const thisType = getThisTypeOfDeclaration(container);
|
||||
if (thisType) {
|
||||
@ -9344,11 +9381,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getContextuallyTypedThisType(func: FunctionLikeDeclaration): Type {
|
||||
function getContextualThisParameter(func: FunctionLikeDeclaration): Symbol {
|
||||
if (isContextSensitiveFunctionOrObjectLiteralMethod(func) && func.kind !== SyntaxKind.ArrowFunction) {
|
||||
const contextualSignature = getContextualSignature(func);
|
||||
if (contextualSignature) {
|
||||
return getThisTypeOfSignature(contextualSignature);
|
||||
return contextualSignature.thisParameter;
|
||||
}
|
||||
}
|
||||
|
||||
@ -9913,7 +9950,7 @@ namespace ts {
|
||||
// If array literal is actually a destructuring pattern, mark it as an implied type. We do this such
|
||||
// that we get the same behavior for "var [x, y] = []" and "[x, y] = []".
|
||||
if (inDestructuringPattern && elementTypes.length) {
|
||||
const type = createNewTupleType(elementTypes);
|
||||
const type = cloneTypeReference(createTupleType(elementTypes));
|
||||
type.pattern = node;
|
||||
return type;
|
||||
}
|
||||
@ -9927,7 +9964,7 @@ namespace ts {
|
||||
for (let i = elementTypes.length; i < patternElements.length; i++) {
|
||||
const patternElement = patternElements[i];
|
||||
if (hasDefaultValue(patternElement)) {
|
||||
elementTypes.push((<TupleType>contextualType).elementTypes[i]);
|
||||
elementTypes.push((<TypeReference>contextualType).typeArguments[i]);
|
||||
}
|
||||
else {
|
||||
if (patternElement.kind !== SyntaxKind.OmittedExpression) {
|
||||
@ -11929,18 +11966,12 @@ namespace ts {
|
||||
// Function interface, since they have none by default. This is a bit of a leap of faith
|
||||
// that the user will not add any.
|
||||
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
|
||||
|
||||
const constructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct);
|
||||
// TS 1.0 spec: 4.12
|
||||
// If FuncExpr is of type Any, or of an object type that has no call or construct signatures
|
||||
// but is a subtype of the Function interface, the call is an untyped function call. In an
|
||||
// untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
|
||||
|
||||
// TS 1.0 Spec: 4.12
|
||||
// In an untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
|
||||
// types are provided for the argument expressions, and the result is always of type Any.
|
||||
// We exclude union types because we may have a union of function types that happen to have
|
||||
// no common signatures.
|
||||
if (isTypeAny(funcType) ||
|
||||
(isTypeAny(apparentType) && funcType.flags & TypeFlags.TypeParameter) ||
|
||||
(!callSignatures.length && !constructSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) {
|
||||
if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) {
|
||||
// The unknownType indicates that an error already occurred (and was reported). No
|
||||
// need to report another error in this case.
|
||||
if (funcType !== unknownType && node.typeArguments) {
|
||||
@ -11963,6 +11994,29 @@ namespace ts {
|
||||
return resolveCall(node, callSignatures, candidatesOutArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* TS 1.0 spec: 4.12
|
||||
* If FuncExpr is of type Any, or of an object type that has no call or construct signatures
|
||||
* but is a subtype of the Function interface, the call is an untyped function call.
|
||||
*/
|
||||
function isUntypedFunctionCall(funcType: Type, apparentFuncType: Type, numCallSignatures: number, numConstructSignatures: number) {
|
||||
if (isTypeAny(funcType)) {
|
||||
return true;
|
||||
}
|
||||
if (isTypeAny(apparentFuncType) && funcType.flags & TypeFlags.TypeParameter) {
|
||||
return true;
|
||||
}
|
||||
if (!numCallSignatures && !numConstructSignatures) {
|
||||
// We exclude union types because we may have a union of function types that happen to have
|
||||
// no common signatures.
|
||||
if (funcType.flags & TypeFlags.Union) {
|
||||
return false;
|
||||
}
|
||||
return isTypeAssignableTo(funcType, globalFunctionType);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[]): Signature {
|
||||
if (node.arguments && languageVersion < ScriptTarget.ES5) {
|
||||
const spreadIndex = getSpreadArgumentIndex(node.arguments);
|
||||
@ -12088,8 +12142,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
|
||||
const constructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct);
|
||||
|
||||
if (isTypeAny(tagType) || (!callSignatures.length && !(tagType.flags & TypeFlags.Union) && isTypeAssignableTo(tagType, globalFunctionType))) {
|
||||
if (isUntypedFunctionCall(tagType, apparentType, callSignatures.length, constructSignatures.length)) {
|
||||
return resolveUntypedCall(node);
|
||||
}
|
||||
|
||||
@ -12134,7 +12189,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
|
||||
if (funcType === anyType || (!callSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) {
|
||||
const constructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct);
|
||||
if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) {
|
||||
return resolveUntypedCall(node);
|
||||
}
|
||||
|
||||
@ -12291,6 +12347,12 @@ namespace ts {
|
||||
|
||||
function assignContextualParameterTypes(signature: Signature, context: Signature, mapper: TypeMapper) {
|
||||
const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
|
||||
if (context.thisParameter) {
|
||||
if (!signature.thisParameter) {
|
||||
signature.thisParameter = createTransientSymbol(context.thisParameter, undefined);
|
||||
}
|
||||
assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter), mapper);
|
||||
}
|
||||
for (let i = 0; i < len; i++) {
|
||||
const parameter = signature.parameters[i];
|
||||
const contextualParameterType = getTypeAtPosition(context, i);
|
||||
@ -13038,7 +13100,7 @@ namespace ts {
|
||||
// such as NodeCheckFlags.LexicalThis on "this"expression.
|
||||
checkExpression(element);
|
||||
if (isTupleType(sourceType)) {
|
||||
error(element, Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(sourceType), (<TupleType>sourceType).elementTypes.length, elements.length);
|
||||
error(element, Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(sourceType), getTypeReferenceArity(<TypeReference>sourceType), elements.length);
|
||||
}
|
||||
else {
|
||||
error(element, Diagnostics.Type_0_has_no_property_1, typeToString(sourceType), propName);
|
||||
@ -14126,12 +14188,7 @@ namespace ts {
|
||||
checkSignatureDeclaration(node);
|
||||
if (node.kind === SyntaxKind.GetAccessor) {
|
||||
if (!isInAmbientContext(node) && nodeIsPresent(node.body) && (node.flags & NodeFlags.HasImplicitReturn)) {
|
||||
if (node.flags & NodeFlags.HasExplicitReturn) {
|
||||
if (compilerOptions.noImplicitReturns) {
|
||||
error(node.name, Diagnostics.Not_all_code_paths_return_a_value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(node.flags & NodeFlags.HasExplicitReturn)) {
|
||||
error(node.name, Diagnostics.A_get_accessor_must_return_a_value);
|
||||
}
|
||||
}
|
||||
@ -14161,7 +14218,10 @@ namespace ts {
|
||||
checkAccessorDeclarationTypesIdentical(node, otherAccessor, getThisTypeOfDeclaration, Diagnostics.get_and_set_accessor_must_have_the_same_this_type);
|
||||
}
|
||||
}
|
||||
getTypeOfAccessors(getSymbolOfNode(node));
|
||||
const returnType = getTypeOfAccessors(getSymbolOfNode(node));
|
||||
if (node.kind === SyntaxKind.GetAccessor) {
|
||||
checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType);
|
||||
}
|
||||
}
|
||||
if (node.parent.kind !== SyntaxKind.ObjectLiteralExpression) {
|
||||
checkSourceElement(node.body);
|
||||
@ -18517,7 +18577,7 @@ namespace ts {
|
||||
else if (isTypeOfKind(type, TypeFlags.StringLike)) {
|
||||
return TypeReferenceSerializationKind.StringLikeType;
|
||||
}
|
||||
else if (isTypeOfKind(type, TypeFlags.Tuple)) {
|
||||
else if (isTupleType(type)) {
|
||||
return TypeReferenceSerializationKind.ArrayLikeType;
|
||||
}
|
||||
else if (isTypeOfKind(type, TypeFlags.ESSymbol)) {
|
||||
@ -18728,7 +18788,13 @@ namespace ts {
|
||||
(augmentations || (augmentations = [])).push(file.moduleAugmentations);
|
||||
}
|
||||
if (file.symbol && file.symbol.globalExports) {
|
||||
mergeSymbolTable(globals, file.symbol.globalExports);
|
||||
// Merge in UMD exports with first-in-wins semantics (see #9771)
|
||||
const source = file.symbol.globalExports;
|
||||
for (const id in source) {
|
||||
if (!(id in globals)) {
|
||||
globals[id] = source[id];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -885,7 +885,7 @@ namespace ts {
|
||||
function convertCompilerOptionsFromJsonWorker(jsonOptions: any,
|
||||
basePath: string, errors: Diagnostic[], configFileName?: string): CompilerOptions {
|
||||
|
||||
const options: CompilerOptions = getBaseFileName(configFileName) === "jsconfig.json" ? { allowJs: true } : {};
|
||||
const options: CompilerOptions = getBaseFileName(configFileName) === "jsconfig.json" ? { allowJs: true, maxNodeModuleJsDepth: 2 } : {};
|
||||
convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_compiler_option_0, errors);
|
||||
return options;
|
||||
}
|
||||
|
||||
@ -1515,20 +1515,39 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function copyListRemovingItem<T>(item: T, list: T[]) {
|
||||
const copiedList: T[] = [];
|
||||
for (const e of list) {
|
||||
if (e !== item) {
|
||||
copiedList.push(e);
|
||||
}
|
||||
/** Remove an item from an array, moving everything to its right one space left. */
|
||||
export function orderedRemoveItemAt<T>(array: T[], index: number): void {
|
||||
// This seems to be faster than either `array.splice(i, 1)` or `array.copyWithin(i, i+ 1)`.
|
||||
for (let i = index; i < array.length - 1; i++) {
|
||||
array[i] = array[i + 1];
|
||||
}
|
||||
return copiedList;
|
||||
array.pop();
|
||||
}
|
||||
|
||||
export function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string {
|
||||
return useCaseSensitivefileNames
|
||||
export function unorderedRemoveItemAt<T>(array: T[], index: number): void {
|
||||
// Fill in the "hole" left at `index`.
|
||||
array[index] = array[array.length - 1];
|
||||
array.pop();
|
||||
}
|
||||
|
||||
/** Remove the *first* occurrence of `item` from the array. */
|
||||
export function unorderedRemoveItem<T>(array: T[], item: T): void {
|
||||
unorderedRemoveFirstItemWhere(array, element => element === item);
|
||||
}
|
||||
|
||||
/** Remove the *first* element satisfying `predicate`. */
|
||||
function unorderedRemoveFirstItemWhere<T>(array: T[], predicate: (element: T) => boolean): void {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (predicate(array[i])) {
|
||||
unorderedRemoveItemAt(array, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function createGetCanonicalFileName(useCaseSensitiveFileNames: boolean): (fileName: string) => string {
|
||||
return useCaseSensitiveFileNames
|
||||
? ((fileName) => fileName)
|
||||
: ((fileName) => fileName.toLowerCase());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1132,8 +1132,10 @@ namespace ts {
|
||||
// it if it's not a well known symbol. In that case, the text of the name will be exactly
|
||||
// what we want, namely the name expression enclosed in brackets.
|
||||
writeTextOfNode(currentText, node.name);
|
||||
// If optional property emit ?
|
||||
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature || node.kind === SyntaxKind.Parameter) && hasQuestionToken(node)) {
|
||||
// If optional property emit ? but in the case of parameterProperty declaration with "?" indicating optional parameter for the constructor
|
||||
// we don't want to emit property declaration with "?"
|
||||
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature ||
|
||||
(node.kind === SyntaxKind.Parameter && !isParameterPropertyDeclaration(node))) && hasQuestionToken(node)) {
|
||||
write("?");
|
||||
}
|
||||
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && node.parent.kind === SyntaxKind.TypeLiteral) {
|
||||
|
||||
@ -1955,6 +1955,10 @@
|
||||
"category": "Error",
|
||||
"code": 2691
|
||||
},
|
||||
"'{0}' is a primitive, but '{1}' is a wrapper object. Prefer using '{0}' when possible.": {
|
||||
"category": "Error",
|
||||
"code": 2692
|
||||
},
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 4000
|
||||
@ -2867,11 +2871,7 @@
|
||||
"Element implicitly has an 'any' type because index expression is not of type 'number'.": {
|
||||
"category": "Error",
|
||||
"code": 7015
|
||||
},
|
||||
"Property '{0}' implicitly has type 'any', because its 'set' accessor lacks a type annotation.": {
|
||||
"category": "Error",
|
||||
"code": 7016
|
||||
},
|
||||
},
|
||||
"Index signature of object type implicitly has an 'any' type.": {
|
||||
"category": "Error",
|
||||
"code": 7017
|
||||
@ -2928,6 +2928,14 @@
|
||||
"category": "Error",
|
||||
"code": 7031
|
||||
},
|
||||
"Property '{0}' implicitly has type 'any', because its set accessor lacks a parameter type annotation.": {
|
||||
"category": "Error",
|
||||
"code": 7032
|
||||
},
|
||||
"Property '{0}' implicitly has type 'any', because its get accessor lacks a return type annotation.": {
|
||||
"category": "Error",
|
||||
"code": 7033
|
||||
},
|
||||
"You cannot rename this element.": {
|
||||
"category": "Error",
|
||||
"code": 8000
|
||||
|
||||
@ -1817,6 +1817,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
else if (node.parent.kind === SyntaxKind.ConditionalExpression && (<ConditionalExpression>node.parent).condition === node) {
|
||||
return true;
|
||||
}
|
||||
else if (node.parent.kind === SyntaxKind.PrefixUnaryExpression || node.parent.kind === SyntaxKind.DeleteExpression ||
|
||||
node.parent.kind === SyntaxKind.TypeOfExpression || node.parent.kind === SyntaxKind.VoidExpression) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -6583,7 +6587,7 @@ const _super = (function (geti, seti) {
|
||||
// import { x, y } from "foo"
|
||||
// import d, * as x from "foo"
|
||||
// import d, { x, y } from "foo"
|
||||
const isNakedImport = SyntaxKind.ImportDeclaration && !(<ImportDeclaration>node).importClause;
|
||||
const isNakedImport = node.kind === SyntaxKind.ImportDeclaration && !(<ImportDeclaration>node).importClause;
|
||||
if (!isNakedImport) {
|
||||
write(varOrConst);
|
||||
write(getGeneratedNameForNode(<ImportDeclaration>node));
|
||||
|
||||
@ -912,7 +912,7 @@ namespace ts {
|
||||
// Note: it is not actually necessary to save/restore the context flags here. That's
|
||||
// because the saving/restoring of these flags happens naturally through the recursive
|
||||
// descent nature of our parser. However, we still store this here just so we can
|
||||
// assert that that invariant holds.
|
||||
// assert that invariant holds.
|
||||
const saveContextFlags = contextFlags;
|
||||
|
||||
// If we're only looking ahead, then tell the scanner to only lookahead as well.
|
||||
@ -2339,6 +2339,7 @@ namespace ts {
|
||||
token() === SyntaxKind.LessThanToken ||
|
||||
token() === SyntaxKind.QuestionToken ||
|
||||
token() === SyntaxKind.ColonToken ||
|
||||
token() === SyntaxKind.CommaToken ||
|
||||
canParseSemicolon();
|
||||
}
|
||||
return false;
|
||||
@ -2765,7 +2766,7 @@ namespace ts {
|
||||
// Note: for ease of implementation we treat productions '2' and '3' as the same thing.
|
||||
// (i.e. they're both BinaryExpressions with an assignment operator in it).
|
||||
|
||||
// First, do the simple check if we have a YieldExpression (production '5').
|
||||
// First, do the simple check if we have a YieldExpression (production '6').
|
||||
if (isYieldExpression()) {
|
||||
return parseYieldExpression();
|
||||
}
|
||||
@ -3373,24 +3374,40 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse ES7 unary expression and await expression
|
||||
* Parse ES7 exponential expression and await expression
|
||||
*
|
||||
* ES7 ExponentiationExpression:
|
||||
* 1) UnaryExpression[?Yield]
|
||||
* 2) UpdateExpression[?Yield] ** ExponentiationExpression[?Yield]
|
||||
*
|
||||
* ES7 UnaryExpression:
|
||||
* 1) SimpleUnaryExpression[?yield]
|
||||
* 2) IncrementExpression[?yield] ** UnaryExpression[?yield]
|
||||
*/
|
||||
function parseUnaryExpressionOrHigher(): UnaryExpression | BinaryExpression {
|
||||
if (isAwaitExpression()) {
|
||||
return parseAwaitExpression();
|
||||
}
|
||||
|
||||
if (isIncrementExpression()) {
|
||||
/**
|
||||
* ES7 UpdateExpression:
|
||||
* 1) LeftHandSideExpression[?Yield]
|
||||
* 2) LeftHandSideExpression[?Yield][no LineTerminator here]++
|
||||
* 3) LeftHandSideExpression[?Yield][no LineTerminator here]--
|
||||
* 4) ++UnaryExpression[?Yield]
|
||||
* 5) --UnaryExpression[?Yield]
|
||||
*/
|
||||
if (isUpdateExpression()) {
|
||||
const incrementExpression = parseIncrementExpression();
|
||||
return token() === SyntaxKind.AsteriskAsteriskToken ?
|
||||
<BinaryExpression>parseBinaryExpressionRest(getBinaryOperatorPrecedence(), incrementExpression) :
|
||||
incrementExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
* ES7 UnaryExpression:
|
||||
* 1) UpdateExpression[?yield]
|
||||
* 2) delete UpdateExpression[?yield]
|
||||
* 3) void UpdateExpression[?yield]
|
||||
* 4) typeof UpdateExpression[?yield]
|
||||
* 5) + UpdateExpression[?yield]
|
||||
* 6) - UpdateExpression[?yield]
|
||||
* 7) ~ UpdateExpression[?yield]
|
||||
* 8) ! UpdateExpression[?yield]
|
||||
*/
|
||||
const unaryOperator = token();
|
||||
const simpleUnaryExpression = parseSimpleUnaryExpression();
|
||||
if (token() === SyntaxKind.AsteriskAsteriskToken) {
|
||||
@ -3408,8 +3425,8 @@ namespace ts {
|
||||
/**
|
||||
* Parse ES7 simple-unary expression or higher:
|
||||
*
|
||||
* ES7 SimpleUnaryExpression:
|
||||
* 1) IncrementExpression[?yield]
|
||||
* ES7 UnaryExpression:
|
||||
* 1) UpdateExpression[?yield]
|
||||
* 2) delete UnaryExpression[?yield]
|
||||
* 3) void UnaryExpression[?yield]
|
||||
* 4) typeof UnaryExpression[?yield]
|
||||
@ -3432,13 +3449,15 @@ namespace ts {
|
||||
return parseTypeOfExpression();
|
||||
case SyntaxKind.VoidKeyword:
|
||||
return parseVoidExpression();
|
||||
case SyntaxKind.AwaitKeyword:
|
||||
return parseAwaitExpression();
|
||||
case SyntaxKind.LessThanToken:
|
||||
// This is modified UnaryExpression grammar in TypeScript
|
||||
// UnaryExpression (modified):
|
||||
// < type > UnaryExpression
|
||||
return parseTypeAssertion();
|
||||
case SyntaxKind.AwaitKeyword:
|
||||
if (isAwaitExpression()) {
|
||||
return parseAwaitExpression();
|
||||
}
|
||||
default:
|
||||
return parseIncrementExpression();
|
||||
}
|
||||
@ -3447,14 +3466,14 @@ namespace ts {
|
||||
/**
|
||||
* Check if the current token can possibly be an ES7 increment expression.
|
||||
*
|
||||
* ES7 IncrementExpression:
|
||||
* ES7 UpdateExpression:
|
||||
* LeftHandSideExpression[?Yield]
|
||||
* LeftHandSideExpression[?Yield][no LineTerminator here]++
|
||||
* LeftHandSideExpression[?Yield][no LineTerminator here]--
|
||||
* ++LeftHandSideExpression[?Yield]
|
||||
* --LeftHandSideExpression[?Yield]
|
||||
*/
|
||||
function isIncrementExpression(): boolean {
|
||||
function isUpdateExpression(): boolean {
|
||||
// This function is called inside parseUnaryExpression to decide
|
||||
// whether to call parseSimpleUnaryExpression or call parseIncrementExpression directly
|
||||
switch (token()) {
|
||||
@ -3465,6 +3484,7 @@ namespace ts {
|
||||
case SyntaxKind.DeleteKeyword:
|
||||
case SyntaxKind.TypeOfKeyword:
|
||||
case SyntaxKind.VoidKeyword:
|
||||
case SyntaxKind.AwaitKeyword:
|
||||
return false;
|
||||
case SyntaxKind.LessThanToken:
|
||||
// If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression
|
||||
@ -5893,6 +5913,9 @@ namespace ts {
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.VoidKeyword:
|
||||
case SyntaxKind.NullKeyword:
|
||||
case SyntaxKind.UndefinedKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
return parseTokenNode<JSDocType>();
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
|
||||
@ -720,8 +720,9 @@ namespace ts {
|
||||
const typesFile = tryReadTypesSection(packageJsonPath, candidate, state);
|
||||
if (typesFile) {
|
||||
const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(typesFile), state.host);
|
||||
// The package.json "typings" property must specify the file with extension, so just try that exact filename.
|
||||
const result = tryFile(typesFile, failedLookupLocation, onlyRecordFailures, state);
|
||||
// A package.json "typings" may specify an exact filename, or may choose to omit an extension.
|
||||
const result = tryFile(typesFile, failedLookupLocation, onlyRecordFailures, state) ||
|
||||
tryAddingExtensions(typesFile, extensions, failedLookupLocation, onlyRecordFailures, state);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
@ -1100,7 +1101,7 @@ namespace ts {
|
||||
// - This calls resolveModuleNames, and then calls findSourceFile for each resolved module.
|
||||
// As all these operations happen - and are nested - within the createProgram call, they close over the below variables.
|
||||
// The current resolution depth is tracked by incrementing/decrementing as the depth first search progresses.
|
||||
const maxNodeModulesJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 2;
|
||||
const maxNodeModulesJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 0;
|
||||
let currentNodeModulesDepth = 0;
|
||||
|
||||
// If a module has some of its imports skipped due to being at the depth limit under node_modules, then track
|
||||
|
||||
@ -285,13 +285,10 @@ namespace ts {
|
||||
function removeFileWatcherCallback(filePath: string, callback: FileWatcherCallback) {
|
||||
const callbacks = fileWatcherCallbacks[filePath];
|
||||
if (callbacks) {
|
||||
const newCallbacks = copyListRemovingItem(callback, callbacks);
|
||||
if (newCallbacks.length === 0) {
|
||||
unorderedRemoveItem(callbacks, callback);
|
||||
if (callbacks.length === 0) {
|
||||
delete fileWatcherCallbacks[filePath];
|
||||
}
|
||||
else {
|
||||
fileWatcherCallbacks[filePath] = newCallbacks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -489,10 +489,7 @@ namespace ts {
|
||||
sourceFile.fileWatcher.close();
|
||||
sourceFile.fileWatcher = undefined;
|
||||
if (removed) {
|
||||
const index = rootFileNames.indexOf(sourceFile.fileName);
|
||||
if (index >= 0) {
|
||||
rootFileNames.splice(index, 1);
|
||||
}
|
||||
unorderedRemoveItem(rootFileNames, sourceFile.fileName);
|
||||
}
|
||||
startTimerForRecompilation();
|
||||
}
|
||||
|
||||
@ -351,6 +351,9 @@ namespace ts {
|
||||
JSDocPropertyTag,
|
||||
JSDocTypeLiteral,
|
||||
JSDocLiteralType,
|
||||
JSDocNullKeyword,
|
||||
JSDocUndefinedKeyword,
|
||||
JSDocNeverKeyword,
|
||||
|
||||
// Synthesized list
|
||||
SyntaxList,
|
||||
@ -383,7 +386,7 @@ namespace ts {
|
||||
FirstJSDocNode = JSDocTypeExpression,
|
||||
LastJSDocNode = JSDocLiteralType,
|
||||
FirstJSDocTagNode = JSDocComment,
|
||||
LastJSDocTagNode = JSDocLiteralType
|
||||
LastJSDocTagNode = JSDocNeverKeyword
|
||||
}
|
||||
|
||||
export const enum NodeFlags {
|
||||
@ -2263,7 +2266,7 @@ namespace ts {
|
||||
Class = 1 << 15, // Class
|
||||
Interface = 1 << 16, // Interface
|
||||
Reference = 1 << 17, // Generic type reference
|
||||
Tuple = 1 << 18, // Tuple
|
||||
Tuple = 1 << 18, // Synthesized generic tuple type
|
||||
Union = 1 << 19, // Union (T | U)
|
||||
Intersection = 1 << 20, // Intersection (T & U)
|
||||
Anonymous = 1 << 21, // Anonymous
|
||||
@ -2385,11 +2388,6 @@ namespace ts {
|
||||
instantiations: Map<TypeReference>; // Generic instantiation cache
|
||||
}
|
||||
|
||||
export interface TupleType extends ObjectType {
|
||||
elementTypes: Type[]; // Element types
|
||||
thisType?: Type; // This-type of tuple (only needed for tuples that are constraints of type parameters)
|
||||
}
|
||||
|
||||
export interface UnionOrIntersectionType extends Type {
|
||||
types: Type[]; // Constituent types
|
||||
/* @internal */
|
||||
|
||||
@ -301,6 +301,10 @@ namespace ts {
|
||||
return node.kind >= SyntaxKind.FirstJSDocNode && node.kind <= SyntaxKind.LastJSDocNode;
|
||||
}
|
||||
|
||||
export function isJSDocTag(node: Node) {
|
||||
return node.kind >= SyntaxKind.FirstJSDocTagNode && node.kind <= SyntaxKind.LastJSDocTagNode;
|
||||
}
|
||||
|
||||
export function getNonDecoratorTokenPosOfNode(node: Node, sourceFile?: SourceFile): number {
|
||||
if (nodeIsMissing(node) || !node.decorators) {
|
||||
return getTokenPosOfNode(node, sourceFile);
|
||||
@ -1031,6 +1035,18 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function isCallLikeExpression(node: Node): node is CallLikeExpression {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
case SyntaxKind.Decorator:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function getInvokedExpression(node: CallLikeExpression): Expression {
|
||||
if (node.kind === SyntaxKind.TaggedTemplateExpression) {
|
||||
return (<TaggedTemplateExpression>node).tag;
|
||||
@ -2655,10 +2671,17 @@ namespace ts {
|
||||
return token >= SyntaxKind.FirstAssignment && token <= SyntaxKind.LastAssignment;
|
||||
}
|
||||
|
||||
export function isExpressionWithTypeArgumentsInClassExtendsClause(node: Node): boolean {
|
||||
return node.kind === SyntaxKind.ExpressionWithTypeArguments &&
|
||||
/** Get `C` given `N` if `N` is in the position `class C extends N` where `N` is an ExpressionWithTypeArguments. */
|
||||
export function tryGetClassExtendingExpressionWithTypeArguments(node: Node): ClassLikeDeclaration | undefined {
|
||||
if (node.kind === SyntaxKind.ExpressionWithTypeArguments &&
|
||||
(<HeritageClause>node.parent).token === SyntaxKind.ExtendsKeyword &&
|
||||
isClassLike(node.parent.parent);
|
||||
isClassLike(node.parent.parent)) {
|
||||
return node.parent.parent;
|
||||
}
|
||||
}
|
||||
|
||||
export function isExpressionWithTypeArgumentsInClassExtendsClause(node: Node): boolean {
|
||||
return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined;
|
||||
}
|
||||
|
||||
export function isEntityNameExpression(node: Expression): node is EntityNameExpression {
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
/// <reference path="harness.ts" />
|
||||
/// <reference path="runnerbase.ts" />
|
||||
/// <reference path="typeWriter.ts" />
|
||||
// In harness baselines, null is different than undefined. See `generateActual` in `harness.ts`.
|
||||
/* tslint:disable:no-null-keyword */
|
||||
|
||||
const enum CompilerTestType {
|
||||
Conformance,
|
||||
@ -136,27 +134,16 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
otherFiles = undefined;
|
||||
});
|
||||
|
||||
function getByteOrderMarkText(file: Harness.Compiler.GeneratedFile): string {
|
||||
return file.writeByteOrderMark ? "\u00EF\u00BB\u00BF" : "";
|
||||
}
|
||||
|
||||
function getErrorBaseline(toBeCompiled: Harness.Compiler.TestFile[], otherFiles: Harness.Compiler.TestFile[], result: Harness.Compiler.CompilerResult) {
|
||||
return Harness.Compiler.getErrorBaseline(toBeCompiled.concat(otherFiles), result.errors);
|
||||
}
|
||||
|
||||
// check errors
|
||||
it("Correct errors for " + fileName, () => {
|
||||
if (this.errors) {
|
||||
Harness.Baseline.runBaseline("Correct errors for " + fileName, justName.replace(/\.tsx?$/, ".errors.txt"), (): string => {
|
||||
if (result.errors.length === 0) return null;
|
||||
return getErrorBaseline(toBeCompiled, otherFiles, result);
|
||||
});
|
||||
Harness.Compiler.doErrorBaseline(justName, toBeCompiled.concat(otherFiles), result.errors);
|
||||
}
|
||||
});
|
||||
|
||||
it (`Correct module resolution tracing for ${fileName}`, () => {
|
||||
if (options.traceResolution) {
|
||||
Harness.Baseline.runBaseline("Correct module resolution tracing for " + fileName, justName.replace(/\.tsx?$/, ".trace.json"), () => {
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".trace.json"), () => {
|
||||
return JSON.stringify(result.traceResults || [], undefined, 4);
|
||||
});
|
||||
}
|
||||
@ -165,11 +152,13 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
// Source maps?
|
||||
it("Correct sourcemap content for " + fileName, () => {
|
||||
if (options.sourceMap || options.inlineSourceMap) {
|
||||
Harness.Baseline.runBaseline("Correct sourcemap content for " + fileName, justName.replace(/\.tsx?$/, ".sourcemap.txt"), () => {
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".sourcemap.txt"), () => {
|
||||
const record = result.getSourceMapRecord();
|
||||
if (options.noEmitOnError && result.errors.length !== 0 && record === undefined) {
|
||||
// Because of the noEmitOnError option no files are created. We need to return null because baselining isn"t required.
|
||||
// Because of the noEmitOnError option no files are created. We need to return null because baselining isn't required.
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
return record;
|
||||
});
|
||||
@ -178,87 +167,12 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
|
||||
it("Correct JS output for " + fileName, () => {
|
||||
if (hasNonDtsFiles && this.emit) {
|
||||
if (!options.noEmit && result.files.length === 0 && result.errors.length === 0) {
|
||||
throw new Error("Expected at least one js file to be emitted or at least one error to be created.");
|
||||
}
|
||||
|
||||
// check js output
|
||||
Harness.Baseline.runBaseline("Correct JS output for " + fileName, justName.replace(/\.tsx?/, ".js"), () => {
|
||||
let tsCode = "";
|
||||
const tsSources = otherFiles.concat(toBeCompiled);
|
||||
if (tsSources.length > 1) {
|
||||
tsCode += "//// [" + fileName + "] ////\r\n\r\n";
|
||||
}
|
||||
for (let i = 0; i < tsSources.length; i++) {
|
||||
tsCode += "//// [" + Harness.Path.getFileName(tsSources[i].unitName) + "]\r\n";
|
||||
tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? "\r\n" : "");
|
||||
}
|
||||
|
||||
let jsCode = "";
|
||||
for (let i = 0; i < result.files.length; i++) {
|
||||
jsCode += "//// [" + Harness.Path.getFileName(result.files[i].fileName) + "]\r\n";
|
||||
jsCode += getByteOrderMarkText(result.files[i]);
|
||||
jsCode += result.files[i].code;
|
||||
}
|
||||
|
||||
if (result.declFilesCode.length > 0) {
|
||||
jsCode += "\r\n\r\n";
|
||||
for (let i = 0; i < result.declFilesCode.length; i++) {
|
||||
jsCode += "//// [" + Harness.Path.getFileName(result.declFilesCode[i].fileName) + "]\r\n";
|
||||
jsCode += getByteOrderMarkText(result.declFilesCode[i]);
|
||||
jsCode += result.declFilesCode[i].code;
|
||||
}
|
||||
}
|
||||
|
||||
const declFileCompilationResult =
|
||||
Harness.Compiler.compileDeclarationFiles(
|
||||
toBeCompiled, otherFiles, result, harnessSettings, options, /*currentDirectory*/ undefined);
|
||||
|
||||
if (declFileCompilationResult && declFileCompilationResult.declResult.errors.length) {
|
||||
jsCode += "\r\n\r\n//// [DtsFileErrors]\r\n";
|
||||
jsCode += "\r\n\r\n";
|
||||
jsCode += getErrorBaseline(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles, declFileCompilationResult.declResult);
|
||||
}
|
||||
|
||||
if (jsCode.length > 0) {
|
||||
return tsCode + "\r\n\r\n" + jsCode;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
Harness.Compiler.doJsEmitBaseline(justName, fileName, options, result, toBeCompiled, otherFiles, harnessSettings);
|
||||
}
|
||||
});
|
||||
|
||||
it("Correct Sourcemap output for " + fileName, () => {
|
||||
if (options.inlineSourceMap) {
|
||||
if (result.sourceMaps.length > 0) {
|
||||
throw new Error("No sourcemap files should be generated if inlineSourceMaps was set.");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else if (options.sourceMap) {
|
||||
if (result.sourceMaps.length !== result.files.length) {
|
||||
throw new Error("Number of sourcemap files should be same as js files.");
|
||||
}
|
||||
|
||||
Harness.Baseline.runBaseline("Correct Sourcemap output for " + fileName, justName.replace(/\.tsx?/, ".js.map"), () => {
|
||||
if (options.noEmitOnError && result.errors.length !== 0 && result.sourceMaps.length === 0) {
|
||||
// We need to return null here or the runBaseLine will actually create a empty file.
|
||||
// Baselining isn't required here because there is no output.
|
||||
return null;
|
||||
}
|
||||
|
||||
let sourceMapCode = "";
|
||||
for (let i = 0; i < result.sourceMaps.length; i++) {
|
||||
sourceMapCode += "//// [" + Harness.Path.getFileName(result.sourceMaps[i].fileName) + "]\r\n";
|
||||
sourceMapCode += getByteOrderMarkText(result.sourceMaps[i]);
|
||||
sourceMapCode += result.sourceMaps[i].code;
|
||||
}
|
||||
|
||||
return sourceMapCode;
|
||||
});
|
||||
}
|
||||
Harness.Compiler.doSourcemapBaseline(justName, options, result);
|
||||
});
|
||||
|
||||
it("Correct type/symbol baselines for " + fileName, () => {
|
||||
@ -266,129 +180,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
return;
|
||||
}
|
||||
|
||||
// NEWTODO: Type baselines
|
||||
if (result.errors.length !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The full walker simulates the types that you would get from doing a full
|
||||
// compile. The pull walker simulates the types you get when you just do
|
||||
// a type query for a random node (like how the LS would do it). Most of the
|
||||
// time, these will be the same. However, occasionally, they can be different.
|
||||
// Specifically, when the compiler internally depends on symbol IDs to order
|
||||
// things, then we may see different results because symbols can be created in a
|
||||
// different order with 'pull' operations, and thus can produce slightly differing
|
||||
// output.
|
||||
//
|
||||
// For example, with a full type check, we may see a type displayed as: number | string
|
||||
// But with a pull type check, we may see it as: string | number
|
||||
//
|
||||
// These types are equivalent, but depend on what order the compiler observed
|
||||
// certain parts of the program.
|
||||
|
||||
const program = result.program;
|
||||
const allFiles = toBeCompiled.concat(otherFiles).filter(file => !!program.getSourceFile(file.unitName));
|
||||
|
||||
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ true);
|
||||
|
||||
const fullResults = ts.createMap<TypeWriterResult[]>();
|
||||
const pullResults = ts.createMap<TypeWriterResult[]>();
|
||||
|
||||
for (const sourceFile of allFiles) {
|
||||
fullResults[sourceFile.unitName] = fullWalker.getTypeAndSymbols(sourceFile.unitName);
|
||||
pullResults[sourceFile.unitName] = fullWalker.getTypeAndSymbols(sourceFile.unitName);
|
||||
}
|
||||
|
||||
// Produce baselines. The first gives the types for all expressions.
|
||||
// The second gives symbols for all identifiers.
|
||||
let e1: Error, e2: Error;
|
||||
try {
|
||||
checkBaseLines(/*isSymbolBaseLine*/ false);
|
||||
}
|
||||
catch (e) {
|
||||
e1 = e;
|
||||
}
|
||||
|
||||
try {
|
||||
checkBaseLines(/*isSymbolBaseLine*/ true);
|
||||
}
|
||||
catch (e) {
|
||||
e2 = e;
|
||||
}
|
||||
|
||||
if (e1 || e2) {
|
||||
throw e1 || e2;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
function checkBaseLines(isSymbolBaseLine: boolean) {
|
||||
const fullBaseLine = generateBaseLine(fullResults, isSymbolBaseLine);
|
||||
const pullBaseLine = generateBaseLine(pullResults, isSymbolBaseLine);
|
||||
|
||||
const fullExtension = isSymbolBaseLine ? ".symbols" : ".types";
|
||||
const pullExtension = isSymbolBaseLine ? ".symbols.pull" : ".types.pull";
|
||||
|
||||
if (fullBaseLine !== pullBaseLine) {
|
||||
Harness.Baseline.runBaseline("Correct full information for " + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine);
|
||||
Harness.Baseline.runBaseline("Correct pull information for " + fileName, justName.replace(/\.tsx?/, pullExtension), () => pullBaseLine);
|
||||
}
|
||||
else {
|
||||
Harness.Baseline.runBaseline("Correct information for " + fileName, justName.replace(/\.tsx?/, fullExtension), () => fullBaseLine);
|
||||
}
|
||||
}
|
||||
|
||||
function generateBaseLine(typeWriterResults: ts.Map<TypeWriterResult[]>, isSymbolBaseline: boolean): string {
|
||||
const typeLines: string[] = [];
|
||||
const typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {};
|
||||
|
||||
allFiles.forEach(file => {
|
||||
const codeLines = file.content.split("\n");
|
||||
typeWriterResults[file.unitName].forEach(result => {
|
||||
if (isSymbolBaseline && !result.symbol) {
|
||||
return;
|
||||
}
|
||||
|
||||
const typeOrSymbolString = isSymbolBaseline ? result.symbol : result.type;
|
||||
const formattedLine = result.sourceText.replace(/\r?\n/g, "") + " : " + typeOrSymbolString;
|
||||
if (!typeMap[file.unitName]) {
|
||||
typeMap[file.unitName] = {};
|
||||
}
|
||||
|
||||
let typeInfo = [formattedLine];
|
||||
const existingTypeInfo = typeMap[file.unitName][result.line];
|
||||
if (existingTypeInfo) {
|
||||
typeInfo = existingTypeInfo.concat(typeInfo);
|
||||
}
|
||||
typeMap[file.unitName][result.line] = typeInfo;
|
||||
});
|
||||
|
||||
typeLines.push("=== " + file.unitName + " ===\r\n");
|
||||
for (let i = 0; i < codeLines.length; i++) {
|
||||
const currentCodeLine = codeLines[i];
|
||||
typeLines.push(currentCodeLine + "\r\n");
|
||||
if (typeMap[file.unitName]) {
|
||||
const typeInfo = typeMap[file.unitName][i];
|
||||
if (typeInfo) {
|
||||
typeInfo.forEach(ty => {
|
||||
typeLines.push(">" + ty + "\r\n");
|
||||
});
|
||||
if (i + 1 < codeLines.length && (codeLines[i + 1].match(/^\s*[{|}]\s*$/) || codeLines[i + 1].trim() === "")) {
|
||||
}
|
||||
else {
|
||||
typeLines.push("\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
typeLines.push("No type information for this code.");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return typeLines.join("");
|
||||
}
|
||||
|
||||
Harness.Compiler.doTypeAndSymbolBaseline(justName, result, toBeCompiled.concat(otherFiles).filter(file => !!result.program.getSourceFile(file.unitName)));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -206,6 +206,24 @@ namespace FourSlash {
|
||||
|
||||
private inputFiles = ts.createMap<string>(); // Map between inputFile's fileName and its content for easily looking up when resolving references
|
||||
|
||||
private static getDisplayPartsJson(displayParts: ts.SymbolDisplayPart[]) {
|
||||
let result = "";
|
||||
ts.forEach(displayParts, part => {
|
||||
if (result) {
|
||||
result += ",\n ";
|
||||
}
|
||||
else {
|
||||
result = "[\n ";
|
||||
}
|
||||
result += JSON.stringify(part);
|
||||
});
|
||||
if (result) {
|
||||
result += "\n]";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Add input file which has matched file name with the given reference-file path.
|
||||
// This is necessary when resolveReference flag is specified
|
||||
private addMatchedInputFile(referenceFilePath: string, extensions: string[]) {
|
||||
@ -777,6 +795,20 @@ namespace FourSlash {
|
||||
ts.forEachProperty(this.rangesByText(), ranges => this.verifyRangesReferenceEachOther(ranges));
|
||||
}
|
||||
|
||||
public verifyDisplayPartsOfReferencedSymbol(expected: ts.SymbolDisplayPart[]) {
|
||||
const referencedSymbols = this.findReferencesAtCaret();
|
||||
|
||||
if (referencedSymbols.length === 0) {
|
||||
this.raiseError("No referenced symbols found at current caret position");
|
||||
}
|
||||
else if (referencedSymbols.length > 1) {
|
||||
this.raiseError("More than one referenced symbol found");
|
||||
}
|
||||
|
||||
assert.equal(TestState.getDisplayPartsJson(referencedSymbols[0].definition.displayParts),
|
||||
TestState.getDisplayPartsJson(expected), this.messageAtLastKnownMarker("referenced symbol definition display parts"));
|
||||
}
|
||||
|
||||
private verifyReferencesWorker(references: ts.ReferenceEntry[], fileName: string, start: number, end: number, isWriteAccess?: boolean, isDefinition?: boolean) {
|
||||
for (let i = 0; i < references.length; i++) {
|
||||
const reference = references[i];
|
||||
@ -811,6 +843,10 @@ namespace FourSlash {
|
||||
return this.languageService.getReferencesAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
}
|
||||
|
||||
private findReferencesAtCaret() {
|
||||
return this.languageService.findReferences(this.activeFile.fileName, this.currentCaretPosition);
|
||||
}
|
||||
|
||||
public getSyntacticDiagnostics(expected: string) {
|
||||
const diagnostics = this.languageService.getSyntacticDiagnostics(this.activeFile.fileName);
|
||||
this.testDiagnostics(expected, diagnostics);
|
||||
@ -856,30 +892,12 @@ namespace FourSlash {
|
||||
displayParts: ts.SymbolDisplayPart[],
|
||||
documentation: ts.SymbolDisplayPart[]) {
|
||||
|
||||
function getDisplayPartsJson(displayParts: ts.SymbolDisplayPart[]) {
|
||||
let result = "";
|
||||
ts.forEach(displayParts, part => {
|
||||
if (result) {
|
||||
result += ",\n ";
|
||||
}
|
||||
else {
|
||||
result = "[\n ";
|
||||
}
|
||||
result += JSON.stringify(part);
|
||||
});
|
||||
if (result) {
|
||||
result += "\n]";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
assert.equal(actualQuickInfo.kind, kind, this.messageAtLastKnownMarker("QuickInfo kind"));
|
||||
assert.equal(actualQuickInfo.kindModifiers, kindModifiers, this.messageAtLastKnownMarker("QuickInfo kindModifiers"));
|
||||
assert.equal(JSON.stringify(actualQuickInfo.textSpan), JSON.stringify(textSpan), this.messageAtLastKnownMarker("QuickInfo textSpan"));
|
||||
assert.equal(getDisplayPartsJson(actualQuickInfo.displayParts), getDisplayPartsJson(displayParts), this.messageAtLastKnownMarker("QuickInfo displayParts"));
|
||||
assert.equal(getDisplayPartsJson(actualQuickInfo.documentation), getDisplayPartsJson(documentation), this.messageAtLastKnownMarker("QuickInfo documentation"));
|
||||
assert.equal(TestState.getDisplayPartsJson(actualQuickInfo.displayParts), TestState.getDisplayPartsJson(displayParts), this.messageAtLastKnownMarker("QuickInfo displayParts"));
|
||||
assert.equal(TestState.getDisplayPartsJson(actualQuickInfo.documentation), TestState.getDisplayPartsJson(documentation), this.messageAtLastKnownMarker("QuickInfo documentation"));
|
||||
}
|
||||
|
||||
public verifyRenameLocations(findInStrings: boolean, findInComments: boolean, ranges?: Range[]) {
|
||||
@ -1132,12 +1150,10 @@ namespace FourSlash {
|
||||
|
||||
}
|
||||
Harness.Baseline.runBaseline(
|
||||
"Breakpoint Locations for " + this.activeFile.fileName,
|
||||
baselineFile,
|
||||
() => {
|
||||
return this.baselineCurrentFileLocations(pos => this.getBreakpointStatementLocation(pos));
|
||||
},
|
||||
true /* run immediately */);
|
||||
});
|
||||
}
|
||||
|
||||
public baselineGetEmitOutput() {
|
||||
@ -1159,7 +1175,6 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
Harness.Baseline.runBaseline(
|
||||
"Generate getEmitOutput baseline : " + emitFiles.join(" "),
|
||||
this.testData.globalOptions[metadataOptionNames.baselineFile],
|
||||
() => {
|
||||
let resultString = "";
|
||||
@ -1185,8 +1200,7 @@ namespace FourSlash {
|
||||
});
|
||||
|
||||
return resultString;
|
||||
},
|
||||
true /* run immediately */);
|
||||
});
|
||||
}
|
||||
|
||||
public printBreakpointLocation(pos: number) {
|
||||
@ -1550,7 +1564,7 @@ namespace FourSlash {
|
||||
public goToDefinition(definitionIndex: number) {
|
||||
const definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
if (!definitions || !definitions.length) {
|
||||
this.raiseError("goToDefinition failed - expected to at least one definition location but got 0");
|
||||
this.raiseError("goToDefinition failed - expected to find at least one definition location but got 0");
|
||||
}
|
||||
|
||||
if (definitionIndex >= definitions.length) {
|
||||
@ -1565,7 +1579,7 @@ namespace FourSlash {
|
||||
public goToTypeDefinition(definitionIndex: number) {
|
||||
const definitions = this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
if (!definitions || !definitions.length) {
|
||||
this.raiseError("goToTypeDefinition failed - expected to at least one definition location but got 0");
|
||||
this.raiseError("goToTypeDefinition failed - expected to find at least one definition location but got 0");
|
||||
}
|
||||
|
||||
if (definitionIndex >= definitions.length) {
|
||||
@ -1586,7 +1600,7 @@ namespace FourSlash {
|
||||
this.raiseError(`goToDefinition - expected to 0 definition locations but got ${definitions.length}`);
|
||||
}
|
||||
else if (!foundDefinitions && !negative) {
|
||||
this.raiseError("goToDefinition - expected to at least one definition location but got 0");
|
||||
this.raiseError("goToDefinition - expected to find at least one definition location but got 0");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1729,13 +1743,11 @@ namespace FourSlash {
|
||||
|
||||
public baselineCurrentFileNameOrDottedNameSpans() {
|
||||
Harness.Baseline.runBaseline(
|
||||
"Name OrDottedNameSpans for " + this.activeFile.fileName,
|
||||
this.testData.globalOptions[metadataOptionNames.baselineFile],
|
||||
() => {
|
||||
return this.baselineCurrentFileLocations(pos =>
|
||||
this.getNameOrDottedNameSpan(pos));
|
||||
},
|
||||
true /* run immediately */);
|
||||
});
|
||||
}
|
||||
|
||||
public printNameOrDottedNameSpans(pos: number) {
|
||||
@ -2952,6 +2964,10 @@ namespace FourSlashInterface {
|
||||
this.state.verifyRangesReferenceEachOther(ranges);
|
||||
}
|
||||
|
||||
public findReferencesDefinitionDisplayPartsAtCaretAre(expected: ts.SymbolDisplayPart[]) {
|
||||
this.state.verifyDisplayPartsOfReferencedSymbol(expected);
|
||||
}
|
||||
|
||||
public rangesWithSameTextReferenceEachOther() {
|
||||
this.state.verifyRangesWithSameTextReferenceEachOther();
|
||||
}
|
||||
|
||||
@ -1328,6 +1328,233 @@ namespace Harness {
|
||||
Harness.IO.newLine() + Harness.IO.newLine() + outputLines.join("\r\n");
|
||||
}
|
||||
|
||||
export function doErrorBaseline(baselinePath: string, inputFiles: TestFile[], errors: ts.Diagnostic[]) {
|
||||
Harness.Baseline.runBaseline(baselinePath.replace(/\.tsx?$/, ".errors.txt"), (): string => {
|
||||
if (errors.length === 0) {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
return getErrorBaseline(inputFiles, errors);
|
||||
});
|
||||
}
|
||||
|
||||
export function doTypeAndSymbolBaseline(baselinePath: string, result: CompilerResult, allFiles: {unitName: string, content: string}[], opts?: Harness.Baseline.BaselineOptions) {
|
||||
if (result.errors.length !== 0) {
|
||||
return;
|
||||
}
|
||||
// The full walker simulates the types that you would get from doing a full
|
||||
// compile. The pull walker simulates the types you get when you just do
|
||||
// a type query for a random node (like how the LS would do it). Most of the
|
||||
// time, these will be the same. However, occasionally, they can be different.
|
||||
// Specifically, when the compiler internally depends on symbol IDs to order
|
||||
// things, then we may see different results because symbols can be created in a
|
||||
// different order with 'pull' operations, and thus can produce slightly differing
|
||||
// output.
|
||||
//
|
||||
// For example, with a full type check, we may see a type displayed as: number | string
|
||||
// But with a pull type check, we may see it as: string | number
|
||||
//
|
||||
// These types are equivalent, but depend on what order the compiler observed
|
||||
// certain parts of the program.
|
||||
|
||||
const program = result.program;
|
||||
|
||||
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ true);
|
||||
|
||||
const fullResults = ts.createMap<TypeWriterResult[]>();
|
||||
|
||||
for (const sourceFile of allFiles) {
|
||||
fullResults[sourceFile.unitName] = fullWalker.getTypeAndSymbols(sourceFile.unitName);
|
||||
}
|
||||
|
||||
// Produce baselines. The first gives the types for all expressions.
|
||||
// The second gives symbols for all identifiers.
|
||||
let typesError: Error, symbolsError: Error;
|
||||
try {
|
||||
checkBaseLines(/*isSymbolBaseLine*/ false);
|
||||
}
|
||||
catch (e) {
|
||||
typesError = e;
|
||||
}
|
||||
|
||||
try {
|
||||
checkBaseLines(/*isSymbolBaseLine*/ true);
|
||||
}
|
||||
catch (e) {
|
||||
symbolsError = e;
|
||||
}
|
||||
|
||||
if (typesError && symbolsError) {
|
||||
throw new Error(typesError.message + ts.sys.newLine + symbolsError.message);
|
||||
}
|
||||
|
||||
if (typesError) {
|
||||
throw typesError;
|
||||
}
|
||||
|
||||
if (symbolsError) {
|
||||
throw symbolsError;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
function checkBaseLines(isSymbolBaseLine: boolean) {
|
||||
const fullBaseLine = generateBaseLine(fullResults, isSymbolBaseLine);
|
||||
|
||||
const fullExtension = isSymbolBaseLine ? ".symbols" : ".types";
|
||||
|
||||
// When calling this function from rwc-runner, the baselinePath will have no extension.
|
||||
// As rwc test- file is stored in json which ".json" will get stripped off.
|
||||
// When calling this function from compiler-runner, the baselinePath will then has either ".ts" or ".tsx" extension
|
||||
const outputFileName = ts.endsWith(baselinePath, ".ts") || ts.endsWith(baselinePath, ".tsx") ?
|
||||
baselinePath.replace(/\.tsx?/, fullExtension) : baselinePath.concat(fullExtension);
|
||||
Harness.Baseline.runBaseline(outputFileName, () => fullBaseLine, opts);
|
||||
}
|
||||
|
||||
function generateBaseLine(typeWriterResults: ts.Map<TypeWriterResult[]>, isSymbolBaseline: boolean): string {
|
||||
const typeLines: string[] = [];
|
||||
const typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {};
|
||||
|
||||
allFiles.forEach(file => {
|
||||
const codeLines = file.content.split("\n");
|
||||
typeWriterResults[file.unitName].forEach(result => {
|
||||
if (isSymbolBaseline && !result.symbol) {
|
||||
return;
|
||||
}
|
||||
|
||||
const typeOrSymbolString = isSymbolBaseline ? result.symbol : result.type;
|
||||
const formattedLine = result.sourceText.replace(/\r?\n/g, "") + " : " + typeOrSymbolString;
|
||||
if (!typeMap[file.unitName]) {
|
||||
typeMap[file.unitName] = {};
|
||||
}
|
||||
|
||||
let typeInfo = [formattedLine];
|
||||
const existingTypeInfo = typeMap[file.unitName][result.line];
|
||||
if (existingTypeInfo) {
|
||||
typeInfo = existingTypeInfo.concat(typeInfo);
|
||||
}
|
||||
typeMap[file.unitName][result.line] = typeInfo;
|
||||
});
|
||||
|
||||
typeLines.push("=== " + file.unitName + " ===\r\n");
|
||||
for (let i = 0; i < codeLines.length; i++) {
|
||||
const currentCodeLine = codeLines[i];
|
||||
typeLines.push(currentCodeLine + "\r\n");
|
||||
if (typeMap[file.unitName]) {
|
||||
const typeInfo = typeMap[file.unitName][i];
|
||||
if (typeInfo) {
|
||||
typeInfo.forEach(ty => {
|
||||
typeLines.push(">" + ty + "\r\n");
|
||||
});
|
||||
if (i + 1 < codeLines.length && (codeLines[i + 1].match(/^\s*[{|}]\s*$/) || codeLines[i + 1].trim() === "")) {
|
||||
}
|
||||
else {
|
||||
typeLines.push("\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
typeLines.push("No type information for this code.");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return typeLines.join("");
|
||||
}
|
||||
}
|
||||
|
||||
function getByteOrderMarkText(file: Harness.Compiler.GeneratedFile): string {
|
||||
return file.writeByteOrderMark ? "\u00EF\u00BB\u00BF" : "";
|
||||
}
|
||||
|
||||
export function doSourcemapBaseline(baselinePath: string, options: ts.CompilerOptions, result: CompilerResult) {
|
||||
if (options.inlineSourceMap) {
|
||||
if (result.sourceMaps.length > 0) {
|
||||
throw new Error("No sourcemap files should be generated if inlineSourceMaps was set.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (options.sourceMap) {
|
||||
if (result.sourceMaps.length !== result.files.length) {
|
||||
throw new Error("Number of sourcemap files should be same as js files.");
|
||||
}
|
||||
|
||||
Harness.Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ".js.map"), () => {
|
||||
if (options.noEmitOnError && result.errors.length !== 0 && result.sourceMaps.length === 0) {
|
||||
// We need to return null here or the runBaseLine will actually create a empty file.
|
||||
// Baselining isn't required here because there is no output.
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
|
||||
let sourceMapCode = "";
|
||||
for (let i = 0; i < result.sourceMaps.length; i++) {
|
||||
sourceMapCode += "//// [" + Harness.Path.getFileName(result.sourceMaps[i].fileName) + "]\r\n";
|
||||
sourceMapCode += getByteOrderMarkText(result.sourceMaps[i]);
|
||||
sourceMapCode += result.sourceMaps[i].code;
|
||||
}
|
||||
|
||||
return sourceMapCode;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function doJsEmitBaseline(baselinePath: string, header: string, options: ts.CompilerOptions, result: CompilerResult, toBeCompiled: Harness.Compiler.TestFile[], otherFiles: Harness.Compiler.TestFile[], harnessSettings: Harness.TestCaseParser.CompilerSettings) {
|
||||
if (!options.noEmit && result.files.length === 0 && result.errors.length === 0) {
|
||||
throw new Error("Expected at least one js file to be emitted or at least one error to be created.");
|
||||
}
|
||||
|
||||
// check js output
|
||||
Harness.Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ".js"), () => {
|
||||
let tsCode = "";
|
||||
const tsSources = otherFiles.concat(toBeCompiled);
|
||||
if (tsSources.length > 1) {
|
||||
tsCode += "//// [" + header + "] ////\r\n\r\n";
|
||||
}
|
||||
for (let i = 0; i < tsSources.length; i++) {
|
||||
tsCode += "//// [" + Harness.Path.getFileName(tsSources[i].unitName) + "]\r\n";
|
||||
tsCode += tsSources[i].content + (i < (tsSources.length - 1) ? "\r\n" : "");
|
||||
}
|
||||
|
||||
let jsCode = "";
|
||||
for (let i = 0; i < result.files.length; i++) {
|
||||
jsCode += "//// [" + Harness.Path.getFileName(result.files[i].fileName) + "]\r\n";
|
||||
jsCode += getByteOrderMarkText(result.files[i]);
|
||||
jsCode += result.files[i].code;
|
||||
}
|
||||
|
||||
if (result.declFilesCode.length > 0) {
|
||||
jsCode += "\r\n\r\n";
|
||||
for (let i = 0; i < result.declFilesCode.length; i++) {
|
||||
jsCode += "//// [" + Harness.Path.getFileName(result.declFilesCode[i].fileName) + "]\r\n";
|
||||
jsCode += getByteOrderMarkText(result.declFilesCode[i]);
|
||||
jsCode += result.declFilesCode[i].code;
|
||||
}
|
||||
}
|
||||
|
||||
const declFileCompilationResult =
|
||||
Harness.Compiler.compileDeclarationFiles(
|
||||
toBeCompiled, otherFiles, result, harnessSettings, options, /*currentDirectory*/ undefined);
|
||||
|
||||
if (declFileCompilationResult && declFileCompilationResult.declResult.errors.length) {
|
||||
jsCode += "\r\n\r\n//// [DtsFileErrors]\r\n";
|
||||
jsCode += "\r\n\r\n";
|
||||
jsCode += Harness.Compiler.getErrorBaseline(declFileCompilationResult.declInputFiles.concat(declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors);
|
||||
}
|
||||
|
||||
if (jsCode.length > 0) {
|
||||
return tsCode + "\r\n\r\n" + jsCode;
|
||||
}
|
||||
else {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function collateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): string {
|
||||
// Collect, test, and sort the fileNames
|
||||
outputFiles.sort((a, b) => cleanName(a.fileName).localeCompare(cleanName(b.fileName)));
|
||||
@ -1558,7 +1785,7 @@ namespace Harness {
|
||||
tsConfig.options.configFilePath = data.name;
|
||||
|
||||
// delete entry from the list
|
||||
testUnitData.splice(i, 1);
|
||||
ts.orderedRemoveItemAt(testUnitData, i);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1604,31 +1831,7 @@ namespace Harness {
|
||||
}
|
||||
|
||||
const fileCache: { [idx: string]: boolean } = {};
|
||||
function generateActual(actualFileName: string, generateContent: () => string): string {
|
||||
// For now this is written using TypeScript, because sys is not available when running old test cases.
|
||||
// But we need to move to sys once we have
|
||||
// Creates the directory including its parent if not already present
|
||||
function createDirectoryStructure(dirName: string) {
|
||||
if (fileCache[dirName] || IO.directoryExists(dirName)) {
|
||||
fileCache[dirName] = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const parentDirectory = IO.directoryName(dirName);
|
||||
if (parentDirectory != "") {
|
||||
createDirectoryStructure(parentDirectory);
|
||||
}
|
||||
IO.createDirectory(dirName);
|
||||
fileCache[dirName] = true;
|
||||
}
|
||||
|
||||
// Create folders if needed
|
||||
createDirectoryStructure(Harness.IO.directoryName(actualFileName));
|
||||
|
||||
// Delete the actual file in case it fails
|
||||
if (IO.fileExists(actualFileName)) {
|
||||
IO.deleteFile(actualFileName);
|
||||
}
|
||||
function generateActual(generateContent: () => string): string {
|
||||
|
||||
const actual = generateContent();
|
||||
|
||||
@ -1663,43 +1866,51 @@ namespace Harness {
|
||||
return { expected, actual };
|
||||
}
|
||||
|
||||
function writeComparison(expected: string, actual: string, relativeFileName: string, actualFileName: string, descriptionForDescribe: string) {
|
||||
function writeComparison(expected: string, actual: string, relativeFileName: string, actualFileName: string) {
|
||||
// For now this is written using TypeScript, because sys is not available when running old test cases.
|
||||
// But we need to move to sys once we have
|
||||
// Creates the directory including its parent if not already present
|
||||
function createDirectoryStructure(dirName: string) {
|
||||
if (fileCache[dirName] || IO.directoryExists(dirName)) {
|
||||
fileCache[dirName] = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const parentDirectory = IO.directoryName(dirName);
|
||||
if (parentDirectory != "") {
|
||||
createDirectoryStructure(parentDirectory);
|
||||
}
|
||||
IO.createDirectory(dirName);
|
||||
fileCache[dirName] = true;
|
||||
}
|
||||
|
||||
// Create folders if needed
|
||||
createDirectoryStructure(Harness.IO.directoryName(actualFileName));
|
||||
|
||||
// Delete the actual file in case it fails
|
||||
if (IO.fileExists(actualFileName)) {
|
||||
IO.deleteFile(actualFileName);
|
||||
}
|
||||
|
||||
const encoded_actual = Utils.encodeString(actual);
|
||||
if (expected !== encoded_actual) {
|
||||
if (actual === NoContent) {
|
||||
IO.writeFile(localPath(relativeFileName + ".delete"), "");
|
||||
IO.writeFile(actualFileName + ".delete", "");
|
||||
}
|
||||
else {
|
||||
IO.writeFile(localPath(relativeFileName), actual);
|
||||
IO.writeFile(actualFileName, actual);
|
||||
}
|
||||
// Overwrite & issue error
|
||||
const errMsg = "The baseline file " + relativeFileName + " has changed.";
|
||||
throw new Error(errMsg);
|
||||
throw new Error(`The baseline file ${relativeFileName} has changed.`);
|
||||
}
|
||||
}
|
||||
|
||||
export function runBaseline(relativeFileName: string, generateContent: () => string, opts?: BaselineOptions): void {
|
||||
|
||||
export function runBaseline(
|
||||
descriptionForDescribe: string,
|
||||
relativeFileName: string,
|
||||
generateContent: () => string,
|
||||
runImmediately = false,
|
||||
opts?: BaselineOptions): void {
|
||||
|
||||
let actual = <string>undefined;
|
||||
const actualFileName = localPath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
||||
|
||||
if (runImmediately) {
|
||||
actual = generateActual(actualFileName, generateContent);
|
||||
const comparison = compareToBaseline(actual, relativeFileName, opts);
|
||||
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe);
|
||||
}
|
||||
else {
|
||||
actual = generateActual(actualFileName, generateContent);
|
||||
|
||||
const comparison = compareToBaseline(actual, relativeFileName, opts);
|
||||
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe);
|
||||
}
|
||||
const actual = generateActual(generateContent);
|
||||
const comparison = compareToBaseline(actual, relativeFileName, opts);
|
||||
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -459,7 +459,7 @@ class ProjectRunner extends RunnerBase {
|
||||
});
|
||||
|
||||
it("Resolution information of (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
|
||||
Harness.Baseline.runBaseline("Resolution information of (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".json", () => {
|
||||
Harness.Baseline.runBaseline(getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".json", () => {
|
||||
return JSON.stringify(getCompilerResolutionInfo(), undefined, " ");
|
||||
});
|
||||
});
|
||||
@ -467,7 +467,7 @@ class ProjectRunner extends RunnerBase {
|
||||
|
||||
it("Errors for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
|
||||
if (compilerResult.errors.length) {
|
||||
Harness.Baseline.runBaseline("Errors for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".errors.txt", () => {
|
||||
Harness.Baseline.runBaseline(getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".errors.txt", () => {
|
||||
return getErrorsBaseline(compilerResult);
|
||||
});
|
||||
}
|
||||
@ -481,7 +481,7 @@ class ProjectRunner extends RunnerBase {
|
||||
// There may be multiple files with different baselines. Run all and report at the end, else
|
||||
// it stops copying the remaining emitted files from 'local/projectOutput' to 'local/project'.
|
||||
try {
|
||||
Harness.Baseline.runBaseline("Baseline of emitted result (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + outputFile.fileName, () => {
|
||||
Harness.Baseline.runBaseline(getBaselineFolder(compilerResult.moduleKind) + outputFile.fileName, () => {
|
||||
try {
|
||||
return Harness.IO.readFile(getProjectOutputFolder(outputFile.fileName, compilerResult.moduleKind));
|
||||
}
|
||||
@ -503,7 +503,7 @@ class ProjectRunner extends RunnerBase {
|
||||
|
||||
it("SourceMapRecord for (" + moduleNameToString(moduleKind) + "): " + testCaseFileName, () => {
|
||||
if (compilerResult.sourceMapData) {
|
||||
Harness.Baseline.runBaseline("SourceMapRecord for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".sourcemap.txt", () => {
|
||||
Harness.Baseline.runBaseline(getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".sourcemap.txt", () => {
|
||||
return Harness.SourceMapRecorder.getSourceMapRecord(compilerResult.sourceMapData, compilerResult.program,
|
||||
ts.filter(compilerResult.outputFiles, outputFile => Harness.Compiler.isJS(outputFile.emittedFileName)));
|
||||
});
|
||||
@ -516,7 +516,7 @@ class ProjectRunner extends RunnerBase {
|
||||
if (!compilerResult.errors.length && testCase.declaration) {
|
||||
const dTsCompileResult = compileCompileDTsFiles(compilerResult);
|
||||
if (dTsCompileResult && dTsCompileResult.errors.length) {
|
||||
Harness.Baseline.runBaseline("Errors in generated Dts files for (" + moduleNameToString(compilerResult.moduleKind) + "): " + testCaseFileName, getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".dts.errors.txt", () => {
|
||||
Harness.Baseline.runBaseline(getBaselineFolder(compilerResult.moduleKind) + testCaseJustName + ".dts.errors.txt", () => {
|
||||
return getErrorsBaseline(dTsCompileResult);
|
||||
});
|
||||
}
|
||||
|
||||
@ -158,41 +158,41 @@ namespace RWC {
|
||||
|
||||
|
||||
it("has the expected emitted code", () => {
|
||||
Harness.Baseline.runBaseline("has the expected emitted code", baseName + ".output.js", () => {
|
||||
Harness.Baseline.runBaseline(`${baseName}.output.js`, () => {
|
||||
return Harness.Compiler.collateOutputs(compilerResult.files);
|
||||
}, false, baselineOpts);
|
||||
}, baselineOpts);
|
||||
});
|
||||
|
||||
it("has the expected declaration file content", () => {
|
||||
Harness.Baseline.runBaseline("has the expected declaration file content", baseName + ".d.ts", () => {
|
||||
Harness.Baseline.runBaseline(`${baseName}.d.ts`, () => {
|
||||
if (!compilerResult.declFilesCode.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Harness.Compiler.collateOutputs(compilerResult.declFilesCode);
|
||||
}, false, baselineOpts);
|
||||
}, baselineOpts);
|
||||
});
|
||||
|
||||
it("has the expected source maps", () => {
|
||||
Harness.Baseline.runBaseline("has the expected source maps", baseName + ".map", () => {
|
||||
Harness.Baseline.runBaseline(`${baseName}.map`, () => {
|
||||
if (!compilerResult.sourceMaps.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Harness.Compiler.collateOutputs(compilerResult.sourceMaps);
|
||||
}, false, baselineOpts);
|
||||
}, baselineOpts);
|
||||
});
|
||||
|
||||
/*it("has correct source map record", () => {
|
||||
if (compilerOptions.sourceMap) {
|
||||
Harness.Baseline.runBaseline("has correct source map record", baseName + ".sourcemap.txt", () => {
|
||||
Harness.Baseline.runBaseline(baseName + ".sourcemap.txt", () => {
|
||||
return compilerResult.getSourceMapRecord();
|
||||
}, false, baselineOpts);
|
||||
}, baselineOpts);
|
||||
}
|
||||
});*/
|
||||
|
||||
it("has the expected errors", () => {
|
||||
Harness.Baseline.runBaseline("has the expected errors", baseName + ".errors.txt", () => {
|
||||
Harness.Baseline.runBaseline(`${baseName}.errors.txt`, () => {
|
||||
if (compilerResult.errors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
@ -200,14 +200,14 @@ namespace RWC {
|
||||
const baselineFiles = inputFiles.concat(otherFiles).filter(f => !Harness.isDefaultLibraryFile(f.unitName));
|
||||
const errors = compilerResult.errors.filter(e => !Harness.isDefaultLibraryFile(e.file.fileName));
|
||||
return Harness.Compiler.getErrorBaseline(baselineFiles, errors);
|
||||
}, false, baselineOpts);
|
||||
}, baselineOpts);
|
||||
});
|
||||
|
||||
// Ideally, a generated declaration file will have no errors. But we allow generated
|
||||
// declaration file errors as part of the baseline.
|
||||
it("has the expected errors in generated declaration files", () => {
|
||||
if (compilerOptions.declaration && !compilerResult.errors.length) {
|
||||
Harness.Baseline.runBaseline("has the expected errors in generated declaration files", baseName + ".dts.errors.txt", () => {
|
||||
Harness.Baseline.runBaseline(`${baseName}.dts.errors.txt`, () => {
|
||||
const declFileCompilationResult = Harness.Compiler.compileDeclarationFiles(
|
||||
inputFiles, otherFiles, compilerResult, /*harnessSettings*/ undefined, compilerOptions, currentDirectory);
|
||||
|
||||
@ -218,11 +218,17 @@ namespace RWC {
|
||||
return Harness.Compiler.minimalDiagnosticsToString(declFileCompilationResult.declResult.errors) +
|
||||
Harness.IO.newLine() + Harness.IO.newLine() +
|
||||
Harness.Compiler.getErrorBaseline(declFileCompilationResult.declInputFiles.concat(declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors);
|
||||
}, false, baselineOpts);
|
||||
}, baselineOpts);
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: Type baselines (need to refactor out from compilerRunner)
|
||||
it("has the expected types", () => {
|
||||
// We don't need to pass the extension here because "doTypeAndSymbolBaseline" will append appropriate extension of ".types" or ".symbols"
|
||||
Harness.Compiler.doTypeAndSymbolBaseline(baseName, compilerResult, inputFiles
|
||||
.concat(otherFiles)
|
||||
.filter(file => !!compilerResult.program.getSourceFile(file.unitName))
|
||||
.filter(e => !Harness.isDefaultLibraryFile(e.unitName)), baselineOpts);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,21 +67,21 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
});
|
||||
|
||||
it("has the expected emitted code", () => {
|
||||
Harness.Baseline.runBaseline("has the expected emitted code", testState.filename + ".output.js", () => {
|
||||
Harness.Baseline.runBaseline(testState.filename + ".output.js", () => {
|
||||
const files = testState.compilerResult.files.filter(f => f.fileName !== Test262BaselineRunner.helpersFilePath);
|
||||
return Harness.Compiler.collateOutputs(files);
|
||||
}, false, Test262BaselineRunner.baselineOptions);
|
||||
}, Test262BaselineRunner.baselineOptions);
|
||||
});
|
||||
|
||||
it("has the expected errors", () => {
|
||||
Harness.Baseline.runBaseline("has the expected errors", testState.filename + ".errors.txt", () => {
|
||||
Harness.Baseline.runBaseline(testState.filename + ".errors.txt", () => {
|
||||
const errors = testState.compilerResult.errors;
|
||||
if (errors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Harness.Compiler.getErrorBaseline(testState.inputFiles, errors);
|
||||
}, false, Test262BaselineRunner.baselineOptions);
|
||||
}, Test262BaselineRunner.baselineOptions);
|
||||
});
|
||||
|
||||
it("satisfies invariants", () => {
|
||||
@ -90,10 +90,10 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
});
|
||||
|
||||
it("has the expected AST", () => {
|
||||
Harness.Baseline.runBaseline("has the expected AST", testState.filename + ".AST.txt", () => {
|
||||
Harness.Baseline.runBaseline(testState.filename + ".AST.txt", () => {
|
||||
const sourceFile = testState.compilerResult.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
||||
return Utils.sourceFileToJSON(sourceFile);
|
||||
}, false, Test262BaselineRunner.baselineOptions);
|
||||
}, Test262BaselineRunner.baselineOptions);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -403,6 +403,7 @@ namespace ts {
|
||||
{
|
||||
compilerOptions: <CompilerOptions>{
|
||||
allowJs: true,
|
||||
maxNodeModuleJsDepth: 2,
|
||||
module: ModuleKind.CommonJS,
|
||||
target: ScriptTarget.ES5,
|
||||
noImplicitAny: false,
|
||||
@ -429,6 +430,7 @@ namespace ts {
|
||||
{
|
||||
compilerOptions: <CompilerOptions>{
|
||||
allowJs: false,
|
||||
maxNodeModuleJsDepth: 2,
|
||||
module: ModuleKind.CommonJS,
|
||||
target: ScriptTarget.ES5,
|
||||
noImplicitAny: false,
|
||||
@ -450,7 +452,8 @@ namespace ts {
|
||||
{
|
||||
compilerOptions:
|
||||
{
|
||||
allowJs: true
|
||||
allowJs: true,
|
||||
maxNodeModuleJsDepth: 2
|
||||
},
|
||||
errors: [{
|
||||
file: undefined,
|
||||
@ -469,7 +472,8 @@ namespace ts {
|
||||
{
|
||||
compilerOptions:
|
||||
{
|
||||
allowJs: true
|
||||
allowJs: true,
|
||||
maxNodeModuleJsDepth: 2
|
||||
},
|
||||
errors: <Diagnostic[]>[]
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ namespace ts {
|
||||
const outputFileName = `tsConfig/${name.replace(/[^a-z0-9\-. ]/ig, "")}/tsconfig.json`;
|
||||
|
||||
it(`Correct output for ${outputFileName}`, () => {
|
||||
Harness.Baseline.runBaseline("Correct output", outputFileName, () => {
|
||||
Harness.Baseline.runBaseline(outputFileName, () => {
|
||||
if (initResult) {
|
||||
return JSON.stringify(initResult, undefined, 4);
|
||||
}
|
||||
|
||||
@ -767,16 +767,9 @@ namespace ts {
|
||||
parsesCorrectly(
|
||||
"{null}",
|
||||
`{
|
||||
"kind": "JSDocTypeReference",
|
||||
"kind": "NullKeyword",
|
||||
"pos": 1,
|
||||
"end": 5,
|
||||
"name": {
|
||||
"kind": "Identifier",
|
||||
"pos": 1,
|
||||
"end": 5,
|
||||
"originalKeywordKind": "NullKeyword",
|
||||
"text": "null"
|
||||
}
|
||||
"end": 5
|
||||
}`);
|
||||
});
|
||||
|
||||
@ -784,16 +777,9 @@ namespace ts {
|
||||
parsesCorrectly(
|
||||
"{undefined}",
|
||||
`{
|
||||
"kind": "JSDocTypeReference",
|
||||
"kind": "UndefinedKeyword",
|
||||
"pos": 1,
|
||||
"end": 10,
|
||||
"name": {
|
||||
"kind": "Identifier",
|
||||
"pos": 1,
|
||||
"end": 10,
|
||||
"originalKeywordKind": "UndefinedKeyword",
|
||||
"text": "undefined"
|
||||
}
|
||||
"end": 10
|
||||
}`);
|
||||
});
|
||||
|
||||
@ -2379,4 +2365,4 @@ namespace ts {
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,79 +0,0 @@
|
||||
class a {
|
||||
constructor ( n : number ) ;
|
||||
constructor ( s : string ) ;
|
||||
constructor ( ns : any ) {
|
||||
|
||||
}
|
||||
|
||||
public pgF ( ) { } ;
|
||||
|
||||
public pv ;
|
||||
public get d ( ) {
|
||||
return 30 ;
|
||||
}
|
||||
public set d ( ) {
|
||||
}
|
||||
|
||||
public static get p2 ( ) {
|
||||
return { x : 30 , y : 40 } ;
|
||||
}
|
||||
|
||||
private static d2 ( ) {
|
||||
}
|
||||
private static get p3 ( ) {
|
||||
return "string" ;
|
||||
}
|
||||
private pv3 ;
|
||||
|
||||
private foo ( n : number ) : string ;
|
||||
private foo ( s : string ) : string ;
|
||||
private foo ( ns : any ) {
|
||||
return ns.toString ( ) ;
|
||||
}
|
||||
}
|
||||
|
||||
class b extends a {
|
||||
}
|
||||
|
||||
class m1b {
|
||||
|
||||
}
|
||||
|
||||
interface m1ib {
|
||||
|
||||
}
|
||||
class c extends m1b {
|
||||
}
|
||||
|
||||
class ib2 implements m1ib {
|
||||
}
|
||||
|
||||
declare class aAmbient {
|
||||
constructor ( n : number ) ;
|
||||
constructor ( s : string ) ;
|
||||
public pgF ( ) : void ;
|
||||
public pv ;
|
||||
public d : number ;
|
||||
static p2 : { x : number ; y : number ; } ;
|
||||
static d2 ( ) ;
|
||||
static p3 ;
|
||||
private pv3 ;
|
||||
private foo ( s ) ;
|
||||
}
|
||||
|
||||
class d {
|
||||
private foo ( n : number ) : string ;
|
||||
private foo ( ns : any ) {
|
||||
return ns.toString ( ) ;
|
||||
}
|
||||
private foo ( s : string ) : string ;
|
||||
}
|
||||
|
||||
class e {
|
||||
private foo ( ns : any ) {
|
||||
return ns.toString ( ) ;
|
||||
}
|
||||
private foo ( s : string ) : string ;
|
||||
private foo ( n : number ) : string ;
|
||||
}
|
||||
|
||||
@ -1,79 +0,0 @@
|
||||
class a {
|
||||
constructor(n: number);
|
||||
constructor(s: string);
|
||||
constructor(ns: any) {
|
||||
|
||||
}
|
||||
|
||||
public pgF() { };
|
||||
|
||||
public pv;
|
||||
public get d() {
|
||||
return 30;
|
||||
}
|
||||
public set d() {
|
||||
}
|
||||
|
||||
public static get p2() {
|
||||
return { x: 30, y: 40 };
|
||||
}
|
||||
|
||||
private static d2() {
|
||||
}
|
||||
private static get p3() {
|
||||
return "string";
|
||||
}
|
||||
private pv3;
|
||||
|
||||
private foo(n: number): string;
|
||||
private foo(s: string): string;
|
||||
private foo(ns: any) {
|
||||
return ns.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class b extends a {
|
||||
}
|
||||
|
||||
class m1b {
|
||||
|
||||
}
|
||||
|
||||
interface m1ib {
|
||||
|
||||
}
|
||||
class c extends m1b {
|
||||
}
|
||||
|
||||
class ib2 implements m1ib {
|
||||
}
|
||||
|
||||
declare class aAmbient {
|
||||
constructor(n: number);
|
||||
constructor(s: string);
|
||||
public pgF(): void;
|
||||
public pv;
|
||||
public d: number;
|
||||
static p2: { x: number; y: number; };
|
||||
static d2();
|
||||
static p3;
|
||||
private pv3;
|
||||
private foo(s);
|
||||
}
|
||||
|
||||
class d {
|
||||
private foo(n: number): string;
|
||||
private foo(ns: any) {
|
||||
return ns.toString();
|
||||
}
|
||||
private foo(s: string): string;
|
||||
}
|
||||
|
||||
class e {
|
||||
private foo(ns: any) {
|
||||
return ns.toString();
|
||||
}
|
||||
private foo(s: string): string;
|
||||
private foo(n: number): string;
|
||||
}
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
class foo {
|
||||
constructor (n?: number, m? = 5, o?: string = "") { }
|
||||
x:number = 1?2:3;
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
class foo {
|
||||
constructor(n?: number, m? = 5, o?: string = "") { }
|
||||
x: number = 1 ? 2 : 3;
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
$ ( document ) . ready ( function ( ) {
|
||||
alert ( 'i am ready' ) ;
|
||||
} );
|
||||
@ -1,3 +0,0 @@
|
||||
$(document).ready(function() {
|
||||
alert('i am ready');
|
||||
});
|
||||
@ -1 +0,0 @@
|
||||
{}
|
||||
@ -1 +0,0 @@
|
||||
{ }
|
||||
@ -1,10 +0,0 @@
|
||||
function foo ( x : { } ) { }
|
||||
|
||||
foo ( { } ) ;
|
||||
|
||||
|
||||
|
||||
interface bar {
|
||||
x : { } ;
|
||||
y : ( ) => { } ;
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
function foo(x: {}) { }
|
||||
|
||||
foo({});
|
||||
|
||||
|
||||
|
||||
interface bar {
|
||||
x: {};
|
||||
y: () => {};
|
||||
}
|
||||
@ -1,112 +0,0 @@
|
||||
// valid
|
||||
( ) => 1 ;
|
||||
( arg ) => 2 ;
|
||||
arg => 2 ;
|
||||
( arg = 1 ) => 3 ;
|
||||
( arg ? ) => 4 ;
|
||||
( arg : number ) => 5 ;
|
||||
( arg : number = 0 ) => 6 ;
|
||||
( arg ? : number ) => 7 ;
|
||||
( ... arg : number [ ] ) => 8 ;
|
||||
( arg1 , arg2 ) => 12 ;
|
||||
( arg1 = 1 , arg2 =3 ) => 13 ;
|
||||
( arg1 ? , arg2 ? ) => 14 ;
|
||||
( arg1 : number , arg2 : number ) => 15 ;
|
||||
( arg1 : number = 0 , arg2 : number = 1 ) => 16 ;
|
||||
( arg1 ? : number , arg2 ? : number ) => 17 ;
|
||||
( arg1 , ... arg2 : number [ ] ) => 18 ;
|
||||
( arg1 , arg2 ? : number ) => 19 ;
|
||||
|
||||
// in paren
|
||||
( ( ) => 21 ) ;
|
||||
( ( arg ) => 22 ) ;
|
||||
( ( arg = 1 ) => 23 ) ;
|
||||
( ( arg ? ) => 24 ) ;
|
||||
( ( arg : number ) => 25 ) ;
|
||||
( ( arg : number = 0 ) => 26 ) ;
|
||||
( ( arg ? : number ) => 27 ) ;
|
||||
( ( ... arg : number [ ] ) => 28 ) ;
|
||||
|
||||
// in multiple paren
|
||||
( ( ( ( ( arg ) => { return 32 ; } ) ) ) ) ;
|
||||
|
||||
// in ternary exression
|
||||
false ? ( ) => 41 : null ;
|
||||
false ? ( arg ) => 42 : null ;
|
||||
false ? ( arg = 1 ) => 43 : null ;
|
||||
false ? ( arg ? ) => 44 : null ;
|
||||
false ? ( arg : number ) => 45 : null ;
|
||||
false ? ( arg ? : number ) => 46 : null ;
|
||||
false ? ( arg ? : number = 0 ) => 47 : null ;
|
||||
false ? ( ... arg : number [ ] ) => 48 : null ;
|
||||
|
||||
// in ternary exression within paren
|
||||
false ? ( ( ) => 51 ) : null ;
|
||||
false ? ( ( arg ) => 52 ) : null ;
|
||||
false ? ( ( arg = 1 ) => 53 ) : null ;
|
||||
false ? ( ( arg ? ) => 54 ) : null ;
|
||||
false ? ( ( arg : number ) => 55 ) : null ;
|
||||
false ? ( ( arg ? : number ) => 56 ) : null ;
|
||||
false ? ( ( arg ? : number = 0 ) => 57 ) : null ;
|
||||
false ? ( ( ... arg : number [ ] ) => 58 ) : null ;
|
||||
|
||||
// ternary exression's else clause
|
||||
false ? null : ( ) => 61 ;
|
||||
false ? null : ( arg ) => 62 ;
|
||||
false ? null : ( arg = 1 ) => 63 ;
|
||||
false ? null : ( arg ? ) => 64 ;
|
||||
false ? null : ( arg : number ) => 65 ;
|
||||
false ? null : ( arg ? : number ) => 66 ;
|
||||
false ? null : ( arg ? : number = 0 ) => 67 ;
|
||||
false ? null : ( ... arg : number [ ] ) => 68 ;
|
||||
|
||||
|
||||
// nested ternary expressions
|
||||
( a ? ) => { return a ; } ? ( b ? ) => { return b ; } : ( c ? ) => { return c ; } ;
|
||||
|
||||
//multiple levels
|
||||
( a ? ) => { return a ; } ? ( b ) => ( c ) => 81 : ( c ) => ( d ) => 82 ;
|
||||
|
||||
|
||||
// In Expressions
|
||||
( ( arg ) => 90 ) instanceof Function ;
|
||||
( ( arg = 1 ) => 91 ) instanceof Function ;
|
||||
( ( arg ? ) => 92 ) instanceof Function ;
|
||||
( ( arg : number ) => 93 ) instanceof Function ;
|
||||
( ( arg : number = 1 ) => 94 ) instanceof Function ;
|
||||
( ( arg ? : number ) => 95 ) instanceof Function ;
|
||||
( ( ... arg : number [ ] ) => 96 ) instanceof Function ;
|
||||
|
||||
'' + ( arg ) => 100 ;
|
||||
( ( arg ) => 0 ) + '' + ( arg ) => 101 ;
|
||||
( ( arg = 1 ) => 0 ) + '' + ( arg = 2 ) => 102 ;
|
||||
( ( arg ? ) => 0 ) + '' + ( arg ? ) => 103 ;
|
||||
( ( arg : number ) => 0 ) + '' + ( arg : number ) => 104 ;
|
||||
( ( arg : number = 1 ) => 0 ) + '' + ( arg : number = 2 ) => 105 ;
|
||||
( ( arg ? : number = 1 ) => 0 ) + '' + ( arg ? : number = 2 ) => 106 ;
|
||||
( ( ... arg : number [ ] ) => 0 ) + '' + ( ... arg : number [ ] ) => 107 ;
|
||||
( ( arg1 , arg2 ? ) => 0 ) + '' + ( arg1 , arg2 ? ) => 108 ;
|
||||
( ( arg1 , ... arg2 : number [ ] ) => 0 ) + '' + ( arg1 , ... arg2 : number [ ] ) => 108 ;
|
||||
|
||||
|
||||
// Function Parameters
|
||||
function foo ( ... arg : any [ ] ) { }
|
||||
|
||||
foo (
|
||||
( a ) => 110 ,
|
||||
( ( a ) => 111 ) ,
|
||||
( a ) => {
|
||||
return 112 ;
|
||||
} ,
|
||||
( a ? ) => 113 ,
|
||||
( a , b ? ) => 114 ,
|
||||
( a : number ) => 115 ,
|
||||
( a : number = 0 ) => 116 ,
|
||||
( a = 0 ) => 117 ,
|
||||
( a ? : number = 0 ) => 118 ,
|
||||
( a ? , b ? : number = 0 ) => 118 ,
|
||||
( ... a : number [ ] ) => 119 ,
|
||||
( a , b ? = 0 , ... c : number [ ] ) => 120 ,
|
||||
( a ) => ( b ) => ( c ) => 121 ,
|
||||
false ? ( a ) => 0 : ( b ) => 122
|
||||
) ;
|
||||
@ -1,112 +0,0 @@
|
||||
// valid
|
||||
() => 1;
|
||||
(arg) => 2;
|
||||
arg => 2;
|
||||
(arg = 1) => 3;
|
||||
(arg?) => 4;
|
||||
(arg: number) => 5;
|
||||
(arg: number = 0) => 6;
|
||||
(arg?: number) => 7;
|
||||
(...arg: number[]) => 8;
|
||||
(arg1, arg2) => 12;
|
||||
(arg1 = 1, arg2 = 3) => 13;
|
||||
(arg1?, arg2?) => 14;
|
||||
(arg1: number, arg2: number) => 15;
|
||||
(arg1: number = 0, arg2: number = 1) => 16;
|
||||
(arg1?: number, arg2?: number) => 17;
|
||||
(arg1, ...arg2: number[]) => 18;
|
||||
(arg1, arg2?: number) => 19;
|
||||
|
||||
// in paren
|
||||
(() => 21);
|
||||
((arg) => 22);
|
||||
((arg = 1) => 23);
|
||||
((arg?) => 24);
|
||||
((arg: number) => 25);
|
||||
((arg: number = 0) => 26);
|
||||
((arg?: number) => 27);
|
||||
((...arg: number[]) => 28);
|
||||
|
||||
// in multiple paren
|
||||
(((((arg) => { return 32; }))));
|
||||
|
||||
// in ternary exression
|
||||
false ? () => 41 : null;
|
||||
false ? (arg) => 42 : null;
|
||||
false ? (arg = 1) => 43 : null;
|
||||
false ? (arg?) => 44 : null;
|
||||
false ? (arg: number) => 45 : null;
|
||||
false ? (arg?: number) => 46 : null;
|
||||
false ? (arg?: number = 0) => 47 : null;
|
||||
false ? (...arg: number[]) => 48 : null;
|
||||
|
||||
// in ternary exression within paren
|
||||
false ? (() => 51) : null;
|
||||
false ? ((arg) => 52) : null;
|
||||
false ? ((arg = 1) => 53) : null;
|
||||
false ? ((arg?) => 54) : null;
|
||||
false ? ((arg: number) => 55) : null;
|
||||
false ? ((arg?: number) => 56) : null;
|
||||
false ? ((arg?: number = 0) => 57) : null;
|
||||
false ? ((...arg: number[]) => 58) : null;
|
||||
|
||||
// ternary exression's else clause
|
||||
false ? null : () => 61;
|
||||
false ? null : (arg) => 62;
|
||||
false ? null : (arg = 1) => 63;
|
||||
false ? null : (arg?) => 64;
|
||||
false ? null : (arg: number) => 65;
|
||||
false ? null : (arg?: number) => 66;
|
||||
false ? null : (arg?: number = 0) => 67;
|
||||
false ? null : (...arg: number[]) => 68;
|
||||
|
||||
|
||||
// nested ternary expressions
|
||||
(a?) => { return a; } ? (b?) => { return b; } : (c?) => { return c; };
|
||||
|
||||
//multiple levels
|
||||
(a?) => { return a; } ? (b) => (c) => 81 : (c) => (d) => 82;
|
||||
|
||||
|
||||
// In Expressions
|
||||
((arg) => 90) instanceof Function;
|
||||
((arg = 1) => 91) instanceof Function;
|
||||
((arg?) => 92) instanceof Function;
|
||||
((arg: number) => 93) instanceof Function;
|
||||
((arg: number = 1) => 94) instanceof Function;
|
||||
((arg?: number) => 95) instanceof Function;
|
||||
((...arg: number[]) => 96) instanceof Function;
|
||||
|
||||
'' + (arg) => 100;
|
||||
((arg) => 0) + '' + (arg) => 101;
|
||||
((arg = 1) => 0) + '' + (arg = 2) => 102;
|
||||
((arg?) => 0) + '' + (arg?) => 103;
|
||||
((arg: number) => 0) + '' + (arg: number) => 104;
|
||||
((arg: number = 1) => 0) + '' + (arg: number = 2) => 105;
|
||||
((arg?: number = 1) => 0) + '' + (arg?: number = 2) => 106;
|
||||
((...arg: number[]) => 0) + '' + (...arg: number[]) => 107;
|
||||
((arg1, arg2?) => 0) + '' + (arg1, arg2?) => 108;
|
||||
((arg1, ...arg2: number[]) => 0) + '' + (arg1, ...arg2: number[]) => 108;
|
||||
|
||||
|
||||
// Function Parameters
|
||||
function foo(...arg: any[]) { }
|
||||
|
||||
foo(
|
||||
(a) => 110,
|
||||
((a) => 111),
|
||||
(a) => {
|
||||
return 112;
|
||||
},
|
||||
(a?) => 113,
|
||||
(a, b?) => 114,
|
||||
(a: number) => 115,
|
||||
(a: number = 0) => 116,
|
||||
(a = 0) => 117,
|
||||
(a?: number = 0) => 118,
|
||||
(a?, b?: number = 0) => 118,
|
||||
(...a: number[]) => 119,
|
||||
(a, b? = 0, ...c: number[]) => 120,
|
||||
(a) => (b) => (c) => 121,
|
||||
false ? (a) => 0 : (b) => 122
|
||||
);
|
||||
@ -1,2 +0,0 @@
|
||||
if(false){debugger;}
|
||||
if ( false ) { debugger ; }
|
||||
@ -1,2 +0,0 @@
|
||||
if (false) { debugger; }
|
||||
if (false) { debugger; }
|
||||
@ -1,13 +0,0 @@
|
||||
var fun1 = function ( ) {
|
||||
var x = 'foo' ,
|
||||
z = 'bar' ;
|
||||
return x ;
|
||||
},
|
||||
|
||||
fun2 = ( function ( f ) {
|
||||
var fun = function ( ) {
|
||||
console . log ( f ( ) ) ;
|
||||
},
|
||||
x = 'Foo' ;
|
||||
return fun ;
|
||||
} ( fun1 ) ) ;
|
||||
@ -1,13 +0,0 @@
|
||||
var fun1 = function() {
|
||||
var x = 'foo',
|
||||
z = 'bar';
|
||||
return x;
|
||||
},
|
||||
|
||||
fun2 = (function(f) {
|
||||
var fun = function() {
|
||||
console.log(f());
|
||||
},
|
||||
x = 'Foo';
|
||||
return fun;
|
||||
} (fun1));
|
||||
@ -1,3 +0,0 @@
|
||||
export class A {
|
||||
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
export class A {
|
||||
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
module Foo {
|
||||
}
|
||||
|
||||
import bar = Foo;
|
||||
|
||||
import bar2=Foo;
|
||||
@ -1,6 +0,0 @@
|
||||
module Foo {
|
||||
}
|
||||
|
||||
import bar = Foo;
|
||||
|
||||
import bar2 = Foo;
|
||||
@ -1,95 +0,0 @@
|
||||
|
||||
var a;var c , b;var $d
|
||||
var $e
|
||||
var f
|
||||
a++;b++;
|
||||
|
||||
function f ( ) {
|
||||
for (i = 0; i < 10; i++) {
|
||||
k = abc + 123 ^ d;
|
||||
a = XYZ[m (a[b[c][d]])];
|
||||
break;
|
||||
|
||||
switch ( variable){
|
||||
case 1: abc += 425;
|
||||
break;
|
||||
case 404 : a [x--/2]%=3 ;
|
||||
break ;
|
||||
case vari : v[--x ] *=++y*( m + n / k[z]);
|
||||
for (a in b){
|
||||
for (a = 0; a < 10; ++a) {
|
||||
a++;--a;
|
||||
if (a == b) {
|
||||
a++;b--;
|
||||
}
|
||||
else
|
||||
if (a == c){
|
||||
++a;
|
||||
(--c)+=d;
|
||||
$c = $a + --$b;
|
||||
}
|
||||
if (a == b)
|
||||
if (a != b) {
|
||||
if (a !== b)
|
||||
if (a === b)
|
||||
--a;
|
||||
else
|
||||
--a;
|
||||
else {
|
||||
a--;++b;
|
||||
a++
|
||||
}
|
||||
}
|
||||
}
|
||||
for (x in y) {
|
||||
m-=m;
|
||||
k=1+2+3+4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
var a ={b:function(){}};
|
||||
return {a:1,b:2}
|
||||
}
|
||||
|
||||
var z = 1;
|
||||
for (i = 0; i < 10; i++)
|
||||
for (j = 0; j < 10; j++)
|
||||
for (k = 0; k < 10; ++k) {
|
||||
z++;
|
||||
}
|
||||
|
||||
for (k = 0; k < 10; k += 2) {
|
||||
z++;
|
||||
}
|
||||
|
||||
$(document).ready ();
|
||||
|
||||
|
||||
function pageLoad() {
|
||||
$('#TextBox1' ) . unbind ( ) ;
|
||||
$('#TextBox1' ) . datepicker ( ) ;
|
||||
}
|
||||
|
||||
function pageLoad ( ) {
|
||||
var webclass=[
|
||||
{ 'student' :
|
||||
{ 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }
|
||||
} ,
|
||||
{ 'student':
|
||||
{'id':'2','name':'Adam Davidson','legacySkill':'Cobol,MainFrame'}
|
||||
} ,
|
||||
{ 'student':
|
||||
{ 'id':'3','name':'Charles Boyer' ,'legacySkill':'HTML, XML'}
|
||||
}
|
||||
];
|
||||
|
||||
$create(Sys.UI.DataView,{data:webclass},null,null,$get('SList'));
|
||||
|
||||
}
|
||||
|
||||
$( document ).ready(function(){
|
||||
alert('hello');
|
||||
} ) ;
|
||||
@ -1,98 +0,0 @@
|
||||
|
||||
var a; var c, b; var $d
|
||||
var $e
|
||||
var f
|
||||
a++; b++;
|
||||
|
||||
function f() {
|
||||
for (i = 0; i < 10; i++) {
|
||||
k = abc + 123 ^ d;
|
||||
a = XYZ[m(a[b[c][d]])];
|
||||
break;
|
||||
|
||||
switch (variable) {
|
||||
case 1: abc += 425;
|
||||
break;
|
||||
case 404: a[x-- / 2] %= 3;
|
||||
break;
|
||||
case vari: v[--x] *= ++y * (m + n / k[z]);
|
||||
for (a in b) {
|
||||
for (a = 0; a < 10; ++a) {
|
||||
a++; --a;
|
||||
if (a == b) {
|
||||
a++; b--;
|
||||
}
|
||||
else
|
||||
if (a == c) {
|
||||
++a;
|
||||
(--c) += d;
|
||||
$c = $a + --$b;
|
||||
}
|
||||
if (a == b)
|
||||
if (a != b) {
|
||||
if (a !== b)
|
||||
if (a === b)
|
||||
--a;
|
||||
else
|
||||
--a;
|
||||
else {
|
||||
a--; ++b;
|
||||
a++
|
||||
}
|
||||
}
|
||||
}
|
||||
for (x in y) {
|
||||
m -= m;
|
||||
k = 1 + 2 + 3 + 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
var a = { b: function() { } };
|
||||
return { a: 1, b: 2 }
|
||||
}
|
||||
|
||||
var z = 1;
|
||||
for (i = 0; i < 10; i++)
|
||||
for (j = 0; j < 10; j++)
|
||||
for (k = 0; k < 10; ++k) {
|
||||
z++;
|
||||
}
|
||||
|
||||
for (k = 0; k < 10; k += 2) {
|
||||
z++;
|
||||
}
|
||||
|
||||
$(document).ready();
|
||||
|
||||
|
||||
function pageLoad() {
|
||||
$('#TextBox1').unbind();
|
||||
$('#TextBox1').datepicker();
|
||||
}
|
||||
|
||||
function pageLoad() {
|
||||
var webclass = [
|
||||
{
|
||||
'student':
|
||||
{ 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }
|
||||
},
|
||||
{
|
||||
'student':
|
||||
{ 'id': '2', 'name': 'Adam Davidson', 'legacySkill': 'Cobol,MainFrame' }
|
||||
},
|
||||
{
|
||||
'student':
|
||||
{ 'id': '3', 'name': 'Charles Boyer', 'legacySkill': 'HTML, XML' }
|
||||
}
|
||||
];
|
||||
|
||||
$create(Sys.UI.DataView, { data: webclass }, null, null, $get('SList'));
|
||||
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
alert('hello');
|
||||
});
|
||||
@ -1,3 +0,0 @@
|
||||
module Foo {
|
||||
export module A . B . C { }
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
module Foo {
|
||||
export module A.B.C { }
|
||||
}
|
||||
@ -1,76 +0,0 @@
|
||||
module mod1 {
|
||||
export class b {
|
||||
}
|
||||
class d {
|
||||
}
|
||||
|
||||
|
||||
export interface ib {
|
||||
}
|
||||
}
|
||||
|
||||
module m2 {
|
||||
|
||||
export module m3 {
|
||||
export class c extends mod1.b {
|
||||
}
|
||||
export class ib2 implements mod1.ib {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class c extends mod1.b {
|
||||
}
|
||||
|
||||
class ib2 implements mod1.ib {
|
||||
}
|
||||
|
||||
declare export module "m4" {
|
||||
export class d {
|
||||
} ;
|
||||
var x : d ;
|
||||
export function foo ( ) : d ;
|
||||
}
|
||||
|
||||
import m4 = module ( "m4" ) ;
|
||||
export var x4 = m4.x ;
|
||||
export var d4 = m4.d ;
|
||||
export var f4 = m4.foo ( ) ;
|
||||
|
||||
export module m1 {
|
||||
declare export module "m2" {
|
||||
export class d {
|
||||
} ;
|
||||
var x: d ;
|
||||
export function foo ( ) : d ;
|
||||
}
|
||||
import m2 = module ( "m2" ) ;
|
||||
import m3 = module ( "m4" ) ;
|
||||
|
||||
export var x2 = m2.x ;
|
||||
export var d2 = m2.d ;
|
||||
export var f2 = m2.foo ( ) ;
|
||||
|
||||
export var x3 = m3.x ;
|
||||
export var d3 = m3.d ;
|
||||
export var f3 = m3.foo ( ) ;
|
||||
}
|
||||
|
||||
export var x2 = m1.m2.x ;
|
||||
export var d2 = m1.m2.d ;
|
||||
export var f2 = m1.m2.foo ( ) ;
|
||||
|
||||
export var x3 = m1.m3.x ;
|
||||
export var d3 = m1.m3.d ;
|
||||
export var f3 = m1.m3.foo ( ) ;
|
||||
|
||||
export module m5 {
|
||||
export var x2 = m1.m2.x ;
|
||||
export var d2 = m1.m2.d ;
|
||||
export var f2 = m1.m2.foo ( ) ;
|
||||
|
||||
export var x3 = m1.m3.x ;
|
||||
export var d3 = m1.m3.d ;
|
||||
export var f3 = m1.m3.foo ( ) ;
|
||||
}
|
||||
|
||||
@ -1,76 +0,0 @@
|
||||
module mod1 {
|
||||
export class b {
|
||||
}
|
||||
class d {
|
||||
}
|
||||
|
||||
|
||||
export interface ib {
|
||||
}
|
||||
}
|
||||
|
||||
module m2 {
|
||||
|
||||
export module m3 {
|
||||
export class c extends mod1.b {
|
||||
}
|
||||
export class ib2 implements mod1.ib {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class c extends mod1.b {
|
||||
}
|
||||
|
||||
class ib2 implements mod1.ib {
|
||||
}
|
||||
|
||||
declare export module "m4" {
|
||||
export class d {
|
||||
};
|
||||
var x: d;
|
||||
export function foo(): d;
|
||||
}
|
||||
|
||||
import m4 = module("m4");
|
||||
export var x4 = m4.x;
|
||||
export var d4 = m4.d;
|
||||
export var f4 = m4.foo();
|
||||
|
||||
export module m1 {
|
||||
declare export module "m2" {
|
||||
export class d {
|
||||
};
|
||||
var x: d;
|
||||
export function foo(): d;
|
||||
}
|
||||
import m2 = module("m2");
|
||||
import m3 = module("m4");
|
||||
|
||||
export var x2 = m2.x;
|
||||
export var d2 = m2.d;
|
||||
export var f2 = m2.foo();
|
||||
|
||||
export var x3 = m3.x;
|
||||
export var d3 = m3.d;
|
||||
export var f3 = m3.foo();
|
||||
}
|
||||
|
||||
export var x2 = m1.m2.x;
|
||||
export var d2 = m1.m2.d;
|
||||
export var f2 = m1.m2.foo();
|
||||
|
||||
export var x3 = m1.m3.x;
|
||||
export var d3 = m1.m3.d;
|
||||
export var f3 = m1.m3.foo();
|
||||
|
||||
export module m5 {
|
||||
export var x2 = m1.m2.x;
|
||||
export var d2 = m1.m2.d;
|
||||
export var f2 = m1.m2.foo();
|
||||
|
||||
export var x3 = m1.m3.x;
|
||||
export var d3 = m1.m3.d;
|
||||
export var f3 = m1.m3.foo();
|
||||
}
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
var x = {foo: 1,
|
||||
bar: "tt",
|
||||
boo: 1 + 5};
|
||||
|
||||
var x2 = {foo: 1,
|
||||
bar: "tt",boo:1+5};
|
||||
|
||||
function Foo() {
|
||||
var typeICalc = {
|
||||
clear: {
|
||||
"()": [1, 2, 3]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rule for object literal members for the "value" of the memebr to follow the indent
|
||||
// of the member, i.e. the relative position of the value is maintained when the member
|
||||
// is indented.
|
||||
var x2 = {
|
||||
foo:
|
||||
3,
|
||||
'bar':
|
||||
{ a: 1, b : 2}
|
||||
};
|
||||
|
||||
var x={ };
|
||||
var y = {};
|
||||
@ -1,31 +0,0 @@
|
||||
var x = {
|
||||
foo: 1,
|
||||
bar: "tt",
|
||||
boo: 1 + 5
|
||||
};
|
||||
|
||||
var x2 = {
|
||||
foo: 1,
|
||||
bar: "tt", boo: 1 + 5
|
||||
};
|
||||
|
||||
function Foo() {
|
||||
var typeICalc = {
|
||||
clear: {
|
||||
"()": [1, 2, 3]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rule for object literal members for the "value" of the memebr to follow the indent
|
||||
// of the member, i.e. the relative position of the value is maintained when the member
|
||||
// is indented.
|
||||
var x2 = {
|
||||
foo:
|
||||
3,
|
||||
'bar':
|
||||
{ a: 1, b: 2 }
|
||||
};
|
||||
|
||||
var x = {};
|
||||
var y = {};
|
||||
@ -1,32 +0,0 @@
|
||||
function f( ) {
|
||||
var x = 3;
|
||||
var z = 2 ;
|
||||
a = z ++ - 2 * x ;
|
||||
for ( ; ; ) {
|
||||
a+=(g +g)*a%t;
|
||||
b -- ;
|
||||
}
|
||||
|
||||
switch ( a )
|
||||
{
|
||||
case 1 : {
|
||||
a ++ ;
|
||||
b--;
|
||||
if(a===a)
|
||||
return;
|
||||
else
|
||||
{
|
||||
for(a in b)
|
||||
if(a!=a)
|
||||
{
|
||||
for(a in b)
|
||||
{
|
||||
a++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
function f() {
|
||||
var x = 3;
|
||||
var z = 2;
|
||||
a = z++ - 2 * x;
|
||||
for (; ;) {
|
||||
a += (g + g) * a % t;
|
||||
b--;
|
||||
}
|
||||
|
||||
switch (a) {
|
||||
case 1: {
|
||||
a++;
|
||||
b--;
|
||||
if (a === a)
|
||||
return;
|
||||
else {
|
||||
for (a in b)
|
||||
if (a != a) {
|
||||
for (a in b) {
|
||||
a++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
var a=b+c^d-e*++f;
|
||||
@ -1 +0,0 @@
|
||||
var a = b + c ^ d - e * ++f;
|
||||
@ -1 +0,0 @@
|
||||
class test { constructor () { } }
|
||||
@ -1 +0,0 @@
|
||||
class test { constructor() { } }
|
||||
@ -1,10 +0,0 @@
|
||||
module Tools {
|
||||
export enum NodeType {
|
||||
Error,
|
||||
Comment,
|
||||
}
|
||||
export enum foob
|
||||
{
|
||||
Blah=1, Bleah=2
|
||||
}
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
module Tools {
|
||||
export enum NodeType {
|
||||
Error,
|
||||
Comment,
|
||||
}
|
||||
export enum foob {
|
||||
Blah = 1, Bleah = 2
|
||||
}
|
||||
}
|
||||
@ -1,65 +0,0 @@
|
||||
module MyModule
|
||||
{
|
||||
module A.B.C {
|
||||
module F {
|
||||
}
|
||||
}
|
||||
interface Blah
|
||||
{
|
||||
boo: string;
|
||||
}
|
||||
|
||||
class Foo
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
class Foo2 {
|
||||
public foo():number {
|
||||
return 5 * 6;
|
||||
}
|
||||
public foo2() {
|
||||
if (1 === 2)
|
||||
|
||||
|
||||
{
|
||||
var y : number= 76;
|
||||
return y;
|
||||
}
|
||||
|
||||
while (2 == 3) {
|
||||
if ( y == null ) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public foo3() {
|
||||
if (1 === 2)
|
||||
|
||||
//comment preventing line merging
|
||||
{
|
||||
var y = 76;
|
||||
return y;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function foo(a:number, b:number):number
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
function bar(a:number, b:number) :number[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
module BugFix3 {
|
||||
declare var f: {
|
||||
(): any;
|
||||
(x: number): string;
|
||||
foo: number;
|
||||
};
|
||||
}
|
||||
@ -1,58 +0,0 @@
|
||||
module MyModule {
|
||||
module A.B.C {
|
||||
module F {
|
||||
}
|
||||
}
|
||||
interface Blah {
|
||||
boo: string;
|
||||
}
|
||||
|
||||
class Foo {
|
||||
|
||||
}
|
||||
|
||||
class Foo2 {
|
||||
public foo(): number {
|
||||
return 5 * 6;
|
||||
}
|
||||
public foo2() {
|
||||
if (1 === 2) {
|
||||
var y: number = 76;
|
||||
return y;
|
||||
}
|
||||
|
||||
while (2 == 3) {
|
||||
if (y == null) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public foo3() {
|
||||
if (1 === 2)
|
||||
|
||||
//comment preventing line merging
|
||||
{
|
||||
var y = 76;
|
||||
return y;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function foo(a: number, b: number): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
function bar(a: number, b: number): number[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
module BugFix3 {
|
||||
declare var f: {
|
||||
(): any;
|
||||
(x: number): string;
|
||||
foo: number;
|
||||
};
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
function f(a,b,c,d){
|
||||
for(var i=0;i<10;i++){
|
||||
var a=0;
|
||||
var b=a+a+a*a%a/2-1;
|
||||
b+=a;
|
||||
++b;
|
||||
f(a,b,c,d);
|
||||
if(1===1){
|
||||
var m=function(e,f){
|
||||
return e^f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0 ; i < this.foo(); i++) {
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
function f(a, b, c, d) {
|
||||
for (var i = 0; i < 10; i++) {
|
||||
var a = 0;
|
||||
var b = a + a + a * a % a / 2 - 1;
|
||||
b += a;
|
||||
++b;
|
||||
f(a, b, c, d);
|
||||
if (1 === 1) {
|
||||
var m = function(e, f) {
|
||||
return e ^ f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0 ; i < this.foo(); i++) {
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
with (foo.bar)
|
||||
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
with (bar.blah)
|
||||
{
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
with (foo.bar) {
|
||||
|
||||
}
|
||||
|
||||
with (bar.blah) {
|
||||
}
|
||||
@ -62,7 +62,7 @@ namespace ts {
|
||||
});
|
||||
|
||||
it("Correct errors for " + justName, () => {
|
||||
Harness.Baseline.runBaseline("Correct errors", justName.replace(/\.tsx?$/, ".errors.txt"), () => {
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".errors.txt"), () => {
|
||||
if (transpileResult.diagnostics.length === 0) {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
@ -75,7 +75,7 @@ namespace ts {
|
||||
|
||||
if (canUseOldTranspile) {
|
||||
it("Correct errors (old transpile) for " + justName, () => {
|
||||
Harness.Baseline.runBaseline("Correct errors", justName.replace(/\.tsx?$/, ".oldTranspile.errors.txt"), () => {
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".oldTranspile.errors.txt"), () => {
|
||||
if (oldTranspileDiagnostics.length === 0) {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
@ -88,7 +88,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
it("Correct output for " + justName, () => {
|
||||
Harness.Baseline.runBaseline("Correct output", justName.replace(/\.tsx?$/, ".js"), () => {
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".js"), () => {
|
||||
if (transpileResult.outputText) {
|
||||
return transpileResult.outputText;
|
||||
}
|
||||
@ -104,7 +104,7 @@ namespace ts {
|
||||
|
||||
if (canUseOldTranspile) {
|
||||
it("Correct output (old transpile) for " + justName, () => {
|
||||
Harness.Baseline.runBaseline("Correct output", justName.replace(/\.tsx?$/, ".oldTranspile.js"), () => {
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".oldTranspile.js"), () => {
|
||||
return oldTranspileResult;
|
||||
});
|
||||
});
|
||||
|
||||
@ -181,5 +181,26 @@ namespace ts {
|
||||
["/d.ts", "/folder/e.ts"]
|
||||
);
|
||||
});
|
||||
|
||||
it("parse and re-emit tsconfig.json file with diagnostics", () => {
|
||||
const content = `{
|
||||
"compilerOptions": {
|
||||
"allowJs": true
|
||||
// Some comments
|
||||
"outDir": "bin"
|
||||
}
|
||||
"files": ["file1.ts"]
|
||||
}`;
|
||||
const { configJsonObject, diagnostics } = parseAndReEmitConfigJSONFile(content);
|
||||
const expectedResult = {
|
||||
compilerOptions: {
|
||||
allowJs: true,
|
||||
outDir: "bin"
|
||||
},
|
||||
files: ["file1.ts"]
|
||||
};
|
||||
assert.isTrue(diagnostics.length === 2);
|
||||
assert.equal(JSON.stringify(configJsonObject), JSON.stringify(expectedResult));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -198,17 +198,13 @@ namespace ts {
|
||||
|
||||
watchDirectory(directoryName: string, callback: DirectoryWatcherCallback, recursive: boolean): DirectoryWatcher {
|
||||
const path = this.toPath(directoryName);
|
||||
const callbacks = multiMapAdd(this.watchedDirectories, path, { cb: callback, recursive });
|
||||
const cbWithRecursive = { cb: callback, recursive };
|
||||
const callbacks = multiMapAdd(this.watchedDirectories, path, cbWithRecursive);
|
||||
return {
|
||||
referenceCount: 0,
|
||||
directoryName,
|
||||
close: () => {
|
||||
for (let i = 0; i < callbacks.length; i++) {
|
||||
if (callbacks[i].cb === callback) {
|
||||
callbacks.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
unorderedRemoveItem(callbacks, cbWithRecursive);
|
||||
if (!callbacks.length) {
|
||||
delete this.watchedDirectories[path];
|
||||
}
|
||||
@ -241,8 +237,7 @@ namespace ts {
|
||||
const callbacks = multiMapAdd(this.watchedFiles, path, callback);
|
||||
return {
|
||||
close: () => {
|
||||
const i = callbacks.indexOf(callback);
|
||||
callbacks.splice(i, 1);
|
||||
unorderedRemoveItem(callbacks, callback);
|
||||
if (!callbacks.length) {
|
||||
delete this.watchedFiles[path];
|
||||
}
|
||||
@ -257,7 +252,7 @@ namespace ts {
|
||||
};
|
||||
readonly clearTimeout = (timeoutId: any): void => {
|
||||
if (typeof timeoutId === "number") {
|
||||
this.callbackQueue.splice(timeoutId, 1);
|
||||
orderedRemoveItemAt(this.callbackQueue, timeoutId);
|
||||
}
|
||||
};
|
||||
|
||||
@ -621,5 +616,23 @@ namespace ts {
|
||||
checkNumberOfConfiguredProjects(projectService, 1);
|
||||
checkNumberOfInferredProjects(projectService, 0);
|
||||
});
|
||||
|
||||
it("should tolerate config file errors and still try to build a project", () => {
|
||||
const configFile: FileOrFolder = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: `{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"allowAnything": true
|
||||
},
|
||||
"someOtherProperty": {}
|
||||
}`
|
||||
};
|
||||
const host = new TestServerHost(/*useCaseSensitiveFileNames*/ false, getExecutingFilePathFromLibFile(libFile), "/", [commonFile1, commonFile2, libFile, configFile]);
|
||||
const projectService = new server.ProjectService(host, nullLogger);
|
||||
projectService.openClientFile(commonFile1.path);
|
||||
checkNumberOfConfiguredProjects(projectService, 1);
|
||||
checkConfiguredProjectRootFiles(projectService.configuredProjects[0], [commonFile1.path, commonFile2.path]);
|
||||
});
|
||||
});
|
||||
}
|
||||
70
src/lib/dom.generated.d.ts
vendored
70
src/lib/dom.generated.d.ts
vendored
@ -126,6 +126,7 @@ interface KeyAlgorithm {
|
||||
}
|
||||
|
||||
interface KeyboardEventInit extends EventModifierInit {
|
||||
code?: string;
|
||||
key?: string;
|
||||
location?: number;
|
||||
repeat?: boolean;
|
||||
@ -2288,7 +2289,7 @@ declare var DeviceRotationRate: {
|
||||
new(): DeviceRotationRate;
|
||||
}
|
||||
|
||||
interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEvent {
|
||||
interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEvent, ParentNode {
|
||||
/**
|
||||
* Sets or gets the URL for the current document.
|
||||
*/
|
||||
@ -3351,7 +3352,7 @@ declare var Document: {
|
||||
new(): Document;
|
||||
}
|
||||
|
||||
interface DocumentFragment extends Node, NodeSelector {
|
||||
interface DocumentFragment extends Node, NodeSelector, ParentNode {
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
@ -3420,7 +3421,7 @@ declare var EXT_texture_filter_anisotropic: {
|
||||
readonly TEXTURE_MAX_ANISOTROPY_EXT: number;
|
||||
}
|
||||
|
||||
interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelector, ChildNode {
|
||||
interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelector, ChildNode, ParentNode {
|
||||
readonly classList: DOMTokenList;
|
||||
className: string;
|
||||
readonly clientHeight: number;
|
||||
@ -3675,6 +3676,16 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec
|
||||
getElementsByClassName(classNames: string): NodeListOf<Element>;
|
||||
matches(selector: string): boolean;
|
||||
closest(selector: string): Element | null;
|
||||
scrollIntoView(arg?: boolean | ScrollIntoViewOptions): void;
|
||||
scroll(options?: ScrollToOptions): void;
|
||||
scroll(x: number, y: number): void;
|
||||
scrollTo(options?: ScrollToOptions): void;
|
||||
scrollTo(x: number, y: number): void;
|
||||
scrollBy(options?: ScrollToOptions): void;
|
||||
scrollBy(x: number, y: number): void;
|
||||
insertAdjacentElement(position: string, insertedElement: Element): Element | null;
|
||||
insertAdjacentHTML(where: string, html: string): void;
|
||||
insertAdjacentText(where: string, text: string): void;
|
||||
addEventListener(type: "MSGestureChange", listener: (this: this, ev: MSGestureEvent) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: "MSGestureDoubleTap", listener: (this: this, ev: MSGestureEvent) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: "MSGestureEnd", listener: (this: this, ev: MSGestureEvent) => any, useCapture?: boolean): void;
|
||||
@ -4446,7 +4457,7 @@ interface HTMLCanvasElement extends HTMLElement {
|
||||
* @param type The standard MIME type for the image format to return. If you do not specify this parameter, the default value is a PNG format image.
|
||||
*/
|
||||
toDataURL(type?: string, ...args: any[]): string;
|
||||
toBlob(callback: (result: Blob | null) => void, ... arguments: any[]): void;
|
||||
toBlob(callback: (result: Blob | null) => void, type?: string, ...arguments: any[]): void;
|
||||
}
|
||||
|
||||
declare var HTMLCanvasElement: {
|
||||
@ -4621,11 +4632,7 @@ interface HTMLElement extends Element {
|
||||
click(): void;
|
||||
dragDrop(): boolean;
|
||||
focus(): void;
|
||||
insertAdjacentElement(position: string, insertedElement: Element): Element;
|
||||
insertAdjacentHTML(where: string, html: string): void;
|
||||
insertAdjacentText(where: string, text: string): void;
|
||||
msGetInputContext(): MSInputMethodContext;
|
||||
scrollIntoView(top?: boolean): void;
|
||||
setActive(): void;
|
||||
addEventListener(type: "MSContentZoom", listener: (this: this, ev: UIEvent) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: "MSGestureChange", listener: (this: this, ev: MSGestureEvent) => any, useCapture?: boolean): void;
|
||||
@ -5890,6 +5897,7 @@ interface HTMLLinkElement extends HTMLElement, LinkStyle {
|
||||
*/
|
||||
type: string;
|
||||
import?: Document;
|
||||
integrity: string;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
@ -6178,7 +6186,7 @@ interface HTMLMediaElement extends HTMLElement {
|
||||
*/
|
||||
canPlayType(type: string): string;
|
||||
/**
|
||||
* Fires immediately after the client loads the object.
|
||||
* Resets the audio or video object and loads a new media resource.
|
||||
*/
|
||||
load(): void;
|
||||
/**
|
||||
@ -6751,6 +6759,7 @@ interface HTMLScriptElement extends HTMLElement {
|
||||
* Sets or retrieves the MIME type for the associated scripting engine.
|
||||
*/
|
||||
type: string;
|
||||
integrity: string;
|
||||
}
|
||||
|
||||
declare var HTMLScriptElement: {
|
||||
@ -7756,6 +7765,7 @@ interface KeyboardEvent extends UIEvent {
|
||||
readonly repeat: boolean;
|
||||
readonly shiftKey: boolean;
|
||||
readonly which: number;
|
||||
readonly code: string;
|
||||
getModifierState(keyArg: string): boolean;
|
||||
initKeyboardEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, keyArg: string, locationArg: number, modifiersListArg: string, repeat: boolean, locale: string): void;
|
||||
readonly DOM_KEY_LOCATION_JOYSTICK: number;
|
||||
@ -9128,6 +9138,7 @@ interface PerformanceTiming {
|
||||
readonly responseStart: number;
|
||||
readonly unloadEventEnd: number;
|
||||
readonly unloadEventStart: number;
|
||||
readonly secureConnectionStart: number;
|
||||
toJSON(): any;
|
||||
}
|
||||
|
||||
@ -11405,8 +11416,8 @@ declare var StereoPannerNode: {
|
||||
interface Storage {
|
||||
readonly length: number;
|
||||
clear(): void;
|
||||
getItem(key: string): string;
|
||||
key(index: number): string;
|
||||
getItem(key: string): string | null;
|
||||
key(index: number): string | null;
|
||||
removeItem(key: string): void;
|
||||
setItem(key: string, data: string): void;
|
||||
[key: string]: any;
|
||||
@ -12947,7 +12958,7 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window
|
||||
onunload: (this: this, ev: Event) => any;
|
||||
onvolumechange: (this: this, ev: Event) => any;
|
||||
onwaiting: (this: this, ev: Event) => any;
|
||||
readonly opener: Window;
|
||||
opener: any;
|
||||
orientation: string | number;
|
||||
readonly outerHeight: number;
|
||||
readonly outerWidth: number;
|
||||
@ -13002,6 +13013,9 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window
|
||||
webkitConvertPointFromNodeToPage(node: Node, pt: WebKitPoint): WebKitPoint;
|
||||
webkitConvertPointFromPageToNode(node: Node, pt: WebKitPoint): WebKitPoint;
|
||||
webkitRequestAnimationFrame(callback: FrameRequestCallback): number;
|
||||
scroll(options?: ScrollToOptions): void;
|
||||
scrollTo(options?: ScrollToOptions): void;
|
||||
scrollBy(options?: ScrollToOptions): void;
|
||||
addEventListener(type: "MSGestureChange", listener: (this: this, ev: MSGestureEvent) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: "MSGestureDoubleTap", listener: (this: this, ev: MSGestureEvent) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: "MSGestureEnd", listener: (this: this, ev: MSGestureEvent) => any, useCapture?: boolean): void;
|
||||
@ -14029,6 +14043,20 @@ interface ProgressEventInit extends EventInit {
|
||||
total?: number;
|
||||
}
|
||||
|
||||
interface ScrollOptions {
|
||||
behavior?: ScrollBehavior;
|
||||
}
|
||||
|
||||
interface ScrollToOptions extends ScrollOptions {
|
||||
left?: number;
|
||||
top?: number;
|
||||
}
|
||||
|
||||
interface ScrollIntoViewOptions extends ScrollOptions {
|
||||
block?: ScrollLogicalPosition;
|
||||
inline?: ScrollLogicalPosition;
|
||||
}
|
||||
|
||||
interface ClipboardEventInit extends EventInit {
|
||||
data?: string;
|
||||
dataType?: string;
|
||||
@ -14072,7 +14100,7 @@ interface EcdsaParams extends Algorithm {
|
||||
}
|
||||
|
||||
interface EcKeyGenParams extends Algorithm {
|
||||
typedCurve: string;
|
||||
namedCurve: string;
|
||||
}
|
||||
|
||||
interface EcKeyAlgorithm extends KeyAlgorithm {
|
||||
@ -14208,6 +14236,13 @@ interface JsonWebKey {
|
||||
k?: string;
|
||||
}
|
||||
|
||||
interface ParentNode {
|
||||
readonly children: HTMLCollection;
|
||||
readonly firstElementChild: Element;
|
||||
readonly lastElementChild: Element;
|
||||
readonly childElementCount: number;
|
||||
}
|
||||
|
||||
declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
|
||||
|
||||
interface ErrorEventHandler {
|
||||
@ -14278,7 +14313,7 @@ declare var location: Location;
|
||||
declare var locationbar: BarProp;
|
||||
declare var menubar: BarProp;
|
||||
declare var msCredentials: MSCredentials;
|
||||
declare var name: string;
|
||||
declare const name: never;
|
||||
declare var navigator: Navigator;
|
||||
declare var offscreenBuffering: string | boolean;
|
||||
declare var onabort: (this: Window, ev: UIEvent) => any;
|
||||
@ -14372,7 +14407,7 @@ declare var ontouchstart: (ev: TouchEvent) => any;
|
||||
declare var onunload: (this: Window, ev: Event) => any;
|
||||
declare var onvolumechange: (this: Window, ev: Event) => any;
|
||||
declare var onwaiting: (this: Window, ev: Event) => any;
|
||||
declare var opener: Window;
|
||||
declare var opener: any;
|
||||
declare var orientation: string | number;
|
||||
declare var outerHeight: number;
|
||||
declare var outerWidth: number;
|
||||
@ -14425,6 +14460,9 @@ declare function webkitCancelAnimationFrame(handle: number): void;
|
||||
declare function webkitConvertPointFromNodeToPage(node: Node, pt: WebKitPoint): WebKitPoint;
|
||||
declare function webkitConvertPointFromPageToNode(node: Node, pt: WebKitPoint): WebKitPoint;
|
||||
declare function webkitRequestAnimationFrame(callback: FrameRequestCallback): number;
|
||||
declare function scroll(options?: ScrollToOptions): void;
|
||||
declare function scrollTo(options?: ScrollToOptions): void;
|
||||
declare function scrollBy(options?: ScrollToOptions): void;
|
||||
declare function toString(): string;
|
||||
declare function addEventListener(type: string, listener?: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
declare function dispatchEvent(evt: Event): boolean;
|
||||
@ -14580,6 +14618,8 @@ type MSOutboundPayload = MSVideoSendPayload | MSAudioSendPayload;
|
||||
type RTCIceGatherCandidate = RTCIceCandidate | RTCIceCandidateComplete;
|
||||
type RTCTransport = RTCDtlsTransport | RTCSrtpSdesTransport;
|
||||
type payloadtype = number;
|
||||
type ScrollBehavior = "auto" | "instant" | "smooth";
|
||||
type ScrollLogicalPosition = "start" | "center" | "end" | "nearest";
|
||||
type IDBValidKey = number | string | Date | IDBArrayKey;
|
||||
type BufferSource = ArrayBuffer | ArrayBufferView;
|
||||
type MouseWheelEvent = WheelEvent;
|
||||
2
src/lib/webworker.generated.d.ts
vendored
2
src/lib/webworker.generated.d.ts
vendored
@ -1000,7 +1000,7 @@ interface EcdsaParams extends Algorithm {
|
||||
}
|
||||
|
||||
interface EcKeyGenParams extends Algorithm {
|
||||
typedCurve: string;
|
||||
namedCurve: string;
|
||||
}
|
||||
|
||||
interface EcKeyAlgorithm extends KeyAlgorithm {
|
||||
|
||||
@ -275,7 +275,7 @@ namespace ts.server {
|
||||
removeRoot(info: ScriptInfo) {
|
||||
if (this.filenameToScript.contains(info.path)) {
|
||||
this.filenameToScript.remove(info.path);
|
||||
this.roots = copyListRemovingItem(info, this.roots);
|
||||
unorderedRemoveItem(this.roots, info);
|
||||
this.resolvedModuleNames.remove(info.path);
|
||||
this.resolvedTypeReferenceDirectives.remove(info.path);
|
||||
}
|
||||
@ -585,16 +585,6 @@ namespace ts.server {
|
||||
project?: Project;
|
||||
}
|
||||
|
||||
function copyListRemovingItem<T>(item: T, list: T[]) {
|
||||
const copiedList: T[] = [];
|
||||
for (let i = 0, len = list.length; i < len; i++) {
|
||||
if (list[i] != item) {
|
||||
copiedList.push(list[i]);
|
||||
}
|
||||
}
|
||||
return copiedList;
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper funciton processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project.
|
||||
*/
|
||||
@ -603,8 +593,11 @@ namespace ts.server {
|
||||
return projects.length > 1 ? deduplicate(result, areEqual) : result;
|
||||
}
|
||||
|
||||
export type ProjectServiceEvent =
|
||||
{ eventName: "context", data: { project: Project, fileName: string } } | { eventName: "configFileDiag", data: { triggerFile?: string, configFileName: string, diagnostics: Diagnostic[] } }
|
||||
|
||||
export interface ProjectServiceEventHandler {
|
||||
(eventName: string, project: Project, fileName: string): void;
|
||||
(event: ProjectServiceEvent): void;
|
||||
}
|
||||
|
||||
export interface HostConfiguration {
|
||||
@ -699,7 +692,8 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
handleProjectFileListChanges(project: Project) {
|
||||
const { projectOptions } = this.configFileToProjectOptions(project.projectFilename);
|
||||
const { projectOptions, errors } = this.configFileToProjectOptions(project.projectFilename);
|
||||
this.reportConfigFileDiagnostics(project.projectFilename, errors);
|
||||
|
||||
const newRootFiles = projectOptions.files.map((f => this.getCanonicalFileName(f)));
|
||||
const currentRootFiles = project.getRootFiles().map((f => this.getCanonicalFileName(f)));
|
||||
@ -717,18 +711,32 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
reportConfigFileDiagnostics(configFileName: string, diagnostics: Diagnostic[], triggerFile?: string) {
|
||||
if (diagnostics && diagnostics.length > 0) {
|
||||
this.eventHandler({
|
||||
eventName: "configFileDiag",
|
||||
data: { configFileName, diagnostics, triggerFile }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the callback function when a watched directory has an added tsconfig file.
|
||||
*/
|
||||
directoryWatchedForTsconfigChanged(fileName: string) {
|
||||
if (ts.getBaseFileName(fileName) != "tsconfig.json") {
|
||||
if (ts.getBaseFileName(fileName) !== "tsconfig.json") {
|
||||
this.log(fileName + " is not tsconfig.json");
|
||||
return;
|
||||
}
|
||||
|
||||
this.log("Detected newly added tsconfig file: " + fileName);
|
||||
|
||||
const { projectOptions } = this.configFileToProjectOptions(fileName);
|
||||
const { projectOptions, errors } = this.configFileToProjectOptions(fileName);
|
||||
this.reportConfigFileDiagnostics(fileName, errors);
|
||||
|
||||
if (!projectOptions) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rootFilesInTsconfig = projectOptions.files.map(f => this.getCanonicalFileName(f));
|
||||
const openFileRoots = this.openFileRoots.map(s => this.getCanonicalFileName(s.fileName));
|
||||
@ -748,10 +756,13 @@ namespace ts.server {
|
||||
return ts.normalizePath(name);
|
||||
}
|
||||
|
||||
watchedProjectConfigFileChanged(project: Project) {
|
||||
watchedProjectConfigFileChanged(project: Project): void {
|
||||
this.log("Config file changed: " + project.projectFilename);
|
||||
this.updateConfiguredProject(project);
|
||||
const configFileErrors = this.updateConfiguredProject(project);
|
||||
this.updateProjectStructure();
|
||||
if (configFileErrors && configFileErrors.length > 0) {
|
||||
this.eventHandler({ eventName: "configFileDiag", data: { triggerFile: project.projectFilename, configFileName: project.projectFilename, diagnostics: configFileErrors } });
|
||||
}
|
||||
}
|
||||
|
||||
log(msg: string, type = "Err") {
|
||||
@ -828,13 +839,13 @@ namespace ts.server {
|
||||
for (let j = 0, flen = this.openFileRoots.length; j < flen; j++) {
|
||||
const openFile = this.openFileRoots[j];
|
||||
if (this.eventHandler) {
|
||||
this.eventHandler("context", openFile.defaultProject, openFile.fileName);
|
||||
this.eventHandler({ eventName: "context", data: { project: openFile.defaultProject, fileName: openFile.fileName } });
|
||||
}
|
||||
}
|
||||
for (let j = 0, flen = this.openFilesReferenced.length; j < flen; j++) {
|
||||
const openFile = this.openFilesReferenced[j];
|
||||
if (this.eventHandler) {
|
||||
this.eventHandler("context", openFile.defaultProject, openFile.fileName);
|
||||
this.eventHandler({ eventName: "context", data: { project: openFile.defaultProject, fileName: openFile.fileName } });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -859,7 +870,7 @@ namespace ts.server {
|
||||
project.directoryWatcher.close();
|
||||
forEachProperty(project.directoriesWatchedForWildcards, watcher => { watcher.close(); });
|
||||
delete project.directoriesWatchedForWildcards;
|
||||
this.configuredProjects = copyListRemovingItem(project, this.configuredProjects);
|
||||
unorderedRemoveItem(this.configuredProjects, project);
|
||||
}
|
||||
else {
|
||||
for (const directory of project.directoriesWatchedForTsconfig) {
|
||||
@ -871,7 +882,7 @@ namespace ts.server {
|
||||
delete project.projectService.directoryWatchersForTsconfig[directory];
|
||||
}
|
||||
}
|
||||
this.inferredProjects = copyListRemovingItem(project, this.inferredProjects);
|
||||
unorderedRemoveItem(this.inferredProjects, project);
|
||||
}
|
||||
|
||||
const fileNames = project.getFileNames();
|
||||
@ -996,7 +1007,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.openFilesReferenced = copyListRemovingItem(info, this.openFilesReferenced);
|
||||
unorderedRemoveItem(this.openFilesReferenced, info);
|
||||
}
|
||||
info.close();
|
||||
}
|
||||
@ -1218,7 +1229,7 @@ namespace ts.server {
|
||||
const project = this.findConfiguredProjectByConfigFile(configFileName);
|
||||
if (!project) {
|
||||
const configResult = this.openConfigFile(configFileName, fileName);
|
||||
if (!configResult.success) {
|
||||
if (!configResult.project) {
|
||||
return { configFileName, configFileErrors: configResult.errors };
|
||||
}
|
||||
else {
|
||||
@ -1234,11 +1245,12 @@ namespace ts.server {
|
||||
else {
|
||||
this.updateConfiguredProject(project);
|
||||
}
|
||||
return { configFileName };
|
||||
}
|
||||
else {
|
||||
this.log("No config files found.");
|
||||
}
|
||||
return configFileName ? { configFileName } : {};
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1328,34 +1340,31 @@ namespace ts.server {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
configFileToProjectOptions(configFilename: string): { succeeded: boolean, projectOptions?: ProjectOptions, errors?: Diagnostic[] } {
|
||||
configFileToProjectOptions(configFilename: string): { projectOptions?: ProjectOptions, errors: Diagnostic[] } {
|
||||
configFilename = ts.normalizePath(configFilename);
|
||||
let errors: Diagnostic[] = [];
|
||||
// file references will be relative to dirPath (or absolute)
|
||||
const dirPath = ts.getDirectoryPath(configFilename);
|
||||
const contents = this.host.readFile(configFilename);
|
||||
const rawConfig: { config?: ProjectOptions; error?: Diagnostic; } = ts.parseConfigFileTextToJson(configFilename, contents);
|
||||
if (rawConfig.error) {
|
||||
return { succeeded: false, errors: [rawConfig.error] };
|
||||
const { configJsonObject, diagnostics } = ts.parseAndReEmitConfigJSONFile(contents);
|
||||
errors = concatenate(errors, diagnostics);
|
||||
const parsedCommandLine = ts.parseJsonConfigFileContent(configJsonObject, this.host, dirPath, /*existingOptions*/ {}, configFilename);
|
||||
errors = concatenate(errors, parsedCommandLine.errors);
|
||||
Debug.assert(!!parsedCommandLine.fileNames);
|
||||
|
||||
if (parsedCommandLine.fileNames.length === 0) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.The_config_file_0_found_doesn_t_contain_any_source_files, configFilename));
|
||||
return { errors };
|
||||
}
|
||||
else {
|
||||
const parsedCommandLine = ts.parseJsonConfigFileContent(rawConfig.config, this.host, dirPath, /*existingOptions*/ {}, configFilename);
|
||||
Debug.assert(!!parsedCommandLine.fileNames);
|
||||
|
||||
if (parsedCommandLine.errors && (parsedCommandLine.errors.length > 0)) {
|
||||
return { succeeded: false, errors: parsedCommandLine.errors };
|
||||
}
|
||||
else if (parsedCommandLine.fileNames.length === 0) {
|
||||
const error = createCompilerDiagnostic(Diagnostics.The_config_file_0_found_doesn_t_contain_any_source_files, configFilename);
|
||||
return { succeeded: false, errors: [error] };
|
||||
}
|
||||
else {
|
||||
const projectOptions: ProjectOptions = {
|
||||
files: parsedCommandLine.fileNames,
|
||||
wildcardDirectories: parsedCommandLine.wildcardDirectories,
|
||||
compilerOptions: parsedCommandLine.options,
|
||||
};
|
||||
return { succeeded: true, projectOptions };
|
||||
}
|
||||
// if the project has some files, we can continue with the parsed options and tolerate
|
||||
// errors in the parsedCommandLine
|
||||
const projectOptions: ProjectOptions = {
|
||||
files: parsedCommandLine.fileNames,
|
||||
wildcardDirectories: parsedCommandLine.wildcardDirectories,
|
||||
compilerOptions: parsedCommandLine.options,
|
||||
};
|
||||
return { projectOptions, errors };
|
||||
}
|
||||
}
|
||||
|
||||
@ -1377,64 +1386,63 @@ namespace ts.server {
|
||||
return false;
|
||||
}
|
||||
|
||||
openConfigFile(configFilename: string, clientFileName?: string): { success: boolean, project?: Project, errors?: Diagnostic[] } {
|
||||
const { succeeded, projectOptions, errors } = this.configFileToProjectOptions(configFilename);
|
||||
if (!succeeded) {
|
||||
return { success: false, errors };
|
||||
openConfigFile(configFilename: string, clientFileName?: string): { project?: Project, errors: Diagnostic[] } {
|
||||
const parseConfigFileResult = this.configFileToProjectOptions(configFilename);
|
||||
let errors = parseConfigFileResult.errors;
|
||||
if (!parseConfigFileResult.projectOptions) {
|
||||
return { errors };
|
||||
}
|
||||
else {
|
||||
if (!projectOptions.compilerOptions.disableSizeLimit && projectOptions.compilerOptions.allowJs) {
|
||||
if (this.exceedTotalNonTsFileSizeLimit(projectOptions.files)) {
|
||||
const project = this.createProject(configFilename, projectOptions, /*languageServiceDisabled*/ true);
|
||||
const projectOptions = parseConfigFileResult.projectOptions;
|
||||
if (!projectOptions.compilerOptions.disableSizeLimit && projectOptions.compilerOptions.allowJs) {
|
||||
if (this.exceedTotalNonTsFileSizeLimit(projectOptions.files)) {
|
||||
const project = this.createProject(configFilename, projectOptions, /*languageServiceDisabled*/ true);
|
||||
|
||||
// for configured projects with languageService disabled, we only watch its config file,
|
||||
// do not care about the directory changes in the folder.
|
||||
project.projectFileWatcher = this.host.watchFile(
|
||||
toPath(configFilename, configFilename, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
|
||||
_ => this.watchedProjectConfigFileChanged(project));
|
||||
return { success: true, project };
|
||||
}
|
||||
// for configured projects with languageService disabled, we only watch its config file,
|
||||
// do not care about the directory changes in the folder.
|
||||
project.projectFileWatcher = this.host.watchFile(
|
||||
toPath(configFilename, configFilename, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
|
||||
_ => this.watchedProjectConfigFileChanged(project));
|
||||
return { project, errors };
|
||||
}
|
||||
}
|
||||
|
||||
const project = this.createProject(configFilename, projectOptions);
|
||||
for (const rootFilename of projectOptions.files) {
|
||||
if (this.host.fileExists(rootFilename)) {
|
||||
const info = this.openFile(rootFilename, /*openedByClient*/ clientFileName == rootFilename);
|
||||
project.addRoot(info);
|
||||
}
|
||||
else {
|
||||
(errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.File_0_not_found, rootFilename));
|
||||
}
|
||||
}
|
||||
project.finishGraph();
|
||||
project.projectFileWatcher = this.host.watchFile(configFilename, _ => this.watchedProjectConfigFileChanged(project));
|
||||
|
||||
const configDirectoryPath = ts.getDirectoryPath(configFilename);
|
||||
|
||||
this.log("Add recursive watcher for: " + configDirectoryPath);
|
||||
project.directoryWatcher = this.host.watchDirectory(
|
||||
configDirectoryPath,
|
||||
path => this.directoryWatchedForSourceFilesChanged(project, path),
|
||||
/*recursive*/ true
|
||||
);
|
||||
|
||||
project.directoriesWatchedForWildcards = reduceProperties(createMap(projectOptions.wildcardDirectories), (watchers, flag, directory) => {
|
||||
if (comparePaths(configDirectoryPath, directory, ".", !this.host.useCaseSensitiveFileNames) !== Comparison.EqualTo) {
|
||||
const recursive = (flag & WatchDirectoryFlags.Recursive) !== 0;
|
||||
this.log(`Add ${ recursive ? "recursive " : ""}watcher for: ${directory}`);
|
||||
watchers[directory] = this.host.watchDirectory(
|
||||
directory,
|
||||
path => this.directoryWatchedForSourceFilesChanged(project, path),
|
||||
recursive
|
||||
);
|
||||
}
|
||||
|
||||
const project = this.createProject(configFilename, projectOptions);
|
||||
let errors: Diagnostic[];
|
||||
for (const rootFilename of projectOptions.files) {
|
||||
if (this.host.fileExists(rootFilename)) {
|
||||
const info = this.openFile(rootFilename, /*openedByClient*/ clientFileName == rootFilename);
|
||||
project.addRoot(info);
|
||||
}
|
||||
else {
|
||||
(errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.File_0_not_found, rootFilename));
|
||||
}
|
||||
}
|
||||
project.finishGraph();
|
||||
project.projectFileWatcher = this.host.watchFile(configFilename, _ => this.watchedProjectConfigFileChanged(project));
|
||||
return watchers;
|
||||
}, <Map<FileWatcher>>{});
|
||||
|
||||
const configDirectoryPath = ts.getDirectoryPath(configFilename);
|
||||
|
||||
this.log("Add recursive watcher for: " + configDirectoryPath);
|
||||
project.directoryWatcher = this.host.watchDirectory(
|
||||
configDirectoryPath,
|
||||
path => this.directoryWatchedForSourceFilesChanged(project, path),
|
||||
/*recursive*/ true
|
||||
);
|
||||
|
||||
project.directoriesWatchedForWildcards = reduceProperties(createMap(projectOptions.wildcardDirectories), (watchers, flag, directory) => {
|
||||
if (comparePaths(configDirectoryPath, directory, ".", !this.host.useCaseSensitiveFileNames) !== Comparison.EqualTo) {
|
||||
const recursive = (flag & WatchDirectoryFlags.Recursive) !== 0;
|
||||
this.log(`Add ${ recursive ? "recursive " : ""}watcher for: ${directory}`);
|
||||
watchers[directory] = this.host.watchDirectory(
|
||||
directory,
|
||||
path => this.directoryWatchedForSourceFilesChanged(project, path),
|
||||
recursive
|
||||
);
|
||||
}
|
||||
|
||||
return watchers;
|
||||
}, <Map<FileWatcher>>{});
|
||||
|
||||
return { success: true, project: project, errors };
|
||||
}
|
||||
return { project: project, errors };
|
||||
}
|
||||
|
||||
updateConfiguredProject(project: Project): Diagnostic[] {
|
||||
@ -1443,15 +1451,15 @@ namespace ts.server {
|
||||
this.removeProject(project);
|
||||
}
|
||||
else {
|
||||
const { succeeded, projectOptions, errors } = this.configFileToProjectOptions(project.projectFilename);
|
||||
if (!succeeded) {
|
||||
const { projectOptions, errors } = this.configFileToProjectOptions(project.projectFilename);
|
||||
if (!projectOptions) {
|
||||
return errors;
|
||||
}
|
||||
else {
|
||||
if (projectOptions.compilerOptions && !projectOptions.compilerOptions.disableSizeLimit && this.exceedTotalNonTsFileSizeLimit(projectOptions.files)) {
|
||||
project.setProjectOptions(projectOptions);
|
||||
if (project.languageServiceDiabled) {
|
||||
return;
|
||||
return errors;
|
||||
}
|
||||
|
||||
project.disableLanguageService();
|
||||
@ -1459,7 +1467,7 @@ namespace ts.server {
|
||||
project.directoryWatcher.close();
|
||||
project.directoryWatcher = undefined;
|
||||
}
|
||||
return;
|
||||
return errors;
|
||||
}
|
||||
|
||||
if (project.languageServiceDiabled) {
|
||||
@ -1478,7 +1486,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
project.finishGraph();
|
||||
return;
|
||||
return errors;
|
||||
}
|
||||
|
||||
// if the project is too large, the root files might not have been all loaded if the total
|
||||
@ -1506,13 +1514,13 @@ namespace ts.server {
|
||||
// openFileRoots or openFileReferenced.
|
||||
if (info.isOpen) {
|
||||
if (this.openFileRoots.indexOf(info) >= 0) {
|
||||
this.openFileRoots = copyListRemovingItem(info, this.openFileRoots);
|
||||
unorderedRemoveItem(this.openFileRoots, info);
|
||||
if (info.defaultProject && !info.defaultProject.isConfiguredProject()) {
|
||||
this.removeProject(info.defaultProject);
|
||||
}
|
||||
}
|
||||
if (this.openFilesReferenced.indexOf(info) >= 0) {
|
||||
this.openFilesReferenced = copyListRemovingItem(info, this.openFilesReferenced);
|
||||
unorderedRemoveItem(this.openFilesReferenced, info);
|
||||
}
|
||||
this.openFileRootsConfigured.push(info);
|
||||
info.defaultProject = project;
|
||||
@ -1524,6 +1532,7 @@ namespace ts.server {
|
||||
project.setProjectOptions(projectOptions);
|
||||
project.finishGraph();
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -204,7 +204,7 @@ namespace ts.server {
|
||||
// average async stat takes about 30 microseconds
|
||||
// set chunk size to do 30 files in < 1 millisecond
|
||||
function createPollingWatchedFileSet(interval = 2500, chunkSize = 30) {
|
||||
let watchedFiles: WatchedFile[] = [];
|
||||
const watchedFiles: WatchedFile[] = [];
|
||||
let nextFileToCheck = 0;
|
||||
let watchTimer: any;
|
||||
|
||||
@ -267,7 +267,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
function removeFile(file: WatchedFile) {
|
||||
watchedFiles = copyListRemovingItem(file, watchedFiles);
|
||||
unorderedRemoveItem(watchedFiles, file);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@ -153,16 +153,22 @@ namespace ts.server {
|
||||
private logger: Logger
|
||||
) {
|
||||
this.projectService =
|
||||
new ProjectService(host, logger, (eventName, project, fileName) => {
|
||||
this.handleEvent(eventName, project, fileName);
|
||||
new ProjectService(host, logger, event => {
|
||||
this.handleEvent(event);
|
||||
});
|
||||
}
|
||||
|
||||
private handleEvent(eventName: string, project: Project, fileName: string) {
|
||||
if (eventName == "context") {
|
||||
this.projectService.log("got context event, updating diagnostics for" + fileName, "Info");
|
||||
this.updateErrorCheck([{ fileName, project }], this.changeSeq,
|
||||
(n) => n === this.changeSeq, 100);
|
||||
private handleEvent(event: ProjectServiceEvent) {
|
||||
switch (event.eventName) {
|
||||
case "context":
|
||||
const { project, fileName } = event.data;
|
||||
this.projectService.log("got context event, updating diagnostics for" + fileName, "Info");
|
||||
this.updateErrorCheck([{ fileName, project }], this.changeSeq,
|
||||
(n) => n === this.changeSeq, 100);
|
||||
break;
|
||||
case "configFileDiag":
|
||||
const { triggerFile, configFileName, diagnostics } = event.data;
|
||||
this.configFileDiagnosticEvent(triggerFile, configFileName, diagnostics);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -466,6 +466,7 @@ namespace ts.NavigationBar {
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return hasSomeImportantChild(item);
|
||||
|
||||
case SyntaxKind.ArrowFunction:
|
||||
|
||||
@ -280,11 +280,14 @@ namespace ts {
|
||||
let pos = this.pos;
|
||||
const useJSDocScanner = this.kind >= SyntaxKind.FirstJSDocTagNode && this.kind <= SyntaxKind.LastJSDocTagNode;
|
||||
const processNode = (node: Node) => {
|
||||
if (pos < node.pos) {
|
||||
const isJSDocTagNode = isJSDocTag(node);
|
||||
if (!isJSDocTagNode && pos < node.pos) {
|
||||
pos = this.addSyntheticNodes(children, pos, node.pos, useJSDocScanner);
|
||||
}
|
||||
children.push(node);
|
||||
pos = node.end;
|
||||
if (!isJSDocTagNode) {
|
||||
pos = node.end;
|
||||
}
|
||||
};
|
||||
const processNodes = (nodes: NodeArray<Node>) => {
|
||||
if (pos < nodes.pos) {
|
||||
@ -1369,8 +1372,12 @@ namespace ts {
|
||||
containerName: string;
|
||||
}
|
||||
|
||||
export interface ReferencedSymbolDefinitionInfo extends DefinitionInfo {
|
||||
displayParts: SymbolDisplayPart[];
|
||||
}
|
||||
|
||||
export interface ReferencedSymbol {
|
||||
definition: DefinitionInfo;
|
||||
definition: ReferencedSymbolDefinitionInfo;
|
||||
references: ReferenceEntry[];
|
||||
}
|
||||
|
||||
@ -2784,18 +2791,42 @@ namespace ts {
|
||||
return node && node.parent && node.parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>node.parent).name === node;
|
||||
}
|
||||
|
||||
function climbPastPropertyAccess(node: Node) {
|
||||
return isRightSideOfPropertyAccess(node) ? node.parent : node;
|
||||
}
|
||||
|
||||
/** Get `C` given `N` if `N` is in the position `class C extends N` or `class C extends foo.N` where `N` is an identifier. */
|
||||
function tryGetClassByExtendingIdentifier(node: Node): ClassLikeDeclaration | undefined {
|
||||
return tryGetClassExtendingExpressionWithTypeArguments(climbPastPropertyAccess(node).parent);
|
||||
}
|
||||
|
||||
function isCallExpressionTarget(node: Node): boolean {
|
||||
if (isRightSideOfPropertyAccess(node)) {
|
||||
node = node.parent;
|
||||
}
|
||||
return node && node.parent && node.parent.kind === SyntaxKind.CallExpression && (<CallExpression>node.parent).expression === node;
|
||||
return isCallOrNewExpressionTarget(node, SyntaxKind.CallExpression);
|
||||
}
|
||||
|
||||
function isNewExpressionTarget(node: Node): boolean {
|
||||
if (isRightSideOfPropertyAccess(node)) {
|
||||
node = node.parent;
|
||||
}
|
||||
return node && node.parent && node.parent.kind === SyntaxKind.NewExpression && (<CallExpression>node.parent).expression === node;
|
||||
return isCallOrNewExpressionTarget(node, SyntaxKind.NewExpression);
|
||||
}
|
||||
|
||||
function isCallOrNewExpressionTarget(node: Node, kind: SyntaxKind) {
|
||||
const target = climbPastPropertyAccess(node);
|
||||
return target && target.parent && target.parent.kind === kind && (<CallExpression>target.parent).expression === target;
|
||||
}
|
||||
|
||||
function climbPastManyPropertyAccesses(node: Node): Node {
|
||||
return isRightSideOfPropertyAccess(node) ? climbPastManyPropertyAccesses(node.parent) : node;
|
||||
}
|
||||
|
||||
/** Returns a CallLikeExpression where `node` is the target being invoked. */
|
||||
function getAncestorCallLikeExpression(node: Node): CallLikeExpression | undefined {
|
||||
const target = climbPastManyPropertyAccesses(node);
|
||||
const callLike = target.parent;
|
||||
return callLike && isCallLikeExpression(callLike) && getInvokedExpression(callLike) === target && callLike;
|
||||
}
|
||||
|
||||
function tryGetSignatureDeclaration(typeChecker: TypeChecker, node: Node): SignatureDeclaration | undefined {
|
||||
const callLike = getAncestorCallLikeExpression(node);
|
||||
return callLike && typeChecker.getResolvedSignature(callLike).declaration;
|
||||
}
|
||||
|
||||
function isNameOfModuleDeclaration(node: Node) {
|
||||
@ -4601,7 +4632,7 @@ namespace ts {
|
||||
const symbolFlags = symbol.flags;
|
||||
let symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, symbolFlags, location);
|
||||
let hasAddedSymbolInfo: boolean;
|
||||
const isThisExpression: boolean = location.kind === SyntaxKind.ThisKeyword && isExpression(location);
|
||||
const isThisExpression = location.kind === SyntaxKind.ThisKeyword && isExpression(location);
|
||||
let type: Type;
|
||||
|
||||
// Class at constructor site need to be shown as constructor apart from property,method, vars
|
||||
@ -4916,6 +4947,28 @@ namespace ts {
|
||||
|
||||
if (!documentation) {
|
||||
documentation = symbol.getDocumentationComment();
|
||||
if (documentation.length === 0 && symbol.flags & SymbolFlags.Property) {
|
||||
// For some special property access expressions like `experts.foo = foo` or `module.exports.foo = foo`
|
||||
// there documentation comments might be attached to the right hand side symbol of their declarations.
|
||||
// The pattern of such special property access is that the parent symbol is the symbol of the file.
|
||||
if (symbol.parent && forEach(symbol.parent.declarations, declaration => declaration.kind === SyntaxKind.SourceFile)) {
|
||||
for (const declaration of symbol.declarations) {
|
||||
if (!declaration.parent || declaration.parent.kind !== SyntaxKind.BinaryExpression) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const rhsSymbol = program.getTypeChecker().getSymbolAtLocation((<BinaryExpression>declaration.parent).right);
|
||||
if (!rhsSymbol) {
|
||||
continue;
|
||||
}
|
||||
|
||||
documentation = rhsSymbol.getDocumentationComment();
|
||||
if (documentation.length > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { displayParts, documentation, symbolKind };
|
||||
@ -5042,14 +5095,25 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function getSymbolInfo(typeChecker: TypeChecker, symbol: Symbol, node: Node) {
|
||||
return {
|
||||
symbolName: typeChecker.symbolToString(symbol), // Do not get scoped name, just the name of the symbol
|
||||
symbolKind: getSymbolKind(symbol, node),
|
||||
containerName: symbol.parent ? typeChecker.symbolToString(symbol.parent, node) : ""
|
||||
};
|
||||
}
|
||||
|
||||
function createDefinitionFromSignatureDeclaration(decl: SignatureDeclaration): DefinitionInfo {
|
||||
const typeChecker = program.getTypeChecker();
|
||||
const { symbolName, symbolKind, containerName } = getSymbolInfo(typeChecker, decl.symbol, decl);
|
||||
return createDefinitionInfo(decl, symbolKind, symbolName, containerName);
|
||||
}
|
||||
|
||||
function getDefinitionFromSymbol(symbol: Symbol, node: Node): DefinitionInfo[] {
|
||||
const typeChecker = program.getTypeChecker();
|
||||
const result: DefinitionInfo[] = [];
|
||||
const declarations = symbol.getDeclarations();
|
||||
const symbolName = typeChecker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol
|
||||
const symbolKind = getSymbolKind(symbol, node);
|
||||
const containerSymbol = symbol.parent;
|
||||
const containerName = containerSymbol ? typeChecker.symbolToString(containerSymbol, node) : "";
|
||||
const { symbolName, symbolKind, containerName } = getSymbolInfo(typeChecker, symbol, node);
|
||||
|
||||
if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) &&
|
||||
!tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) {
|
||||
@ -5175,6 +5239,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
const typeChecker = program.getTypeChecker();
|
||||
|
||||
const calledDeclaration = tryGetSignatureDeclaration(typeChecker, node);
|
||||
if (calledDeclaration) {
|
||||
return [createDefinitionFromSignatureDeclaration(calledDeclaration)];
|
||||
}
|
||||
|
||||
let symbol = typeChecker.getSymbolAtLocation(node);
|
||||
|
||||
// Could not find a symbol e.g. node is string or number keyword,
|
||||
@ -5982,6 +6052,7 @@ namespace ts {
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
// case SyntaxKind.SuperKeyword: TODO:GH#9268
|
||||
case SyntaxKind.ConstructorKeyword:
|
||||
case SyntaxKind.StringLiteral:
|
||||
return getReferencedSymbolsForNode(node, program.getSourceFiles(), findInStrings, findInComments);
|
||||
}
|
||||
@ -6026,6 +6097,8 @@ namespace ts {
|
||||
return getReferencesForSuperKeyword(node);
|
||||
}
|
||||
|
||||
// `getSymbolAtLocation` normally returns the symbol of the class when given the constructor keyword,
|
||||
// so we have to specify that we want the constructor symbol.
|
||||
const symbol = typeChecker.getSymbolAtLocation(node);
|
||||
|
||||
if (!symbol && node.kind === SyntaxKind.StringLiteral) {
|
||||
@ -6081,7 +6154,7 @@ namespace ts {
|
||||
|
||||
return result;
|
||||
|
||||
function getDefinition(symbol: Symbol): DefinitionInfo {
|
||||
function getDefinition(symbol: Symbol): ReferencedSymbolDefinitionInfo {
|
||||
const info = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, node.getSourceFile(), getContainerNode(node), node);
|
||||
const name = map(info.displayParts, p => p.text).join("");
|
||||
const declarations = symbol.declarations;
|
||||
@ -6095,11 +6168,12 @@ namespace ts {
|
||||
name,
|
||||
kind: info.symbolKind,
|
||||
fileName: declarations[0].getSourceFile().fileName,
|
||||
textSpan: createTextSpan(declarations[0].getStart(), 0)
|
||||
textSpan: createTextSpan(declarations[0].getStart(), 0),
|
||||
displayParts: info.displayParts
|
||||
};
|
||||
}
|
||||
|
||||
function getAliasSymbolForPropertyNameSymbol(symbol: Symbol, location: Node): Symbol {
|
||||
function getAliasSymbolForPropertyNameSymbol(symbol: Symbol, location: Node): Symbol | undefined {
|
||||
if (symbol.flags & SymbolFlags.Alias) {
|
||||
// Default import get alias
|
||||
const defaultImport = getDeclarationOfKind(symbol, SyntaxKind.ImportClause);
|
||||
@ -6125,6 +6199,10 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function followAliasIfNecessary(symbol: Symbol, location: Node): Symbol {
|
||||
return getAliasSymbolForPropertyNameSymbol(symbol, location) || symbol;
|
||||
}
|
||||
|
||||
function getPropertySymbolOfDestructuringAssignment(location: Node) {
|
||||
return isArrayLiteralOrObjectLiteralDestructuringPattern(location.parent.parent) &&
|
||||
typeChecker.getPropertySymbolOfDestructuringAssignment(<Identifier>location);
|
||||
@ -6290,13 +6368,14 @@ namespace ts {
|
||||
}
|
||||
});
|
||||
|
||||
const definition: DefinitionInfo = {
|
||||
const definition: ReferencedSymbolDefinitionInfo = {
|
||||
containerKind: "",
|
||||
containerName: "",
|
||||
fileName: targetLabel.getSourceFile().fileName,
|
||||
kind: ScriptElementKind.label,
|
||||
name: labelName,
|
||||
textSpan: createTextSpanFromBounds(targetLabel.getStart(), targetLabel.getEnd())
|
||||
textSpan: createTextSpanFromBounds(targetLabel.getStart(), targetLabel.getEnd()),
|
||||
displayParts: [displayPart(labelName, SymbolDisplayPartKind.text)]
|
||||
};
|
||||
|
||||
return [{ definition, references }];
|
||||
@ -6388,7 +6467,8 @@ namespace ts {
|
||||
if (referenceSymbol) {
|
||||
const referenceSymbolDeclaration = referenceSymbol.valueDeclaration;
|
||||
const shorthandValueSymbol = typeChecker.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration);
|
||||
const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation);
|
||||
const relatedSymbol = getRelatedSymbol(searchSymbols, referenceSymbol, referenceLocation,
|
||||
/*searchLocationIsConstructor*/ searchLocation.kind === SyntaxKind.ConstructorKeyword);
|
||||
|
||||
if (relatedSymbol) {
|
||||
const referencedSymbol = getReferencedSymbol(relatedSymbol);
|
||||
@ -6404,12 +6484,94 @@ namespace ts {
|
||||
const referencedSymbol = getReferencedSymbol(shorthandValueSymbol);
|
||||
referencedSymbol.references.push(getReferenceEntryFromNode(referenceSymbolDeclaration.name));
|
||||
}
|
||||
else if (searchLocation.kind === SyntaxKind.ConstructorKeyword) {
|
||||
findAdditionalConstructorReferences(referenceSymbol, referenceLocation);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
/** Adds references when a constructor is used with `new this()` in its own class and `super()` calls in subclasses. */
|
||||
function findAdditionalConstructorReferences(referenceSymbol: Symbol, referenceLocation: Node): void {
|
||||
Debug.assert(isClassLike(searchSymbol.valueDeclaration));
|
||||
|
||||
const referenceClass = referenceLocation.parent;
|
||||
if (referenceSymbol === searchSymbol && isClassLike(referenceClass)) {
|
||||
Debug.assert(referenceClass.name === referenceLocation);
|
||||
// This is the class declaration containing the constructor.
|
||||
addReferences(findOwnConstructorCalls(searchSymbol));
|
||||
}
|
||||
else {
|
||||
// If this class appears in `extends C`, then the extending class' "super" calls are references.
|
||||
const classExtending = tryGetClassByExtendingIdentifier(referenceLocation);
|
||||
if (classExtending && isClassLike(classExtending) && followAliasIfNecessary(referenceSymbol, referenceLocation) === searchSymbol) {
|
||||
addReferences(superConstructorAccesses(classExtending));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addReferences(references: Node[]): void {
|
||||
if (references.length) {
|
||||
const referencedSymbol = getReferencedSymbol(searchSymbol);
|
||||
addRange(referencedSymbol.references, map(references, getReferenceEntryFromNode));
|
||||
}
|
||||
}
|
||||
|
||||
/** `classSymbol` is the class where the constructor was defined.
|
||||
* Reference the constructor and all calls to `new this()`.
|
||||
*/
|
||||
function findOwnConstructorCalls(classSymbol: Symbol): Node[] {
|
||||
const result: Node[] = [];
|
||||
|
||||
for (const decl of classSymbol.members["__constructor"].declarations) {
|
||||
Debug.assert(decl.kind === SyntaxKind.Constructor);
|
||||
const ctrKeyword = decl.getChildAt(0);
|
||||
Debug.assert(ctrKeyword.kind === SyntaxKind.ConstructorKeyword);
|
||||
result.push(ctrKeyword);
|
||||
}
|
||||
|
||||
forEachProperty(classSymbol.exports, member => {
|
||||
const decl = member.valueDeclaration;
|
||||
if (decl && decl.kind === SyntaxKind.MethodDeclaration) {
|
||||
const body = (<MethodDeclaration>decl).body;
|
||||
if (body) {
|
||||
forEachDescendantOfKind(body, SyntaxKind.ThisKeyword, thisKeyword => {
|
||||
if (isNewExpressionTarget(thisKeyword)) {
|
||||
result.push(thisKeyword);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Find references to `super` in the constructor of an extending class. */
|
||||
function superConstructorAccesses(cls: ClassLikeDeclaration): Node[] {
|
||||
const symbol = cls.symbol;
|
||||
const ctr = symbol.members["__constructor"];
|
||||
if (!ctr) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const result: Node[] = [];
|
||||
for (const decl of ctr.declarations) {
|
||||
Debug.assert(decl.kind === SyntaxKind.Constructor);
|
||||
const body = (<ConstructorDeclaration>decl).body;
|
||||
if (body) {
|
||||
forEachDescendantOfKind(body, SyntaxKind.SuperKeyword, node => {
|
||||
if (isCallExpressionTarget(node)) {
|
||||
result.push(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
function getReferencedSymbol(symbol: Symbol): ReferencedSymbol {
|
||||
const symbolId = getSymbolId(symbol);
|
||||
let index = symbolToIndex[symbolId];
|
||||
@ -6536,6 +6698,11 @@ namespace ts {
|
||||
getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, references);
|
||||
}
|
||||
|
||||
const thisOrSuperSymbol = typeChecker.getSymbolAtLocation(thisOrSuperKeyword);
|
||||
|
||||
const displayParts = thisOrSuperSymbol && getSymbolDisplayPartsDocumentationAndSymbolKind(
|
||||
thisOrSuperSymbol, thisOrSuperKeyword.getSourceFile(), getContainerNode(thisOrSuperKeyword), thisOrSuperKeyword).displayParts;
|
||||
|
||||
return [{
|
||||
definition: {
|
||||
containerKind: "",
|
||||
@ -6543,7 +6710,8 @@ namespace ts {
|
||||
fileName: node.getSourceFile().fileName,
|
||||
kind: ScriptElementKind.variableElement,
|
||||
name: "this",
|
||||
textSpan: createTextSpanFromBounds(node.getStart(), node.getEnd())
|
||||
textSpan: createTextSpanFromBounds(node.getStart(), node.getEnd()),
|
||||
displayParts
|
||||
},
|
||||
references: references
|
||||
}];
|
||||
@ -6614,7 +6782,8 @@ namespace ts {
|
||||
fileName: node.getSourceFile().fileName,
|
||||
kind: ScriptElementKind.variableElement,
|
||||
name: type.text,
|
||||
textSpan: createTextSpanFromBounds(node.getStart(), node.getEnd())
|
||||
textSpan: createTextSpanFromBounds(node.getStart(), node.getEnd()),
|
||||
displayParts: [displayPart(getTextOfNode(node), SymbolDisplayPartKind.stringLiteral)]
|
||||
},
|
||||
references: references
|
||||
}];
|
||||
@ -6783,16 +6952,17 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getRelatedSymbol(searchSymbols: Symbol[], referenceSymbol: Symbol, referenceLocation: Node): Symbol {
|
||||
if (searchSymbols.indexOf(referenceSymbol) >= 0) {
|
||||
return referenceSymbol;
|
||||
function getRelatedSymbol(searchSymbols: Symbol[], referenceSymbol: Symbol, referenceLocation: Node, searchLocationIsConstructor: boolean): Symbol | undefined {
|
||||
if (contains(searchSymbols, referenceSymbol)) {
|
||||
// If we are searching for constructor uses, they must be 'new' expressions.
|
||||
return (!searchLocationIsConstructor || isNewExpressionTarget(referenceLocation)) && referenceSymbol;
|
||||
}
|
||||
|
||||
// If the reference symbol is an alias, check if what it is aliasing is one of the search
|
||||
// symbols but by looking up for related symbol of this alias so it can handle multiple level of indirectness.
|
||||
const aliasSymbol = getAliasSymbolForPropertyNameSymbol(referenceSymbol, referenceLocation);
|
||||
if (aliasSymbol) {
|
||||
return getRelatedSymbol(searchSymbols, aliasSymbol, referenceLocation);
|
||||
return getRelatedSymbol(searchSymbols, aliasSymbol, referenceLocation, searchLocationIsConstructor);
|
||||
}
|
||||
|
||||
// If the reference location is in an object literal, try to get the contextual type for the
|
||||
@ -7573,6 +7743,10 @@ namespace ts {
|
||||
* False will mean that node is not classified and traverse routine should recurse into node contents.
|
||||
*/
|
||||
function tryClassifyNode(node: Node): boolean {
|
||||
if (isJSDocTag(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nodeIsMissing(node)) {
|
||||
return true;
|
||||
}
|
||||
@ -8312,6 +8486,15 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function forEachDescendantOfKind(node: Node, kind: SyntaxKind, action: (node: Node) => void) {
|
||||
forEachChild(node, child => {
|
||||
if (child.kind === kind) {
|
||||
action(child);
|
||||
}
|
||||
forEachDescendantOfKind(child, kind, action);
|
||||
});
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function getNameTable(sourceFile: SourceFile): Map<number> {
|
||||
if (!sourceFile.nameTable) {
|
||||
|
||||
@ -1203,6 +1203,6 @@ namespace TypeScript.Services {
|
||||
// TODO: it should be moved into a namespace though.
|
||||
|
||||
/* @internal */
|
||||
const toolsVersion = "1.9";
|
||||
const toolsVersion = "2.1";
|
||||
|
||||
/* tslint:enable:no-unused-variable */
|
||||
|
||||
@ -925,4 +925,25 @@ namespace ts {
|
||||
}
|
||||
return ensureScriptKind(fileName, scriptKind);
|
||||
}
|
||||
|
||||
export function parseAndReEmitConfigJSONFile(content: string) {
|
||||
const options: TranspileOptions = {
|
||||
fileName: "config.js",
|
||||
compilerOptions: {
|
||||
target: ScriptTarget.ES6,
|
||||
removeComments: true
|
||||
},
|
||||
reportDiagnostics: true
|
||||
};
|
||||
const { outputText, diagnostics } = ts.transpileModule("(" + content + ")", options);
|
||||
// Becasue the content was wrapped in "()", the start position of diagnostics needs to be subtract by 1
|
||||
// also, the emitted result will have "(" in the beginning and ");" in the end. We need to strip these
|
||||
// as well
|
||||
const trimmedOutput = outputText.trim();
|
||||
const configJsonObject = JSON.parse(trimmedOutput.substring(1, trimmedOutput.length - 2));
|
||||
for (const diagnostic of diagnostics) {
|
||||
diagnostic.start = diagnostic.start - 1;
|
||||
}
|
||||
return { configJsonObject, diagnostics };
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtyping.ts(9,7): error TS2415: Class 'Derived<U>' incorrectly extends base class 'Base<string>'.
|
||||
Types of property 'x' are incompatible.
|
||||
Type 'String' is not assignable to type 'string'.
|
||||
'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtyping.ts (1 errors) ====
|
||||
@ -17,6 +18,7 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtypi
|
||||
!!! error TS2415: Class 'Derived<U>' incorrectly extends base class 'Base<string>'.
|
||||
!!! error TS2415: Types of property 'x' are incompatible.
|
||||
!!! error TS2415: Type 'String' is not assignable to type 'string'.
|
||||
!!! error TS2415: 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible.
|
||||
x: String;
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSuperty
|
||||
Types of property 'x' are incompatible.
|
||||
Type 'U' is not assignable to type 'string'.
|
||||
Type 'String' is not assignable to type 'string'.
|
||||
'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSupertype.ts (1 errors) ====
|
||||
@ -19,5 +20,6 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSuperty
|
||||
!!! error TS2415: Types of property 'x' are incompatible.
|
||||
!!! error TS2415: Type 'U' is not assignable to type 'string'.
|
||||
!!! error TS2415: Type 'String' is not assignable to type 'string'.
|
||||
!!! error TS2415: 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible.
|
||||
x: U;
|
||||
}
|
||||
@ -39,8 +39,7 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(26,5): error
|
||||
tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(27,5): error TS2322: Type '{ 0: string; 1: number; }' is not assignable to type '[string]'.
|
||||
Property 'length' is missing in type '{ 0: string; 1: number; }'.
|
||||
tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(28,5): error TS2322: Type '[string, number]' is not assignable to type '[number, string]'.
|
||||
Types of property '0' are incompatible.
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(29,5): error TS2322: Type 'StrNum' is not assignable to type '[number, string]'.
|
||||
Types of property '0' are incompatible.
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
@ -136,8 +135,7 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error
|
||||
var n1: [number, string] = x;
|
||||
~~
|
||||
!!! error TS2322: Type '[string, number]' is not assignable to type '[number, string]'.
|
||||
!!! error TS2322: Types of property '0' are incompatible.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
var n2: [number, string] = y;
|
||||
~~
|
||||
!!! error TS2322: Type 'StrNum' is not assignable to type '[number, string]'.
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(10,5): error TS2322: Type 'undefined[]' is not assignable to type '[any, any, any]'.
|
||||
Property '0' is missing in type 'undefined[]'.
|
||||
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(11,5): error TS2322: Type '[string, number, boolean]' is not assignable to type '[boolean, string, number]'.
|
||||
Types of property '0' are incompatible.
|
||||
Type 'string' is not assignable to type 'boolean'.
|
||||
Type 'string' is not assignable to type 'boolean'.
|
||||
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(17,5): error TS2322: Type '[number, number, string, boolean]' is not assignable to type '[number, number]'.
|
||||
Types of property 'pop' are incompatible.
|
||||
Type '() => string | number | boolean' is not assignable to type '() => number'.
|
||||
@ -18,6 +17,7 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error
|
||||
Types of parameters 'items' and 'items' are incompatible.
|
||||
Type 'Number' is not assignable to type 'string | number'.
|
||||
Type 'Number' is not assignable to type 'number'.
|
||||
'number' is a primitive, but 'Number' is a wrapper object. Prefer using 'number' when possible.
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts (6 errors) ====
|
||||
@ -37,8 +37,7 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error
|
||||
var a1: [boolean, string, number] = ["string", 1, true]; // Error
|
||||
~~
|
||||
!!! error TS2322: Type '[string, number, boolean]' is not assignable to type '[boolean, string, number]'.
|
||||
!!! error TS2322: Types of property '0' are incompatible.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'boolean'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'boolean'.
|
||||
|
||||
// The resulting type an array literal expression is determined as follows:
|
||||
// - If the array literal contains no spread elements and is an array assignment pattern in a destructuring assignment (section 4.17.1),
|
||||
@ -81,4 +80,5 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error
|
||||
!!! error TS2322: Types of parameters 'items' and 'items' are incompatible.
|
||||
!!! error TS2322: Type 'Number' is not assignable to type 'string | number'.
|
||||
!!! error TS2322: Type 'Number' is not assignable to type 'number'.
|
||||
!!! error TS2322: 'number' is a primitive, but 'Number' is a wrapper object. Prefer using 'number' when possible.
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface.ts(3,1): error TS2322: Type 'Boolean' is not assignable to type 'boolean'.
|
||||
'boolean' is a primitive, but 'Boolean' is a wrapper object. Prefer using 'boolean' when possible.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface.ts (1 errors) ====
|
||||
@ -7,4 +8,5 @@ tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface.ts(3
|
||||
x = a;
|
||||
~
|
||||
!!! error TS2322: Type 'Boolean' is not assignable to type 'boolean'.
|
||||
!!! error TS2322: 'boolean' is a primitive, but 'Boolean' is a wrapper object. Prefer using 'boolean' when possible.
|
||||
a = x;
|
||||
@ -3,6 +3,7 @@ tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface2.ts(
|
||||
Type '() => Object' is not assignable to type '() => boolean'.
|
||||
Type 'Object' is not assignable to type 'boolean'.
|
||||
tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface2.ts(19,1): error TS2322: Type 'Boolean' is not assignable to type 'boolean'.
|
||||
'boolean' is a primitive, but 'Boolean' is a wrapper object. Prefer using 'boolean' when possible.
|
||||
tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface2.ts(20,1): error TS2322: Type 'NotBoolean' is not assignable to type 'boolean'.
|
||||
|
||||
|
||||
@ -33,6 +34,7 @@ tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface2.ts(
|
||||
x = a; // expected error
|
||||
~
|
||||
!!! error TS2322: Type 'Boolean' is not assignable to type 'boolean'.
|
||||
!!! error TS2322: 'boolean' is a primitive, but 'Boolean' is a wrapper object. Prefer using 'boolean' when possible.
|
||||
x = b; // expected error
|
||||
~
|
||||
!!! error TS2322: Type 'NotBoolean' is not assignable to type 'boolean'.
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
tests/cases/conformance/types/primitives/number/assignFromNumberInterface.ts(3,1): error TS2322: Type 'Number' is not assignable to type 'number'.
|
||||
'number' is a primitive, but 'Number' is a wrapper object. Prefer using 'number' when possible.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/primitives/number/assignFromNumberInterface.ts (1 errors) ====
|
||||
@ -7,4 +8,5 @@ tests/cases/conformance/types/primitives/number/assignFromNumberInterface.ts(3,1
|
||||
x = a;
|
||||
~
|
||||
!!! error TS2322: Type 'Number' is not assignable to type 'number'.
|
||||
!!! error TS2322: 'number' is a primitive, but 'Number' is a wrapper object. Prefer using 'number' when possible.
|
||||
a = x;
|
||||
@ -1,4 +1,5 @@
|
||||
tests/cases/conformance/types/primitives/number/assignFromNumberInterface2.ts(24,1): error TS2322: Type 'Number' is not assignable to type 'number'.
|
||||
'number' is a primitive, but 'Number' is a wrapper object. Prefer using 'number' when possible.
|
||||
tests/cases/conformance/types/primitives/number/assignFromNumberInterface2.ts(25,1): error TS2322: Type 'NotNumber' is not assignable to type 'number'.
|
||||
|
||||
|
||||
@ -29,6 +30,7 @@ tests/cases/conformance/types/primitives/number/assignFromNumberInterface2.ts(25
|
||||
x = a; // expected error
|
||||
~
|
||||
!!! error TS2322: Type 'Number' is not assignable to type 'number'.
|
||||
!!! error TS2322: 'number' is a primitive, but 'Number' is a wrapper object. Prefer using 'number' when possible.
|
||||
x = b; // expected error
|
||||
~
|
||||
!!! error TS2322: Type 'NotNumber' is not assignable to type 'number'.
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
tests/cases/conformance/types/primitives/string/assignFromStringInterface.ts(3,1): error TS2322: Type 'String' is not assignable to type 'string'.
|
||||
'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/primitives/string/assignFromStringInterface.ts (1 errors) ====
|
||||
@ -7,4 +8,5 @@ tests/cases/conformance/types/primitives/string/assignFromStringInterface.ts(3,1
|
||||
x = a;
|
||||
~
|
||||
!!! error TS2322: Type 'String' is not assignable to type 'string'.
|
||||
!!! error TS2322: 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible.
|
||||
a = x;
|
||||
@ -1,4 +1,5 @@
|
||||
tests/cases/conformance/types/primitives/string/assignFromStringInterface2.ts(47,1): error TS2322: Type 'String' is not assignable to type 'string'.
|
||||
'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible.
|
||||
tests/cases/conformance/types/primitives/string/assignFromStringInterface2.ts(48,1): error TS2322: Type 'NotString' is not assignable to type 'string'.
|
||||
|
||||
|
||||
@ -52,6 +53,7 @@ tests/cases/conformance/types/primitives/string/assignFromStringInterface2.ts(48
|
||||
x = a; // expected error
|
||||
~
|
||||
!!! error TS2322: Type 'String' is not assignable to type 'string'.
|
||||
!!! error TS2322: 'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible.
|
||||
x = b; // expected error
|
||||
~
|
||||
!!! error TS2322: Type 'NotString' is not assignable to type 'string'.
|
||||
|
||||
47
tests/baselines/reference/await_unaryExpression_es6.js
Normal file
47
tests/baselines/reference/await_unaryExpression_es6.js
Normal file
@ -0,0 +1,47 @@
|
||||
//// [await_unaryExpression_es6.ts]
|
||||
|
||||
async function bar() {
|
||||
!await 42; // OK
|
||||
}
|
||||
|
||||
async function bar1() {
|
||||
+await 42; // OK
|
||||
}
|
||||
|
||||
async function bar3() {
|
||||
-await 42; // OK
|
||||
}
|
||||
|
||||
async function bar4() {
|
||||
~await 42; // OK
|
||||
}
|
||||
|
||||
//// [await_unaryExpression_es6.js]
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments)).next());
|
||||
});
|
||||
};
|
||||
function bar() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
!(yield 42); // OK
|
||||
});
|
||||
}
|
||||
function bar1() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
+(yield 42); // OK
|
||||
});
|
||||
}
|
||||
function bar3() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
-(yield 42); // OK
|
||||
});
|
||||
}
|
||||
function bar4() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
~(yield 42); // OK
|
||||
});
|
||||
}
|
||||
25
tests/baselines/reference/await_unaryExpression_es6.symbols
Normal file
25
tests/baselines/reference/await_unaryExpression_es6.symbols
Normal file
@ -0,0 +1,25 @@
|
||||
=== tests/cases/conformance/async/es6/await_unaryExpression_es6.ts ===
|
||||
|
||||
async function bar() {
|
||||
>bar : Symbol(bar, Decl(await_unaryExpression_es6.ts, 0, 0))
|
||||
|
||||
!await 42; // OK
|
||||
}
|
||||
|
||||
async function bar1() {
|
||||
>bar1 : Symbol(bar1, Decl(await_unaryExpression_es6.ts, 3, 1))
|
||||
|
||||
+await 42; // OK
|
||||
}
|
||||
|
||||
async function bar3() {
|
||||
>bar3 : Symbol(bar3, Decl(await_unaryExpression_es6.ts, 7, 1))
|
||||
|
||||
-await 42; // OK
|
||||
}
|
||||
|
||||
async function bar4() {
|
||||
>bar4 : Symbol(bar4, Decl(await_unaryExpression_es6.ts, 11, 1))
|
||||
|
||||
~await 42; // OK
|
||||
}
|
||||
37
tests/baselines/reference/await_unaryExpression_es6.types
Normal file
37
tests/baselines/reference/await_unaryExpression_es6.types
Normal file
@ -0,0 +1,37 @@
|
||||
=== tests/cases/conformance/async/es6/await_unaryExpression_es6.ts ===
|
||||
|
||||
async function bar() {
|
||||
>bar : () => Promise<void>
|
||||
|
||||
!await 42; // OK
|
||||
>!await 42 : boolean
|
||||
>await 42 : number
|
||||
>42 : number
|
||||
}
|
||||
|
||||
async function bar1() {
|
||||
>bar1 : () => Promise<void>
|
||||
|
||||
+await 42; // OK
|
||||
>+await 42 : number
|
||||
>await 42 : number
|
||||
>42 : number
|
||||
}
|
||||
|
||||
async function bar3() {
|
||||
>bar3 : () => Promise<void>
|
||||
|
||||
-await 42; // OK
|
||||
>-await 42 : number
|
||||
>await 42 : number
|
||||
>42 : number
|
||||
}
|
||||
|
||||
async function bar4() {
|
||||
>bar4 : () => Promise<void>
|
||||
|
||||
~await 42; // OK
|
||||
>~await 42 : number
|
||||
>await 42 : number
|
||||
>42 : number
|
||||
}
|
||||
56
tests/baselines/reference/await_unaryExpression_es6_1.js
Normal file
56
tests/baselines/reference/await_unaryExpression_es6_1.js
Normal file
@ -0,0 +1,56 @@
|
||||
//// [await_unaryExpression_es6_1.ts]
|
||||
|
||||
async function bar() {
|
||||
!await 42; // OK
|
||||
}
|
||||
|
||||
async function bar1() {
|
||||
delete await 42; // OK
|
||||
}
|
||||
|
||||
async function bar2() {
|
||||
delete await 42; // OK
|
||||
}
|
||||
|
||||
async function bar3() {
|
||||
void await 42;
|
||||
}
|
||||
|
||||
async function bar4() {
|
||||
+await 42;
|
||||
}
|
||||
|
||||
//// [await_unaryExpression_es6_1.js]
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments)).next());
|
||||
});
|
||||
};
|
||||
function bar() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
!(yield 42); // OK
|
||||
});
|
||||
}
|
||||
function bar1() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
delete (yield 42); // OK
|
||||
});
|
||||
}
|
||||
function bar2() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
delete (yield 42); // OK
|
||||
});
|
||||
}
|
||||
function bar3() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
void (yield 42);
|
||||
});
|
||||
}
|
||||
function bar4() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
+(yield 42);
|
||||
});
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
=== tests/cases/conformance/async/es6/await_unaryExpression_es6_1.ts ===
|
||||
|
||||
async function bar() {
|
||||
>bar : Symbol(bar, Decl(await_unaryExpression_es6_1.ts, 0, 0))
|
||||
|
||||
!await 42; // OK
|
||||
}
|
||||
|
||||
async function bar1() {
|
||||
>bar1 : Symbol(bar1, Decl(await_unaryExpression_es6_1.ts, 3, 1))
|
||||
|
||||
delete await 42; // OK
|
||||
}
|
||||
|
||||
async function bar2() {
|
||||
>bar2 : Symbol(bar2, Decl(await_unaryExpression_es6_1.ts, 7, 1))
|
||||
|
||||
delete await 42; // OK
|
||||
}
|
||||
|
||||
async function bar3() {
|
||||
>bar3 : Symbol(bar3, Decl(await_unaryExpression_es6_1.ts, 11, 1))
|
||||
|
||||
void await 42;
|
||||
}
|
||||
|
||||
async function bar4() {
|
||||
>bar4 : Symbol(bar4, Decl(await_unaryExpression_es6_1.ts, 15, 1))
|
||||
|
||||
+await 42;
|
||||
}
|
||||
46
tests/baselines/reference/await_unaryExpression_es6_1.types
Normal file
46
tests/baselines/reference/await_unaryExpression_es6_1.types
Normal file
@ -0,0 +1,46 @@
|
||||
=== tests/cases/conformance/async/es6/await_unaryExpression_es6_1.ts ===
|
||||
|
||||
async function bar() {
|
||||
>bar : () => Promise<void>
|
||||
|
||||
!await 42; // OK
|
||||
>!await 42 : boolean
|
||||
>await 42 : number
|
||||
>42 : number
|
||||
}
|
||||
|
||||
async function bar1() {
|
||||
>bar1 : () => Promise<void>
|
||||
|
||||
delete await 42; // OK
|
||||
>delete await 42 : boolean
|
||||
>await 42 : number
|
||||
>42 : number
|
||||
}
|
||||
|
||||
async function bar2() {
|
||||
>bar2 : () => Promise<void>
|
||||
|
||||
delete await 42; // OK
|
||||
>delete await 42 : boolean
|
||||
>await 42 : number
|
||||
>42 : number
|
||||
}
|
||||
|
||||
async function bar3() {
|
||||
>bar3 : () => Promise<void>
|
||||
|
||||
void await 42;
|
||||
>void await 42 : undefined
|
||||
>await 42 : number
|
||||
>42 : number
|
||||
}
|
||||
|
||||
async function bar4() {
|
||||
>bar4 : () => Promise<void>
|
||||
|
||||
+await 42;
|
||||
>+await 42 : number
|
||||
>await 42 : number
|
||||
>42 : number
|
||||
}
|
||||
38
tests/baselines/reference/await_unaryExpression_es6_2.js
Normal file
38
tests/baselines/reference/await_unaryExpression_es6_2.js
Normal file
@ -0,0 +1,38 @@
|
||||
//// [await_unaryExpression_es6_2.ts]
|
||||
|
||||
async function bar1() {
|
||||
delete await 42;
|
||||
}
|
||||
|
||||
async function bar2() {
|
||||
delete await 42;
|
||||
}
|
||||
|
||||
async function bar3() {
|
||||
void await 42;
|
||||
}
|
||||
|
||||
//// [await_unaryExpression_es6_2.js]
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments)).next());
|
||||
});
|
||||
};
|
||||
function bar1() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
delete (yield 42);
|
||||
});
|
||||
}
|
||||
function bar2() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
delete (yield 42);
|
||||
});
|
||||
}
|
||||
function bar3() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
void (yield 42);
|
||||
});
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
=== tests/cases/conformance/async/es6/await_unaryExpression_es6_2.ts ===
|
||||
|
||||
async function bar1() {
|
||||
>bar1 : Symbol(bar1, Decl(await_unaryExpression_es6_2.ts, 0, 0))
|
||||
|
||||
delete await 42;
|
||||
}
|
||||
|
||||
async function bar2() {
|
||||
>bar2 : Symbol(bar2, Decl(await_unaryExpression_es6_2.ts, 3, 1))
|
||||
|
||||
delete await 42;
|
||||
}
|
||||
|
||||
async function bar3() {
|
||||
>bar3 : Symbol(bar3, Decl(await_unaryExpression_es6_2.ts, 7, 1))
|
||||
|
||||
void await 42;
|
||||
}
|
||||
28
tests/baselines/reference/await_unaryExpression_es6_2.types
Normal file
28
tests/baselines/reference/await_unaryExpression_es6_2.types
Normal file
@ -0,0 +1,28 @@
|
||||
=== tests/cases/conformance/async/es6/await_unaryExpression_es6_2.ts ===
|
||||
|
||||
async function bar1() {
|
||||
>bar1 : () => Promise<void>
|
||||
|
||||
delete await 42;
|
||||
>delete await 42 : boolean
|
||||
>await 42 : number
|
||||
>42 : number
|
||||
}
|
||||
|
||||
async function bar2() {
|
||||
>bar2 : () => Promise<void>
|
||||
|
||||
delete await 42;
|
||||
>delete await 42 : boolean
|
||||
>await 42 : number
|
||||
>42 : number
|
||||
}
|
||||
|
||||
async function bar3() {
|
||||
>bar3 : () => Promise<void>
|
||||
|
||||
void await 42;
|
||||
>void await 42 : undefined
|
||||
>await 42 : number
|
||||
>42 : number
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
tests/cases/conformance/async/es6/await_unaryExpression_es6_3.ts(3,7): error TS1109: Expression expected.
|
||||
tests/cases/conformance/async/es6/await_unaryExpression_es6_3.ts(7,7): error TS1109: Expression expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/async/es6/await_unaryExpression_es6_3.ts (2 errors) ====
|
||||
|
||||
async function bar1() {
|
||||
++await 42; // Error
|
||||
~~~~~
|
||||
!!! error TS1109: Expression expected.
|
||||
}
|
||||
|
||||
async function bar2() {
|
||||
--await 42; // Error
|
||||
~~~~~
|
||||
!!! error TS1109: Expression expected.
|
||||
}
|
||||
|
||||
async function bar3() {
|
||||
var x = 42;
|
||||
await x++; // OK but shouldn't need parenthesis
|
||||
}
|
||||
|
||||
async function bar4() {
|
||||
var x = 42;
|
||||
await x--; // OK but shouldn't need parenthesis
|
||||
}
|
||||
53
tests/baselines/reference/await_unaryExpression_es6_3.js
Normal file
53
tests/baselines/reference/await_unaryExpression_es6_3.js
Normal file
@ -0,0 +1,53 @@
|
||||
//// [await_unaryExpression_es6_3.ts]
|
||||
|
||||
async function bar1() {
|
||||
++await 42; // Error
|
||||
}
|
||||
|
||||
async function bar2() {
|
||||
--await 42; // Error
|
||||
}
|
||||
|
||||
async function bar3() {
|
||||
var x = 42;
|
||||
await x++; // OK but shouldn't need parenthesis
|
||||
}
|
||||
|
||||
async function bar4() {
|
||||
var x = 42;
|
||||
await x--; // OK but shouldn't need parenthesis
|
||||
}
|
||||
|
||||
//// [await_unaryExpression_es6_3.js]
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments)).next());
|
||||
});
|
||||
};
|
||||
function bar1() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
++;
|
||||
yield 42; // Error
|
||||
});
|
||||
}
|
||||
function bar2() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
--;
|
||||
yield 42; // Error
|
||||
});
|
||||
}
|
||||
function bar3() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
var x = 42;
|
||||
yield x++; // OK but shouldn't need parenthesis
|
||||
});
|
||||
}
|
||||
function bar4() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
var x = 42;
|
||||
yield x--; // OK but shouldn't need parenthesis
|
||||
});
|
||||
}
|
||||
@ -20,9 +20,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
function f() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield 0;
|
||||
typeof yield 0;
|
||||
void yield 0;
|
||||
yield void typeof void yield 0;
|
||||
typeof (yield 0);
|
||||
void (yield 0);
|
||||
yield void typeof void (yield 0);
|
||||
yield yield 0;
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
tests/cases/conformance/types/tuple/castingTuple.ts(28,10): error TS2352: Type '[number, string]' cannot be converted to type '[number, number]'.
|
||||
Types of property '1' are incompatible.
|
||||
Type 'string' is not comparable to type 'number'.
|
||||
Type 'string' is not comparable to type 'number'.
|
||||
tests/cases/conformance/types/tuple/castingTuple.ts(29,10): error TS2352: Type '[C, D]' cannot be converted to type '[A, I]'.
|
||||
Types of property '0' are incompatible.
|
||||
Type 'C' is not comparable to type 'A'.
|
||||
Property 'a' is missing in type 'C'.
|
||||
Type 'C' is not comparable to type 'A'.
|
||||
Property 'a' is missing in type 'C'.
|
||||
tests/cases/conformance/types/tuple/castingTuple.ts(30,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' must be of type '{}[]', but here has type 'number[]'.
|
||||
tests/cases/conformance/types/tuple/castingTuple.ts(31,1): error TS2304: Cannot find name 't4'.
|
||||
|
||||
@ -40,14 +38,12 @@ tests/cases/conformance/types/tuple/castingTuple.ts(31,1): error TS2304: Cannot
|
||||
var t3 = <[number, number]>numStrTuple;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2352: Type '[number, string]' cannot be converted to type '[number, number]'.
|
||||
!!! error TS2352: Types of property '1' are incompatible.
|
||||
!!! error TS2352: Type 'string' is not comparable to type 'number'.
|
||||
!!! error TS2352: Type 'string' is not comparable to type 'number'.
|
||||
var t9 = <[A, I]>classCDTuple;
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2352: Type '[C, D]' cannot be converted to type '[A, I]'.
|
||||
!!! error TS2352: Types of property '0' are incompatible.
|
||||
!!! error TS2352: Type 'C' is not comparable to type 'A'.
|
||||
!!! error TS2352: Property 'a' is missing in type 'C'.
|
||||
!!! error TS2352: Type 'C' is not comparable to type 'A'.
|
||||
!!! error TS2352: Property 'a' is missing in type 'C'.
|
||||
var array1 = <number[]>numStrTuple;
|
||||
~~~~~~
|
||||
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' must be of type '{}[]', but here has type 'number[]'.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user