mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-14 19:16:17 -06:00
Merge branch 'master' into no_ts_extension
This commit is contained in:
commit
297cb50cbf
210
Gulpfile.ts
210
Gulpfile.ts
@ -17,7 +17,7 @@ declare module "gulp-typescript" {
|
||||
stripInternal?: boolean;
|
||||
types?: string[];
|
||||
}
|
||||
interface CompileStream extends NodeJS.ReadWriteStream {} // Either gulp or gulp-typescript has some odd typings which don't reflect reality, making this required
|
||||
interface CompileStream extends NodeJS.ReadWriteStream { } // Either gulp or gulp-typescript has some odd typings which don't reflect reality, making this required
|
||||
}
|
||||
import * as insert from "gulp-insert";
|
||||
import * as sourcemaps from "gulp-sourcemaps";
|
||||
@ -34,7 +34,6 @@ import through2 = require("through2");
|
||||
import merge2 = require("merge2");
|
||||
import intoStream = require("into-stream");
|
||||
import * as os from "os";
|
||||
import Linter = require("tslint");
|
||||
import fold = require("travis-fold");
|
||||
const gulp = helpMaker(originalGulp);
|
||||
const mochaParallel = require("./scripts/mocha-parallel.js");
|
||||
@ -66,7 +65,7 @@ const cmdLineOptions = minimist(process.argv.slice(2), {
|
||||
}
|
||||
});
|
||||
|
||||
function exec(cmd: string, args: string[], complete: () => void = (() => {}), error: (e: any, status: number) => void = (() => {})) {
|
||||
function exec(cmd: string, args: string[], complete: () => void = (() => { }), error: (e: any, status: number) => void = (() => { })) {
|
||||
console.log(`${cmd} ${args.join(" ")}`);
|
||||
// TODO (weswig): Update child_process types to add windowsVerbatimArguments to the type definition
|
||||
const subshellFlag = isWin ? "/c" : "-c";
|
||||
@ -117,12 +116,12 @@ const es2015LibrarySources = [
|
||||
];
|
||||
|
||||
const es2015LibrarySourceMap = es2015LibrarySources.map(function(source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
});
|
||||
|
||||
const es2016LibrarySource = [ "es2016.array.include.d.ts" ];
|
||||
const es2016LibrarySource = ["es2016.array.include.d.ts"];
|
||||
|
||||
const es2016LibrarySourceMap = es2016LibrarySource.map(function (source) {
|
||||
const es2016LibrarySourceMap = es2016LibrarySource.map(function(source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
});
|
||||
|
||||
@ -131,38 +130,38 @@ const es2017LibrarySource = [
|
||||
"es2017.sharedmemory.d.ts"
|
||||
];
|
||||
|
||||
const es2017LibrarySourceMap = es2017LibrarySource.map(function (source) {
|
||||
const es2017LibrarySourceMap = es2017LibrarySource.map(function(source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
});
|
||||
|
||||
const hostsLibrarySources = ["dom.generated.d.ts", "webworker.importscripts.d.ts", "scripthost.d.ts"];
|
||||
|
||||
const 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);
|
||||
|
||||
const libraryTargets = librarySourceMap.map(function (f) {
|
||||
const libraryTargets = librarySourceMap.map(function(f) {
|
||||
return path.join(builtLocalDirectory, f.target);
|
||||
});
|
||||
|
||||
for (const i in libraryTargets) {
|
||||
const entry = librarySourceMap[i];
|
||||
const target = libraryTargets[i];
|
||||
const sources = [copyright].concat(entry.sources.map(function (s) {
|
||||
const sources = [copyright].concat(entry.sources.map(function(s) {
|
||||
return path.join(libraryDirectory, s);
|
||||
}));
|
||||
gulp.task(target, false, [], function() {
|
||||
@ -392,7 +391,7 @@ gulp.task(servicesFile, false, ["lib", "generate-diagnostics"], () => {
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(tsc(servicesProject));
|
||||
const completedJs = js.pipe(prependCopyright())
|
||||
.pipe(sourcemaps.write("."));
|
||||
.pipe(sourcemaps.write("."));
|
||||
const completedDts = dts.pipe(prependCopyright(/*outputCopyright*/true))
|
||||
.pipe(insert.transform((contents, file) => {
|
||||
file.path = standaloneDefinitionsFile;
|
||||
@ -435,17 +434,17 @@ const tsserverLibraryDefinitionFile = path.join(builtLocalDirectory, "tsserverli
|
||||
|
||||
gulp.task(tsserverLibraryFile, false, [servicesFile], (done) => {
|
||||
const serverLibraryProject = tsc.createProject("src/server/tsconfig.library.json", getCompilerSettings({}, /*useBuiltCompiler*/ true));
|
||||
const {js, dts}: {js: NodeJS.ReadableStream, dts: NodeJS.ReadableStream} = serverLibraryProject.src()
|
||||
const {js, dts}: { js: NodeJS.ReadableStream, dts: NodeJS.ReadableStream } = serverLibraryProject.src()
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(newer(tsserverLibraryFile))
|
||||
.pipe(tsc(serverLibraryProject));
|
||||
|
||||
return merge2([
|
||||
js.pipe(prependCopyright())
|
||||
.pipe(sourcemaps.write("."))
|
||||
.pipe(gulp.dest(builtLocalDirectory)),
|
||||
.pipe(sourcemaps.write("."))
|
||||
.pipe(gulp.dest(builtLocalDirectory)),
|
||||
dts.pipe(prependCopyright())
|
||||
.pipe(gulp.dest(builtLocalDirectory))
|
||||
.pipe(gulp.dest(builtLocalDirectory))
|
||||
]);
|
||||
});
|
||||
|
||||
@ -477,7 +476,7 @@ gulp.task(specMd, false, [word2mdJs], (done) => {
|
||||
const specMDFullPath = path.resolve(specMd);
|
||||
const cmd = "cscript //nologo " + word2mdJs + " \"" + specWordFullPath + "\" " + "\"" + specMDFullPath + "\"";
|
||||
console.log(cmd);
|
||||
cp.exec(cmd, function () {
|
||||
cp.exec(cmd, function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
@ -493,12 +492,12 @@ gulp.task("dontUseDebugMode", false, [], (done) => { useDebugMode = false; done(
|
||||
|
||||
gulp.task("VerifyLKG", false, [], () => {
|
||||
const expectedFiles = [builtLocalCompiler, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile].concat(libraryTargets);
|
||||
const missingFiles = expectedFiles.filter(function (f) {
|
||||
const missingFiles = expectedFiles.filter(function(f) {
|
||||
return !fs.existsSync(f);
|
||||
});
|
||||
if (missingFiles.length > 0) {
|
||||
throw new Error("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
|
||||
return gulp.src(expectedFiles).pipe(gulp.dest(LKGDirectory));
|
||||
@ -532,8 +531,6 @@ const localRwcBaseline = path.join(internalTests, "baselines/rwc/local");
|
||||
const refRwcBaseline = path.join(internalTests, "baselines/rwc/reference");
|
||||
|
||||
const localTest262Baseline = path.join(internalTests, "baselines/test262/local");
|
||||
const refTest262Baseline = path.join(internalTests, "baselines/test262/reference");
|
||||
|
||||
|
||||
gulp.task("tests", "Builds the test infrastructure using the built compiler", [run]);
|
||||
gulp.task("tests-debug", "Builds the test sources and automation in debug mode", () => {
|
||||
@ -628,7 +625,7 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
||||
}
|
||||
args.push(run);
|
||||
setNodeEnvToDevelopment();
|
||||
runTestsInParallel(taskConfigsFolder, run, { testTimeout: testTimeout, noColors: colors === " --no-colors " }, function (err) {
|
||||
runTestsInParallel(taskConfigsFolder, run, { testTimeout: testTimeout, noColors: colors === " --no-colors " }, function(err) {
|
||||
// last worker clean everything and runs linter in case if there were no errors
|
||||
del(taskConfigsFolder).then(() => {
|
||||
if (!err) {
|
||||
@ -680,7 +677,7 @@ gulp.task("runtests",
|
||||
["build-rules", "tests"],
|
||||
(done) => {
|
||||
runConsoleTests("mocha-fivemat-progress-reporter", /*runInParallel*/ false, done);
|
||||
});
|
||||
});
|
||||
|
||||
const nodeServerOutFile = "tests/webTestServer.js";
|
||||
const nodeServerInFile = "tests/webTestServer.ts";
|
||||
@ -812,32 +809,36 @@ gulp.task("diff-rwc", "Diffs the RWC baselines using the diff tool specified by
|
||||
exec(getDiffTool(), [refRwcBaseline, localRwcBaseline], done, done);
|
||||
});
|
||||
|
||||
gulp.task("baseline-accept", "Makes the most recent test results the new baseline, overwriting the old baseline", () => {
|
||||
return baselineAccept("");
|
||||
});
|
||||
|
||||
function baselineAccept(subfolder = "") {
|
||||
return merge2(baselineCopy(subfolder), baselineDelete(subfolder));
|
||||
}
|
||||
|
||||
function baselineCopy(subfolder = "") {
|
||||
return gulp.src([`tests/baselines/local/${subfolder}/**`, `!tests/baselines/local/${subfolder}/**/*.delete`])
|
||||
.pipe(gulp.dest(refBaseline));
|
||||
}
|
||||
|
||||
function baselineDelete(subfolder = "") {
|
||||
return gulp.src(["tests/baselines/local/**/*.delete"])
|
||||
.pipe(insert.transform((content, fileObj) => {
|
||||
const target = path.join(refBaseline, fileObj.relative.substr(0, fileObj.relative.length - ".delete".length));
|
||||
del.sync(target);
|
||||
del.sync(fileObj.path);
|
||||
return "";
|
||||
}));
|
||||
}
|
||||
|
||||
gulp.task("baseline-accept", "Makes the most recent test results the new baseline, overwriting the old baseline", (done) => {
|
||||
const softAccept = cmdLineOptions["soft"];
|
||||
if (!softAccept) {
|
||||
del(refBaseline).then(() => {
|
||||
fs.renameSync(localBaseline, refBaseline);
|
||||
done();
|
||||
}, done);
|
||||
}
|
||||
else {
|
||||
gulp.src(localBaseline)
|
||||
.pipe(gulp.dest(refBaseline))
|
||||
.on("end", () => {
|
||||
del(path.join(refBaseline, "local")).then(() => done(), done);
|
||||
});
|
||||
}
|
||||
});
|
||||
gulp.task("baseline-accept-rwc", "Makes the most recent rwc test results the new baseline, overwriting the old baseline", () => {
|
||||
return del(refRwcBaseline).then(() => {
|
||||
fs.renameSync(localRwcBaseline, refRwcBaseline);
|
||||
});
|
||||
return baselineAccept("rwc");
|
||||
});
|
||||
|
||||
|
||||
gulp.task("baseline-accept-test262", "Makes the most recent test262 test results the new baseline, overwriting the old baseline", () => {
|
||||
return del(refTest262Baseline).then(() => {
|
||||
fs.renameSync(localTest262Baseline, refTest262Baseline);
|
||||
});
|
||||
return baselineAccept("test262");
|
||||
});
|
||||
|
||||
|
||||
@ -929,26 +930,6 @@ gulp.task("build-rules", "Compiles tslint rules to js", () => {
|
||||
.pipe(gulp.dest(dest));
|
||||
});
|
||||
|
||||
function getLinterOptions() {
|
||||
return {
|
||||
configuration: require("./tslint.json"),
|
||||
formatter: "prose",
|
||||
formattersDirectory: undefined,
|
||||
rulesDirectory: "built/local/tslint"
|
||||
};
|
||||
}
|
||||
|
||||
function lintFileContents(options, path, contents) {
|
||||
const ll = new Linter(path, contents, options);
|
||||
console.log("Linting '" + path + "'.");
|
||||
return ll.lint();
|
||||
}
|
||||
|
||||
function lintFile(options, path) {
|
||||
const contents = fs.readFileSync(path, "utf8");
|
||||
return lintFileContents(options, path, contents);
|
||||
}
|
||||
|
||||
const lintTargets = [
|
||||
"Gulpfile.ts",
|
||||
"src/compiler/**/*.ts",
|
||||
@ -960,29 +941,72 @@ const lintTargets = [
|
||||
"tests/*.ts", "tests/webhost/*.ts" // Note: does *not* descend recursively
|
||||
];
|
||||
|
||||
function sendNextFile(files: {path: string}[], child: cp.ChildProcess, callback: (failures: number) => void, failures: number) {
|
||||
const file = files.pop();
|
||||
if (file) {
|
||||
console.log(`Linting '${file.path}'.`);
|
||||
child.send({ kind: "file", name: file.path });
|
||||
}
|
||||
else {
|
||||
child.send({ kind: "close" });
|
||||
callback(failures);
|
||||
}
|
||||
}
|
||||
|
||||
function spawnLintWorker(files: {path: string}[], callback: (failures: number) => void) {
|
||||
const child = cp.fork("./scripts/parallel-lint");
|
||||
let failures = 0;
|
||||
child.on("message", function(data) {
|
||||
switch (data.kind) {
|
||||
case "result":
|
||||
if (data.failures > 0) {
|
||||
failures += data.failures;
|
||||
console.log(data.output);
|
||||
}
|
||||
sendNextFile(files, child, callback, failures);
|
||||
break;
|
||||
case "error":
|
||||
console.error(data.error);
|
||||
failures++;
|
||||
sendNextFile(files, child, callback, failures);
|
||||
break;
|
||||
}
|
||||
});
|
||||
sendNextFile(files, child, callback, failures);
|
||||
}
|
||||
|
||||
gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are: --f[iles]=regex", ["build-rules"], () => {
|
||||
const fileMatcher = RegExp(cmdLineOptions["files"]);
|
||||
const lintOptions = getLinterOptions();
|
||||
let failed = 0;
|
||||
if (fold.isTravis()) console.log(fold.start("lint"));
|
||||
return gulp.src(lintTargets)
|
||||
.pipe(insert.transform((contents, file) => {
|
||||
if (!fileMatcher.test(file.path)) return contents;
|
||||
const result = lintFile(lintOptions, file.path);
|
||||
if (result.failureCount > 0) {
|
||||
console.log(result.output);
|
||||
failed += result.failureCount;
|
||||
|
||||
let files: {stat: fs.Stats, path: string}[] = [];
|
||||
return gulp.src(lintTargets, { read: false })
|
||||
.pipe(through2.obj((chunk, enc, cb) => {
|
||||
files.push(chunk);
|
||||
cb();
|
||||
}, (cb) => {
|
||||
files = files.filter(file => fileMatcher.test(file.path)).sort((filea, fileb) => filea.stat.size - fileb.stat.size);
|
||||
const workerCount = (process.env.workerCount && +process.env.workerCount) || os.cpus().length;
|
||||
for (let i = 0; i < workerCount; i++) {
|
||||
spawnLintWorker(files, finished);
|
||||
}
|
||||
return contents; // TODO (weswig): Automatically apply fixes? :3
|
||||
}))
|
||||
.on("end", () => {
|
||||
if (fold.isTravis()) console.log(fold.end("lint"));
|
||||
if (failed > 0) {
|
||||
console.error("Linter errors.");
|
||||
process.exit(1);
|
||||
|
||||
let completed = 0;
|
||||
let failures = 0;
|
||||
function finished(fails) {
|
||||
completed++;
|
||||
failures += fails;
|
||||
if (completed === workerCount) {
|
||||
if (fold.isTravis()) console.log(fold.end("lint"));
|
||||
if (failures > 0) {
|
||||
throw new Error(`Linter errors: ${failures}`);
|
||||
}
|
||||
else {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
|
||||
161
Jakefile.js
161
Jakefile.js
@ -4,7 +4,6 @@ var fs = require("fs");
|
||||
var os = require("os");
|
||||
var path = require("path");
|
||||
var child_process = require("child_process");
|
||||
var Linter = require("tslint");
|
||||
var fold = require("travis-fold");
|
||||
var runTestsInParallel = require("./scripts/mocha-parallel").runTestsInParallel;
|
||||
|
||||
@ -181,7 +180,8 @@ var harnessSources = harnessCoreSources.concat([
|
||||
"convertCompilerOptionsFromJson.ts",
|
||||
"convertTypingOptionsFromJson.ts",
|
||||
"tsserverProjectSystem.ts",
|
||||
"matchFiles.ts"
|
||||
"matchFiles.ts",
|
||||
"initializeTSConfig.ts",
|
||||
].map(function (f) {
|
||||
return path.join(unittestsDirectory, f);
|
||||
})).concat([
|
||||
@ -938,16 +938,16 @@ 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) {
|
||||
if (!hardOrSoft || hardOrSoft === "hard") {
|
||||
jake.rmRf(refBaseline);
|
||||
fs.renameSync(localBaseline, refBaseline);
|
||||
}
|
||||
else if (hardOrSoft === "soft") {
|
||||
var files = jake.readdirR(localBaseline);
|
||||
for (var i in files) {
|
||||
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);
|
||||
}
|
||||
jake.rmRf(path.join(refBaseline, "local"));
|
||||
}
|
||||
});
|
||||
|
||||
@ -1054,36 +1054,6 @@ task("build-rules-end", [] , function() {
|
||||
if (fold.isTravis()) console.log(fold.end("build-rules"));
|
||||
});
|
||||
|
||||
function getLinterOptions() {
|
||||
return {
|
||||
configuration: require("./tslint.json"),
|
||||
formatter: "prose",
|
||||
formattersDirectory: undefined,
|
||||
rulesDirectory: "built/local/tslint"
|
||||
};
|
||||
}
|
||||
|
||||
function lintFileContents(options, path, contents) {
|
||||
var ll = new Linter(path, contents, options);
|
||||
console.log("Linting '" + path + "'.");
|
||||
return ll.lint();
|
||||
}
|
||||
|
||||
function lintFile(options, path) {
|
||||
var contents = fs.readFileSync(path, "utf8");
|
||||
return lintFileContents(options, path, contents);
|
||||
}
|
||||
|
||||
function lintFileAsync(options, path, cb) {
|
||||
fs.readFile(path, "utf8", function(err, contents) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
var result = lintFileContents(options, path, contents);
|
||||
cb(undefined, result);
|
||||
});
|
||||
}
|
||||
|
||||
var lintTargets = compilerSources
|
||||
.concat(harnessSources)
|
||||
// Other harness sources
|
||||
@ -1094,75 +1064,78 @@ var lintTargets = compilerSources
|
||||
.concat(["Gulpfile.ts"])
|
||||
.concat([nodeServerInFile, perftscPath, "tests/perfsys.ts", webhostPath]);
|
||||
|
||||
function sendNextFile(files, child, callback, failures) {
|
||||
var file = files.pop();
|
||||
if (file) {
|
||||
console.log("Linting '" + file + "'.");
|
||||
child.send({kind: "file", name: file});
|
||||
}
|
||||
else {
|
||||
child.send({kind: "close"});
|
||||
callback(failures);
|
||||
}
|
||||
}
|
||||
|
||||
function spawnLintWorker(files, callback) {
|
||||
var child = child_process.fork("./scripts/parallel-lint");
|
||||
var failures = 0;
|
||||
child.on("message", function(data) {
|
||||
switch (data.kind) {
|
||||
case "result":
|
||||
if (data.failures > 0) {
|
||||
failures += data.failures;
|
||||
console.log(data.output);
|
||||
}
|
||||
sendNextFile(files, child, callback, failures);
|
||||
break;
|
||||
case "error":
|
||||
console.error(data.error);
|
||||
failures++;
|
||||
sendNextFile(files, child, callback, failures);
|
||||
break;
|
||||
}
|
||||
});
|
||||
sendNextFile(files, child, callback, failures);
|
||||
}
|
||||
|
||||
desc("Runs tslint on the compiler sources. Optional arguments are: f[iles]=regex");
|
||||
task("lint", ["build-rules"], function() {
|
||||
if (fold.isTravis()) console.log(fold.start("lint"));
|
||||
var startTime = mark();
|
||||
var lintOptions = getLinterOptions();
|
||||
var failed = 0;
|
||||
var fileMatcher = RegExp(process.env.f || process.env.file || process.env.files || "");
|
||||
var done = {};
|
||||
for (var i in lintTargets) {
|
||||
var target = lintTargets[i];
|
||||
if (!done[target] && fileMatcher.test(target)) {
|
||||
var result = lintFile(lintOptions, target);
|
||||
if (result.failureCount > 0) {
|
||||
console.log(result.output);
|
||||
failed += result.failureCount;
|
||||
}
|
||||
done[target] = true;
|
||||
done[target] = fs.statSync(target).size;
|
||||
}
|
||||
}
|
||||
measure(startTime);
|
||||
if (fold.isTravis()) console.log(fold.end("lint"));
|
||||
if (failed > 0) {
|
||||
fail('Linter errors.', failed);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* This is required because file watches on Windows get fires _twice_
|
||||
* when a file changes on some node/windows version configuations
|
||||
* (node v4 and win 10, for example). By not running a lint for a file
|
||||
* which already has a pending lint, we avoid duplicating our work.
|
||||
* (And avoid printing duplicate results!)
|
||||
*/
|
||||
var lintSemaphores = {};
|
||||
var workerCount = (process.env.workerCount && +process.env.workerCount) || os.cpus().length;
|
||||
|
||||
function lintWatchFile(filename) {
|
||||
fs.watch(filename, {persistent: true}, function(event) {
|
||||
if (event !== "change") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!lintSemaphores[filename]) {
|
||||
lintSemaphores[filename] = true;
|
||||
lintFileAsync(getLinterOptions(), filename, function(err, result) {
|
||||
delete lintSemaphores[filename];
|
||||
if (err) {
|
||||
console.log(err);
|
||||
return;
|
||||
}
|
||||
if (result.failureCount > 0) {
|
||||
console.log("***Lint failure***");
|
||||
for (var i = 0; i < result.failures.length; i++) {
|
||||
var failure = result.failures[i];
|
||||
var start = failure.startPosition.lineAndCharacter;
|
||||
var end = failure.endPosition.lineAndCharacter;
|
||||
console.log("warning " + filename + " (" + (start.line + 1) + "," + (start.character + 1) + "," + (end.line + 1) + "," + (end.character + 1) + "): " + failure.failure);
|
||||
}
|
||||
console.log("*** Total " + result.failureCount + " failures.");
|
||||
}
|
||||
});
|
||||
}
|
||||
var names = Object.keys(done).sort(function(namea, nameb) {
|
||||
return done[namea] - done[nameb];
|
||||
});
|
||||
}
|
||||
|
||||
desc("Watches files for changes to rerun a lint pass");
|
||||
task("lint-server", ["build-rules"], function() {
|
||||
console.log("Watching ./src for changes to linted files");
|
||||
for (var i = 0; i < lintTargets.length; i++) {
|
||||
lintWatchFile(lintTargets[i]);
|
||||
for (var i = 0; i < workerCount; i++) {
|
||||
spawnLintWorker(names, finished);
|
||||
}
|
||||
});
|
||||
|
||||
var completed = 0;
|
||||
var failures = 0;
|
||||
function finished(fails) {
|
||||
completed++;
|
||||
failures += fails;
|
||||
if (completed === workerCount) {
|
||||
measure(startTime);
|
||||
if (fold.isTravis()) console.log(fold.end("lint"));
|
||||
if (failures > 0) {
|
||||
fail('Linter errors.', failed);
|
||||
}
|
||||
else {
|
||||
complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {async: true});
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
[](https://gitter.im/Microsoft/TypeScript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
[TypeScript](http://www.typescriptlang.org/) is a language for application-scale JavaScript. TypeScript adds optional types, classes, and modules to JavaScript. TypeScript supports tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. Try it out at the [playground](http://www.typescriptlang.org/Playground), and stay up to date via [our blog](http://blogs.msdn.com/typescript) and [Twitter account](https://twitter.com/typescriptlang).
|
||||
[TypeScript](http://www.typescriptlang.org/) is a language for application-scale JavaScript. TypeScript adds optional types, classes, and modules to JavaScript. TypeScript supports tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. Try it out at the [playground](http://www.typescriptlang.org/Playground), and stay up to date via [our blog](https://blogs.msdn.microsoft.com/typescript) and [Twitter account](https://twitter.com/typescriptlang).
|
||||
|
||||
## Installing
|
||||
|
||||
|
||||
@ -69,6 +69,7 @@
|
||||
"mkdirp": "latest",
|
||||
"mocha": "latest",
|
||||
"mocha-fivemat-progress-reporter": "latest",
|
||||
"q": "latest",
|
||||
"run-sequence": "latest",
|
||||
"sorcery": "latest",
|
||||
"through2": "latest",
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/// <reference path="../src/harness/external/node.d.ts" />
|
||||
/// <reference types="node"/>
|
||||
|
||||
import fs = require('fs');
|
||||
import path = require('path');
|
||||
|
||||
45
scripts/parallel-lint.js
Normal file
45
scripts/parallel-lint.js
Normal file
@ -0,0 +1,45 @@
|
||||
var Linter = require("tslint");
|
||||
var fs = require("fs");
|
||||
|
||||
function getLinterOptions() {
|
||||
return {
|
||||
configuration: require("../tslint.json"),
|
||||
formatter: "prose",
|
||||
formattersDirectory: undefined,
|
||||
rulesDirectory: "built/local/tslint"
|
||||
};
|
||||
}
|
||||
|
||||
function lintFileContents(options, path, contents) {
|
||||
var ll = new Linter(path, contents, options);
|
||||
return ll.lint();
|
||||
}
|
||||
|
||||
function lintFileAsync(options, path, cb) {
|
||||
fs.readFile(path, "utf8", function (err, contents) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
var result = lintFileContents(options, path, contents);
|
||||
cb(undefined, result);
|
||||
});
|
||||
}
|
||||
|
||||
process.on("message", function (data) {
|
||||
switch (data.kind) {
|
||||
case "file":
|
||||
var target = data.name;
|
||||
var lintOptions = getLinterOptions();
|
||||
lintFileAsync(lintOptions, target, function (err, result) {
|
||||
if (err) {
|
||||
process.send({ kind: "error", error: err.toString() });
|
||||
return;
|
||||
}
|
||||
process.send({ kind: "result", failures: result.failureCount, output: result.output });
|
||||
});
|
||||
break;
|
||||
case "close":
|
||||
process.exit(0);
|
||||
break;
|
||||
}
|
||||
});
|
||||
2
scripts/types/ambient.d.ts
vendored
2
scripts/types/ambient.d.ts
vendored
@ -10,7 +10,7 @@ declare module "gulp-insert" {
|
||||
export function append(text: string | Buffer): NodeJS.ReadWriteStream;
|
||||
export function prepend(text: string | Buffer): NodeJS.ReadWriteStream;
|
||||
export function wrap(text: string | Buffer, tail: string | Buffer): NodeJS.ReadWriteStream;
|
||||
export function transform(cb: (contents: string, file: {path: string}) => string): NodeJS.ReadWriteStream; // file is a vinyl file
|
||||
export function transform(cb: (contents: string, file: {path: string, relative: string}) => string): NodeJS.ReadWriteStream; // file is a vinyl file
|
||||
}
|
||||
|
||||
declare module "into-stream" {
|
||||
|
||||
@ -89,9 +89,10 @@ namespace ts {
|
||||
const binder = createBinder();
|
||||
|
||||
export function bindSourceFile(file: SourceFile, options: CompilerOptions) {
|
||||
const start = performance.mark();
|
||||
performance.mark("beforeBind");
|
||||
binder(file, options);
|
||||
performance.measure("Bind", start);
|
||||
performance.mark("afterBind");
|
||||
performance.measure("Bind", "beforeBind", "afterBind");
|
||||
}
|
||||
|
||||
function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
|
||||
@ -298,8 +299,10 @@ namespace ts {
|
||||
const name = isDefaultExport && parent ? "default" : getDeclarationName(node);
|
||||
|
||||
let symbol: Symbol;
|
||||
if (name !== undefined) {
|
||||
|
||||
if (name === undefined) {
|
||||
symbol = createSymbol(SymbolFlags.None, "__missing");
|
||||
}
|
||||
else {
|
||||
// Check and see if the symbol table already has a symbol with this name. If not,
|
||||
// create a new symbol with this name and add it to the table. Note that we don't
|
||||
// give the new symbol any flags *yet*. This ensures that it will not conflict
|
||||
@ -311,6 +314,11 @@ namespace ts {
|
||||
// declaration we have for this symbol, and then create a new symbol for this
|
||||
// declaration.
|
||||
//
|
||||
// Note that when properties declared in Javascript constructors
|
||||
// (marked by isReplaceableByMethod) conflict with another symbol, the property loses.
|
||||
// Always. This allows the common Javascript pattern of overwriting a prototype method
|
||||
// with an bound instance method of the same type: `this.method = this.method.bind(this)`
|
||||
//
|
||||
// If we created a new symbol, either because we didn't have a symbol with this name
|
||||
// in the symbol table, or we conflicted with an existing symbol, then just add this
|
||||
// node as the sole declaration of the new symbol.
|
||||
@ -325,33 +333,37 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (symbol.flags & excludes) {
|
||||
if (node.name) {
|
||||
node.name.parent = node;
|
||||
if (symbol.isReplaceableByMethod) {
|
||||
// Javascript constructor-declared symbols can be discarded in favor of
|
||||
// prototype symbols like methods.
|
||||
symbol = symbolTable[name] = createSymbol(SymbolFlags.None, name);
|
||||
}
|
||||
|
||||
// Report errors every position with duplicate declaration
|
||||
// Report errors on previous encountered declarations
|
||||
let message = symbol.flags & SymbolFlags.BlockScopedVariable
|
||||
? Diagnostics.Cannot_redeclare_block_scoped_variable_0
|
||||
: Diagnostics.Duplicate_identifier_0;
|
||||
|
||||
forEach(symbol.declarations, declaration => {
|
||||
if (declaration.flags & NodeFlags.Default) {
|
||||
message = Diagnostics.A_module_cannot_have_multiple_default_exports;
|
||||
else {
|
||||
if (node.name) {
|
||||
node.name.parent = node;
|
||||
}
|
||||
});
|
||||
|
||||
forEach(symbol.declarations, declaration => {
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
|
||||
});
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(node.name || node, message, getDisplayName(node)));
|
||||
// Report errors every position with duplicate declaration
|
||||
// Report errors on previous encountered declarations
|
||||
let message = symbol.flags & SymbolFlags.BlockScopedVariable
|
||||
? Diagnostics.Cannot_redeclare_block_scoped_variable_0
|
||||
: Diagnostics.Duplicate_identifier_0;
|
||||
|
||||
symbol = createSymbol(SymbolFlags.None, name);
|
||||
forEach(symbol.declarations, declaration => {
|
||||
if (declaration.flags & NodeFlags.Default) {
|
||||
message = Diagnostics.A_module_cannot_have_multiple_default_exports;
|
||||
}
|
||||
});
|
||||
|
||||
forEach(symbol.declarations, declaration => {
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(declaration.name || declaration, message, getDisplayName(declaration)));
|
||||
});
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(node.name || node, message, getDisplayName(node)));
|
||||
|
||||
symbol = createSymbol(SymbolFlags.None, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
symbol = createSymbol(SymbolFlags.None, "__missing");
|
||||
}
|
||||
|
||||
addDeclarationToSymbol(symbol, node, includes);
|
||||
symbol.parent = parent;
|
||||
@ -1965,20 +1977,25 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindThisPropertyAssignment(node: BinaryExpression) {
|
||||
// Declare a 'member' in case it turns out the container was an ES5 class or ES6 constructor
|
||||
let assignee: Node;
|
||||
Debug.assert(isInJavaScriptFile(node));
|
||||
// Declare a 'member' if the container is an ES5 class or ES6 constructor
|
||||
if (container.kind === SyntaxKind.FunctionDeclaration || container.kind === SyntaxKind.FunctionExpression) {
|
||||
assignee = container;
|
||||
container.symbol.members = container.symbol.members || createMap<Symbol>();
|
||||
// It's acceptable for multiple 'this' assignments of the same identifier to occur
|
||||
declareSymbol(container.symbol.members, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property);
|
||||
}
|
||||
else if (container.kind === SyntaxKind.Constructor) {
|
||||
assignee = container.parent;
|
||||
// this.foo assignment in a JavaScript class
|
||||
// Bind this property to the containing class
|
||||
const saveContainer = container;
|
||||
container = container.parent;
|
||||
const symbol = bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property, SymbolFlags.None);
|
||||
if (symbol) {
|
||||
// constructor-declared symbols can be overwritten by subsequent method declarations
|
||||
(symbol as Symbol).isReplaceableByMethod = true;
|
||||
}
|
||||
container = saveContainer;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
assignee.symbol.members = assignee.symbol.members || createMap<Symbol>();
|
||||
// It's acceptable for multiple 'this' assignments of the same identifier to occur
|
||||
declareSymbol(assignee.symbol.members, assignee.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property);
|
||||
}
|
||||
|
||||
function bindPrototypePropertyAssignment(node: BinaryExpression) {
|
||||
|
||||
@ -284,7 +284,7 @@ namespace ts {
|
||||
NullFacts = TypeofEQObject | TypeofNEString | TypeofNENumber | TypeofNEBoolean | TypeofNESymbol | TypeofNEFunction | TypeofNEHostObject | EQNull | EQUndefinedOrNull | NEUndefined | Falsy,
|
||||
}
|
||||
|
||||
const typeofEQFacts: MapLike<TypeFacts> = {
|
||||
const typeofEQFacts = createMap({
|
||||
"string": TypeFacts.TypeofEQString,
|
||||
"number": TypeFacts.TypeofEQNumber,
|
||||
"boolean": TypeFacts.TypeofEQBoolean,
|
||||
@ -292,9 +292,9 @@ namespace ts {
|
||||
"undefined": TypeFacts.EQUndefined,
|
||||
"object": TypeFacts.TypeofEQObject,
|
||||
"function": TypeFacts.TypeofEQFunction
|
||||
};
|
||||
});
|
||||
|
||||
const typeofNEFacts: MapLike<TypeFacts> = {
|
||||
const typeofNEFacts = createMap({
|
||||
"string": TypeFacts.TypeofNEString,
|
||||
"number": TypeFacts.TypeofNENumber,
|
||||
"boolean": TypeFacts.TypeofNEBoolean,
|
||||
@ -302,15 +302,15 @@ namespace ts {
|
||||
"undefined": TypeFacts.NEUndefined,
|
||||
"object": TypeFacts.TypeofNEObject,
|
||||
"function": TypeFacts.TypeofNEFunction
|
||||
};
|
||||
});
|
||||
|
||||
const typeofTypesByName: MapLike<Type> = {
|
||||
const typeofTypesByName = createMap<Type>({
|
||||
"string": stringType,
|
||||
"number": numberType,
|
||||
"boolean": booleanType,
|
||||
"symbol": esSymbolType,
|
||||
"undefined": undefinedType
|
||||
};
|
||||
});
|
||||
|
||||
let jsxElementType: ObjectType;
|
||||
/** Things we lazy load from the JSX namespace */
|
||||
@ -403,8 +403,8 @@ namespace ts {
|
||||
result.parent = symbol.parent;
|
||||
if (symbol.valueDeclaration) result.valueDeclaration = symbol.valueDeclaration;
|
||||
if (symbol.constEnumOnlyModule) result.constEnumOnlyModule = true;
|
||||
if (symbol.members) result.members = cloneSymbolTable(symbol.members);
|
||||
if (symbol.exports) result.exports = cloneSymbolTable(symbol.exports);
|
||||
if (symbol.members) result.members = cloneMap(symbol.members);
|
||||
if (symbol.exports) result.exports = cloneMap(symbol.exports);
|
||||
recordMergedSymbol(result, symbol);
|
||||
return result;
|
||||
}
|
||||
@ -447,14 +447,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function cloneSymbolTable(symbolTable: SymbolTable): SymbolTable {
|
||||
const result = createMap<Symbol>();
|
||||
for (const id in symbolTable) {
|
||||
result[id] = symbolTable[id];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function mergeSymbolTable(target: SymbolTable, source: SymbolTable) {
|
||||
for (const id in source) {
|
||||
let targetSymbol = target[id];
|
||||
@ -531,7 +523,7 @@ namespace ts {
|
||||
|
||||
function getNodeLinks(node: Node): NodeLinks {
|
||||
const nodeId = getNodeId(node);
|
||||
return nodeLinks[nodeId] || (nodeLinks[nodeId] = {});
|
||||
return nodeLinks[nodeId] || (nodeLinks[nodeId] = { flags: 0 });
|
||||
}
|
||||
|
||||
function isGlobalSourceFile(node: Node) {
|
||||
@ -1457,7 +1449,7 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
visitedSymbols.push(symbol);
|
||||
const symbols = cloneSymbolTable(symbol.exports);
|
||||
const symbols = cloneMap(symbol.exports);
|
||||
// All export * declarations are collected in an __export symbol by the binder
|
||||
const exportStars = symbol.exports["__export"];
|
||||
if (exportStars) {
|
||||
@ -1662,12 +1654,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
// If symbol is directly available by its name in the symbol table
|
||||
if (isAccessible(lookUp(symbols, symbol.name))) {
|
||||
if (isAccessible(symbols[symbol.name])) {
|
||||
return [symbol];
|
||||
}
|
||||
|
||||
// Check if symbol is any of the alias
|
||||
return forEachValue(symbols, symbolFromSymbolTable => {
|
||||
return forEachProperty(symbols, symbolFromSymbolTable => {
|
||||
if (symbolFromSymbolTable.flags & SymbolFlags.Alias
|
||||
&& symbolFromSymbolTable.name !== "export="
|
||||
&& !getDeclarationOfKind(symbolFromSymbolTable, SyntaxKind.ExportSpecifier)) {
|
||||
@ -3098,7 +3090,7 @@ namespace ts {
|
||||
|
||||
// If the declaration specifies a binding pattern, use the type implied by the binding pattern
|
||||
if (isBindingPattern(declaration.name)) {
|
||||
return getTypeFromBindingPattern(<BindingPattern>declaration.name, /*includePatternInType*/ false);
|
||||
return getTypeFromBindingPattern(<BindingPattern>declaration.name, /*includePatternInType*/ false, /*reportErrors*/ true);
|
||||
}
|
||||
|
||||
// No type specified and nothing can be inferred
|
||||
@ -3108,23 +3100,21 @@ namespace ts {
|
||||
// Return the type implied by a binding pattern element. This is the type of the initializer of the element if
|
||||
// one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding
|
||||
// pattern. Otherwise, it is the type any.
|
||||
function getTypeFromBindingElement(element: BindingElement, includePatternInType?: boolean): Type {
|
||||
function getTypeFromBindingElement(element: BindingElement, includePatternInType?: boolean, reportErrors?: boolean): Type {
|
||||
if (element.initializer) {
|
||||
const type = checkExpressionCached(element.initializer);
|
||||
reportErrorsFromWidening(element, type);
|
||||
return getWidenedType(type);
|
||||
return checkExpressionCached(element.initializer);
|
||||
}
|
||||
if (isBindingPattern(element.name)) {
|
||||
return getTypeFromBindingPattern(<BindingPattern>element.name, includePatternInType);
|
||||
return getTypeFromBindingPattern(<BindingPattern>element.name, includePatternInType, reportErrors);
|
||||
}
|
||||
if (compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) {
|
||||
if (reportErrors && compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) {
|
||||
reportImplicitAnyError(element, anyType);
|
||||
}
|
||||
return anyType;
|
||||
}
|
||||
|
||||
// Return the type implied by an object binding pattern
|
||||
function getTypeFromObjectBindingPattern(pattern: BindingPattern, includePatternInType: boolean): Type {
|
||||
function getTypeFromObjectBindingPattern(pattern: BindingPattern, includePatternInType: boolean, reportErrors: boolean): Type {
|
||||
const members = createMap<Symbol>();
|
||||
let hasComputedProperties = false;
|
||||
forEach(pattern.elements, e => {
|
||||
@ -3138,7 +3128,7 @@ namespace ts {
|
||||
const text = getTextOfPropertyName(name);
|
||||
const flags = SymbolFlags.Property | SymbolFlags.Transient | (e.initializer ? SymbolFlags.Optional : 0);
|
||||
const symbol = <TransientSymbol>createSymbol(flags, text);
|
||||
symbol.type = getTypeFromBindingElement(e, includePatternInType);
|
||||
symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors);
|
||||
symbol.bindingElement = e;
|
||||
members[symbol.name] = symbol;
|
||||
});
|
||||
@ -3153,13 +3143,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Return the type implied by an array binding pattern
|
||||
function getTypeFromArrayBindingPattern(pattern: BindingPattern, includePatternInType: boolean): Type {
|
||||
function getTypeFromArrayBindingPattern(pattern: BindingPattern, includePatternInType: boolean, reportErrors: boolean): Type {
|
||||
const elements = pattern.elements;
|
||||
if (elements.length === 0 || elements[elements.length - 1].dotDotDotToken) {
|
||||
return languageVersion >= ScriptTarget.ES6 ? createIterableType(anyType) : anyArrayType;
|
||||
}
|
||||
// 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));
|
||||
const elementTypes = map(elements, e => e.kind === SyntaxKind.OmittedExpression ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors));
|
||||
if (includePatternInType) {
|
||||
const result = createNewTupleType(elementTypes);
|
||||
result.pattern = pattern;
|
||||
@ -3175,10 +3165,10 @@ namespace ts {
|
||||
// used as the contextual type of an initializer associated with the binding pattern. Also, for a destructuring
|
||||
// parameter with no type annotation or initializer, the type implied by the binding pattern becomes the type of
|
||||
// the parameter.
|
||||
function getTypeFromBindingPattern(pattern: BindingPattern, includePatternInType?: boolean): Type {
|
||||
function getTypeFromBindingPattern(pattern: BindingPattern, includePatternInType?: boolean, reportErrors?: boolean): Type {
|
||||
return pattern.kind === SyntaxKind.ObjectBindingPattern
|
||||
? getTypeFromObjectBindingPattern(pattern, includePatternInType)
|
||||
: getTypeFromArrayBindingPattern(pattern, includePatternInType);
|
||||
? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors)
|
||||
: getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors);
|
||||
}
|
||||
|
||||
// Return the type associated with a variable, parameter, or property declaration. In the simple case this is the type
|
||||
@ -3255,6 +3245,13 @@ namespace ts {
|
||||
// * className.prototype.method = expr
|
||||
if (declaration.kind === SyntaxKind.BinaryExpression ||
|
||||
declaration.kind === SyntaxKind.PropertyAccessExpression && declaration.parent.kind === SyntaxKind.BinaryExpression) {
|
||||
// Use JS Doc type if present on parent expression statement
|
||||
if (declaration.flags & NodeFlags.JavaScriptFile) {
|
||||
const typeTag = getJSDocTypeTag(declaration.parent);
|
||||
if (typeTag && typeTag.typeExpression) {
|
||||
return links.type = getTypeFromTypeNode(typeTag.typeExpression.type);
|
||||
}
|
||||
}
|
||||
const declaredTypes = map(symbol.declarations,
|
||||
decl => decl.kind === SyntaxKind.BinaryExpression ?
|
||||
checkExpressionCached((<BinaryExpression>decl).right) :
|
||||
@ -5560,6 +5557,8 @@ namespace ts {
|
||||
return getTypeFromThisTypeNode(node);
|
||||
case SyntaxKind.LiteralType:
|
||||
return getTypeFromLiteralTypeNode(<LiteralTypeNode>node);
|
||||
case SyntaxKind.JSDocLiteralType:
|
||||
return getTypeFromLiteralTypeNode((<JSDocLiteralType>node).literal);
|
||||
case SyntaxKind.TypeReference:
|
||||
case SyntaxKind.JSDocTypeReference:
|
||||
return getTypeFromTypeReference(<TypeReferenceNode>node);
|
||||
@ -6629,7 +6628,7 @@ namespace ts {
|
||||
const maybeCache = maybeStack[depth];
|
||||
// If result is definitely true, copy assumptions to global cache, else copy to next level up
|
||||
const destinationCache = (result === Ternary.True || depth === 0) ? relation : maybeStack[depth - 1];
|
||||
copyMap(maybeCache, destinationCache);
|
||||
copyProperties(maybeCache, destinationCache);
|
||||
}
|
||||
else {
|
||||
// A false result goes straight into global cache (when something is false under assumptions it
|
||||
@ -7941,7 +7940,7 @@ namespace ts {
|
||||
// check. This gives us a quicker out in the common case where an object type is not a function.
|
||||
const resolved = resolveStructuredTypeMembers(type);
|
||||
return !!(resolved.callSignatures.length || resolved.constructSignatures.length ||
|
||||
hasProperty(resolved.members, "bind") && isTypeSubtypeOf(type, globalFunctionType));
|
||||
resolved.members["bind"] && isTypeSubtypeOf(type, globalFunctionType));
|
||||
}
|
||||
|
||||
function getTypeFacts(type: Type): TypeFacts {
|
||||
@ -8192,7 +8191,7 @@ namespace ts {
|
||||
return incomplete ? { flags: 0, type } : type;
|
||||
}
|
||||
|
||||
function getFlowTypeOfReference(reference: Node, declaredType: Type, assumeInitialized: boolean, includeOuterFunctions: boolean) {
|
||||
function getFlowTypeOfReference(reference: Node, declaredType: Type, assumeInitialized: boolean, flowContainer: Node) {
|
||||
let key: string;
|
||||
if (!reference.flowNode || assumeInitialized && !(declaredType.flags & TypeFlags.Narrowable)) {
|
||||
return declaredType;
|
||||
@ -8244,7 +8243,7 @@ namespace ts {
|
||||
else if (flow.flags & FlowFlags.Start) {
|
||||
// Check if we should continue with the control flow of the containing function.
|
||||
const container = (<FlowStart>flow).container;
|
||||
if (container && includeOuterFunctions) {
|
||||
if (container && container !== flowContainer && reference.kind !== SyntaxKind.PropertyAccessExpression) {
|
||||
flow = container.flowNode;
|
||||
continue;
|
||||
}
|
||||
@ -8372,13 +8371,18 @@ namespace ts {
|
||||
// each antecedent code path.
|
||||
const antecedentTypes: Type[] = [];
|
||||
let subtypeReduction = false;
|
||||
let firstAntecedentType: FlowType;
|
||||
flowLoopNodes[flowLoopCount] = flow;
|
||||
flowLoopKeys[flowLoopCount] = key;
|
||||
flowLoopTypes[flowLoopCount] = antecedentTypes;
|
||||
for (const antecedent of flow.antecedents) {
|
||||
flowLoopCount++;
|
||||
const type = getTypeFromFlowType(getTypeAtFlowNode(antecedent));
|
||||
const flowType = getTypeAtFlowNode(antecedent);
|
||||
flowLoopCount--;
|
||||
if (!firstAntecedentType) {
|
||||
firstAntecedentType = flowType;
|
||||
}
|
||||
const type = getTypeFromFlowType(flowType);
|
||||
// If we see a value appear in the cache it is a sign that control flow analysis
|
||||
// was restarted and completed by checkExpressionCached. We can simply pick up
|
||||
// the resulting type and bail out.
|
||||
@ -8401,7 +8405,13 @@ namespace ts {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cache[key] = getUnionType(antecedentTypes, subtypeReduction);
|
||||
// The result is incomplete if the first antecedent (the non-looping control flow path)
|
||||
// is incomplete.
|
||||
const result = getUnionType(antecedentTypes, subtypeReduction);
|
||||
if (isIncomplete(firstAntecedentType)) {
|
||||
return createFlowType(result, /*incomplete*/ true);
|
||||
}
|
||||
return cache[key] = result;
|
||||
}
|
||||
|
||||
function isMatchingReferenceDiscriminant(expr: Expression) {
|
||||
@ -8517,14 +8527,14 @@ namespace ts {
|
||||
// We narrow a non-union type to an exact primitive type if the non-union type
|
||||
// is a supertype of that primitive type. For example, type 'any' can be narrowed
|
||||
// to one of the primitive types.
|
||||
const targetType = getProperty(typeofTypesByName, literal.text);
|
||||
const targetType = typeofTypesByName[literal.text];
|
||||
if (targetType && isTypeSubtypeOf(targetType, type)) {
|
||||
return targetType;
|
||||
}
|
||||
}
|
||||
const facts = assumeTrue ?
|
||||
getProperty(typeofEQFacts, literal.text) || TypeFacts.TypeofEQHostObject :
|
||||
getProperty(typeofNEFacts, literal.text) || TypeFacts.TypeofNEHostObject;
|
||||
typeofEQFacts[literal.text] || TypeFacts.TypeofEQHostObject :
|
||||
typeofNEFacts[literal.text] || TypeFacts.TypeofNEHostObject;
|
||||
return getTypeWithFacts(type, facts);
|
||||
}
|
||||
|
||||
@ -8722,21 +8732,52 @@ namespace ts {
|
||||
function getControlFlowContainer(node: Node): Node {
|
||||
while (true) {
|
||||
node = node.parent;
|
||||
if (isFunctionLike(node) || node.kind === SyntaxKind.ModuleBlock || node.kind === SyntaxKind.SourceFile || node.kind === SyntaxKind.PropertyDeclaration) {
|
||||
if (isFunctionLike(node) && !getImmediatelyInvokedFunctionExpression(node) ||
|
||||
node.kind === SyntaxKind.ModuleBlock ||
|
||||
node.kind === SyntaxKind.SourceFile ||
|
||||
node.kind === SyntaxKind.PropertyDeclaration) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isDeclarationIncludedInFlow(reference: Node, declaration: Declaration, includeOuterFunctions: boolean) {
|
||||
const declarationContainer = getControlFlowContainer(declaration);
|
||||
let container = getControlFlowContainer(reference);
|
||||
while (container !== declarationContainer &&
|
||||
(container.kind === SyntaxKind.FunctionExpression || container.kind === SyntaxKind.ArrowFunction) &&
|
||||
(includeOuterFunctions || getImmediatelyInvokedFunctionExpression(<FunctionExpression>container))) {
|
||||
container = getControlFlowContainer(container);
|
||||
// Check if a parameter is assigned anywhere within its declaring function.
|
||||
function isParameterAssigned(symbol: Symbol) {
|
||||
const func = <FunctionLikeDeclaration>getRootDeclaration(symbol.valueDeclaration).parent;
|
||||
const links = getNodeLinks(func);
|
||||
if (!(links.flags & NodeCheckFlags.AssignmentsMarked)) {
|
||||
links.flags |= NodeCheckFlags.AssignmentsMarked;
|
||||
if (!hasParentWithAssignmentsMarked(func)) {
|
||||
markParameterAssignments(func);
|
||||
}
|
||||
}
|
||||
return symbol.isAssigned || false;
|
||||
}
|
||||
|
||||
function hasParentWithAssignmentsMarked(node: Node) {
|
||||
while (true) {
|
||||
node = node.parent;
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
if (isFunctionLike(node) && getNodeLinks(node).flags & NodeCheckFlags.AssignmentsMarked) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function markParameterAssignments(node: Node) {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
if (isAssignmentTarget(node)) {
|
||||
const symbol = getResolvedSymbol(<Identifier>node);
|
||||
if (symbol.valueDeclaration && getRootDeclaration(symbol.valueDeclaration).kind === SyntaxKind.Parameter) {
|
||||
symbol.isAssigned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
forEachChild(node, markParameterAssignments);
|
||||
}
|
||||
return container === declarationContainer;
|
||||
}
|
||||
|
||||
function checkIdentifier(node: Identifier): Type {
|
||||
@ -8791,15 +8832,35 @@ namespace ts {
|
||||
checkNestedBlockScopedBinding(node, symbol);
|
||||
|
||||
const type = getTypeOfSymbol(localOrExportSymbol);
|
||||
if (!(localOrExportSymbol.flags & SymbolFlags.Variable) || isAssignmentTarget(node)) {
|
||||
const declaration = localOrExportSymbol.valueDeclaration;
|
||||
// We only narrow variables and parameters occurring in a non-assignment position. For all other
|
||||
// entities we simply return the declared type.
|
||||
if (!(localOrExportSymbol.flags & SymbolFlags.Variable) || isAssignmentTarget(node) || !declaration) {
|
||||
return type;
|
||||
}
|
||||
const declaration = localOrExportSymbol.valueDeclaration;
|
||||
const includeOuterFunctions = isReadonlySymbol(localOrExportSymbol);
|
||||
const assumeInitialized = !strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || !declaration ||
|
||||
getRootDeclaration(declaration).kind === SyntaxKind.Parameter || isInAmbientContext(declaration) ||
|
||||
!isDeclarationIncludedInFlow(node, declaration, includeOuterFunctions);
|
||||
const flowType = getFlowTypeOfReference(node, type, assumeInitialized, includeOuterFunctions);
|
||||
// The declaration container is the innermost function that encloses the declaration of the variable
|
||||
// or parameter. The flow container is the innermost function starting with which we analyze the control
|
||||
// flow graph to determine the control flow based type.
|
||||
const isParameter = getRootDeclaration(declaration).kind === SyntaxKind.Parameter;
|
||||
const declarationContainer = getControlFlowContainer(declaration);
|
||||
let flowContainer = getControlFlowContainer(node);
|
||||
// When the control flow originates in a function expression or arrow function and we are referencing
|
||||
// a const variable or parameter from an outer function, we extend the origin of the control flow
|
||||
// analysis to include the immediately enclosing function.
|
||||
while (flowContainer !== declarationContainer &&
|
||||
(flowContainer.kind === SyntaxKind.FunctionExpression || flowContainer.kind === SyntaxKind.ArrowFunction) &&
|
||||
(isReadonlySymbol(localOrExportSymbol) || isParameter && !isParameterAssigned(localOrExportSymbol))) {
|
||||
flowContainer = getControlFlowContainer(flowContainer);
|
||||
}
|
||||
// We only look for uninitialized variables in strict null checking mode, and only when we can analyze
|
||||
// the entire control flow graph from the variable's declaration (i.e. when the flow container and
|
||||
// declaration container are the same).
|
||||
const assumeInitialized = !strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || isParameter ||
|
||||
flowContainer !== declarationContainer || isInAmbientContext(declaration);
|
||||
const flowType = getFlowTypeOfReference(node, type, assumeInitialized, flowContainer);
|
||||
// A variable is considered uninitialized when it is possible to analyze the entire control flow graph
|
||||
// from declaration to use, and when the variable's declared type doesn't include undefined but the
|
||||
// control flow based type does include undefined.
|
||||
if (!assumeInitialized && !(getFalsyFlags(type) & TypeFlags.Undefined) && getFalsyFlags(flowType) & TypeFlags.Undefined) {
|
||||
error(node, Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol));
|
||||
// Return the declared type to reduce follow-on errors
|
||||
@ -9052,7 +9113,7 @@ namespace ts {
|
||||
if (isClassLike(container.parent)) {
|
||||
const symbol = getSymbolOfNode(container.parent);
|
||||
const type = container.flags & NodeFlags.Static ? getTypeOfSymbol(symbol) : (<InterfaceType>getDeclaredTypeOfSymbol(symbol)).thisType;
|
||||
return getFlowTypeOfReference(node, type, /*assumeInitialized*/ true, /*includeOuterFunctions*/ true);
|
||||
return getFlowTypeOfReference(node, type, /*assumeInitialized*/ true, /*flowContainer*/ undefined);
|
||||
}
|
||||
|
||||
if (isInJavaScriptFile(node)) {
|
||||
@ -9358,7 +9419,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
if (isBindingPattern(declaration.name)) {
|
||||
return getTypeFromBindingPattern(<BindingPattern>declaration.name, /*includePatternInType*/ true);
|
||||
return getTypeFromBindingPattern(<BindingPattern>declaration.name, /*includePatternInType*/ true, /*reportErrors*/ false);
|
||||
}
|
||||
if (isBindingPattern(declaration.parent)) {
|
||||
const parentDeclaration = declaration.parent.parent;
|
||||
@ -9463,6 +9524,11 @@ namespace ts {
|
||||
const binaryExpression = <BinaryExpression>node.parent;
|
||||
const operator = binaryExpression.operatorToken.kind;
|
||||
if (operator >= SyntaxKind.FirstAssignment && operator <= SyntaxKind.LastAssignment) {
|
||||
// Don't do this for special property assignments to avoid circularity
|
||||
if (getSpecialPropertyAssignmentKind(binaryExpression) !== SpecialPropertyAssignmentKind.None) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// In an assignment expression, the right operand is contextually typed by the type of the left operand.
|
||||
if (node === binaryExpression.right) {
|
||||
return checkExpression(binaryExpression.left);
|
||||
@ -10135,10 +10201,9 @@ namespace ts {
|
||||
const correspondingPropSymbol = getPropertyOfType(elementAttributesType, node.name.text);
|
||||
correspondingPropType = correspondingPropSymbol && getTypeOfSymbol(correspondingPropSymbol);
|
||||
if (isUnhyphenatedJsxName(node.name.text)) {
|
||||
// Maybe there's a string indexer?
|
||||
const indexerType = getIndexTypeOfType(elementAttributesType, IndexKind.String);
|
||||
if (indexerType) {
|
||||
correspondingPropType = indexerType;
|
||||
const attributeType = getTypeOfPropertyOfType(elementAttributesType, getTextOfPropertyName(node.name)) || getIndexTypeOfType(elementAttributesType, IndexKind.String);
|
||||
if (attributeType) {
|
||||
correspondingPropType = attributeType;
|
||||
}
|
||||
else {
|
||||
// If there's no corresponding property with this name, error
|
||||
@ -10713,7 +10778,7 @@ namespace ts {
|
||||
!(prop.flags & SymbolFlags.Method && propType.flags & TypeFlags.Union)) {
|
||||
return propType;
|
||||
}
|
||||
return getFlowTypeOfReference(node, propType, /*assumeInitialized*/ true, /*includeOuterFunctions*/ false);
|
||||
return getFlowTypeOfReference(node, propType, /*assumeInitialized*/ true, /*flowContainer*/ undefined);
|
||||
}
|
||||
|
||||
function isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean {
|
||||
@ -10838,10 +10903,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Check for compatible indexer types.
|
||||
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
|
||||
const allowedNullableFlags = strictNullChecks ? 0 : TypeFlags.Nullable;
|
||||
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol | allowedNullableFlags)) {
|
||||
|
||||
// Try to use a number indexer.
|
||||
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.NumberLike) || isForInVariableForNumericPropertyNames(node.argumentExpression)) {
|
||||
if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.NumberLike | allowedNullableFlags) || isForInVariableForNumericPropertyNames(node.argumentExpression)) {
|
||||
const numberIndexInfo = getIndexInfoOfType(objectType, IndexKind.Number);
|
||||
if (numberIndexInfo) {
|
||||
getNodeLinks(node).resolvedIndexInfo = numberIndexInfo;
|
||||
@ -13801,15 +13867,19 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkClassForDuplicateDeclarations(node: ClassLikeDeclaration) {
|
||||
const getter = 1, setter = 2, property = getter | setter;
|
||||
const enum Accessor {
|
||||
Getter = 1,
|
||||
Setter = 2,
|
||||
Property = Getter | Setter
|
||||
}
|
||||
|
||||
const instanceNames = createMap<number>();
|
||||
const staticNames = createMap<number>();
|
||||
const instanceNames = createMap<Accessor>();
|
||||
const staticNames = createMap<Accessor>();
|
||||
for (const member of node.members) {
|
||||
if (member.kind === SyntaxKind.Constructor) {
|
||||
for (const param of (member as ConstructorDeclaration).parameters) {
|
||||
if (isParameterPropertyDeclaration(param)) {
|
||||
addName(instanceNames, param.name, (param.name as Identifier).text, property);
|
||||
addName(instanceNames, param.name, (param.name as Identifier).text, Accessor.Property);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13821,22 +13891,22 @@ namespace ts {
|
||||
if (memberName) {
|
||||
switch (member.kind) {
|
||||
case SyntaxKind.GetAccessor:
|
||||
addName(names, member.name, memberName, getter);
|
||||
addName(names, member.name, memberName, Accessor.Getter);
|
||||
break;
|
||||
|
||||
case SyntaxKind.SetAccessor:
|
||||
addName(names, member.name, memberName, setter);
|
||||
addName(names, member.name, memberName, Accessor.Setter);
|
||||
break;
|
||||
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
addName(names, member.name, memberName, property);
|
||||
addName(names, member.name, memberName, Accessor.Property);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addName(names: Map<number>, location: Node, name: string, meaning: number) {
|
||||
function addName(names: Map<Accessor>, location: Node, name: string, meaning: Accessor) {
|
||||
const prev = names[name];
|
||||
if (prev) {
|
||||
if (prev & meaning) {
|
||||
@ -15118,7 +15188,7 @@ namespace ts {
|
||||
else if (member.kind === SyntaxKind.Constructor) {
|
||||
for (const parameter of (<ConstructorDeclaration>member).parameters) {
|
||||
if (!parameter.symbol.isReferenced && parameter.flags & NodeFlags.Private) {
|
||||
error(parameter.name, Diagnostics._0_is_declared_but_never_used, parameter.symbol.name);
|
||||
error(parameter.name, Diagnostics.Property_0_is_declared_but_never_used, parameter.symbol.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -17041,11 +17111,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (compilerOptions.noImplicitAny && !node.body) {
|
||||
// Ambient shorthand module is an implicit any
|
||||
reportImplicitAnyError(node, anyType);
|
||||
}
|
||||
|
||||
if (node.body) {
|
||||
checkSourceElement(node.body);
|
||||
if (!isGlobalScopeAugmentation(node)) {
|
||||
@ -17549,11 +17614,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkSourceFile(node: SourceFile) {
|
||||
const start = performance.mark();
|
||||
|
||||
performance.mark("beforeCheck");
|
||||
checkSourceFileWorker(node);
|
||||
|
||||
performance.measure("Check", start);
|
||||
performance.mark("afterCheck");
|
||||
performance.measure("Check", "beforeCheck", "afterCheck");
|
||||
}
|
||||
|
||||
// Fully type check a source file and collect the relevant diagnostics.
|
||||
@ -18207,7 +18271,7 @@ namespace ts {
|
||||
// otherwise - check if at least one export is value
|
||||
symbolLinks.exportsSomeValue = hasExportAssignment
|
||||
? !!(moduleSymbol.flags & SymbolFlags.Value)
|
||||
: forEachValue(getExportsOfModule(moduleSymbol), isValue);
|
||||
: forEachProperty(getExportsOfModule(moduleSymbol), isValue);
|
||||
}
|
||||
|
||||
return symbolLinks.exportsSomeValue;
|
||||
|
||||
@ -61,10 +61,10 @@ namespace ts {
|
||||
},
|
||||
{
|
||||
name: "jsx",
|
||||
type: {
|
||||
type: createMap({
|
||||
"preserve": JsxEmit.Preserve,
|
||||
"react": JsxEmit.React
|
||||
},
|
||||
}),
|
||||
paramType: Diagnostics.KIND,
|
||||
description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_or_react,
|
||||
},
|
||||
@ -91,7 +91,7 @@ namespace ts {
|
||||
{
|
||||
name: "module",
|
||||
shortName: "m",
|
||||
type: {
|
||||
type: createMap({
|
||||
"none": ModuleKind.None,
|
||||
"commonjs": ModuleKind.CommonJS,
|
||||
"amd": ModuleKind.AMD,
|
||||
@ -99,16 +99,16 @@ namespace ts {
|
||||
"umd": ModuleKind.UMD,
|
||||
"es6": ModuleKind.ES6,
|
||||
"es2015": ModuleKind.ES2015,
|
||||
},
|
||||
}),
|
||||
description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015,
|
||||
paramType: Diagnostics.KIND,
|
||||
},
|
||||
{
|
||||
name: "newLine",
|
||||
type: {
|
||||
type: createMap({
|
||||
"crlf": NewLineKind.CarriageReturnLineFeed,
|
||||
"lf": NewLineKind.LineFeed
|
||||
},
|
||||
}),
|
||||
description: Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix,
|
||||
paramType: Diagnostics.NEWLINE,
|
||||
},
|
||||
@ -126,6 +126,10 @@ namespace ts {
|
||||
type: "boolean",
|
||||
description: Diagnostics.Do_not_emit_outputs_if_any_errors_were_reported,
|
||||
},
|
||||
{
|
||||
name: "noErrorTruncation",
|
||||
type: "boolean"
|
||||
},
|
||||
{
|
||||
name: "noImplicitAny",
|
||||
type: "boolean",
|
||||
@ -250,12 +254,12 @@ namespace ts {
|
||||
{
|
||||
name: "target",
|
||||
shortName: "t",
|
||||
type: {
|
||||
type: createMap({
|
||||
"es3": ScriptTarget.ES3,
|
||||
"es5": ScriptTarget.ES5,
|
||||
"es6": ScriptTarget.ES6,
|
||||
"es2015": ScriptTarget.ES2015,
|
||||
},
|
||||
}),
|
||||
description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015,
|
||||
paramType: Diagnostics.VERSION,
|
||||
},
|
||||
@ -284,10 +288,10 @@ namespace ts {
|
||||
},
|
||||
{
|
||||
name: "moduleResolution",
|
||||
type: {
|
||||
type: createMap({
|
||||
"node": ModuleResolutionKind.NodeJs,
|
||||
"classic": ModuleResolutionKind.Classic,
|
||||
},
|
||||
}),
|
||||
description: Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6,
|
||||
},
|
||||
{
|
||||
@ -392,7 +396,7 @@ namespace ts {
|
||||
type: "list",
|
||||
element: {
|
||||
name: "lib",
|
||||
type: {
|
||||
type: createMap({
|
||||
// JavaScript only
|
||||
"es5": "lib.es5.d.ts",
|
||||
"es6": "lib.es2015.d.ts",
|
||||
@ -417,7 +421,7 @@ namespace ts {
|
||||
"es2016.array.include": "lib.es2016.array.include.d.ts",
|
||||
"es2017.object": "lib.es2017.object.d.ts",
|
||||
"es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts"
|
||||
},
|
||||
}),
|
||||
},
|
||||
description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon
|
||||
},
|
||||
@ -462,6 +466,14 @@ namespace ts {
|
||||
shortOptionNames: Map<string>;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const defaultInitCompilerOptions: CompilerOptions = {
|
||||
module: ModuleKind.CommonJS,
|
||||
target: ScriptTarget.ES5,
|
||||
noImplicitAny: false,
|
||||
sourceMap: false,
|
||||
};
|
||||
|
||||
let optionNameMapCache: OptionNameMap;
|
||||
|
||||
/* @internal */
|
||||
@ -486,10 +498,9 @@ namespace ts {
|
||||
/* @internal */
|
||||
export function createCompilerDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType): Diagnostic {
|
||||
const namesOfType: string[] = [];
|
||||
forEachKey(opt.type, key => {
|
||||
for (const key in opt.type) {
|
||||
namesOfType.push(` '${key}'`);
|
||||
});
|
||||
|
||||
}
|
||||
return createCompilerDiagnostic(Diagnostics.Argument_for_0_option_must_be_Colon_1, `--${opt.name}`, namesOfType);
|
||||
}
|
||||
|
||||
@ -497,7 +508,7 @@ namespace ts {
|
||||
export function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) {
|
||||
const key = trimString((value || "")).toLowerCase();
|
||||
const map = opt.type;
|
||||
if (hasProperty(map, key)) {
|
||||
if (key in map) {
|
||||
return map[key];
|
||||
}
|
||||
else {
|
||||
@ -551,11 +562,11 @@ namespace ts {
|
||||
s = s.slice(s.charCodeAt(1) === CharacterCodes.minus ? 2 : 1).toLowerCase();
|
||||
|
||||
// Try to translate short option names to their full equivalents.
|
||||
if (hasProperty(shortOptionNames, s)) {
|
||||
if (s in shortOptionNames) {
|
||||
s = shortOptionNames[s];
|
||||
}
|
||||
|
||||
if (hasProperty(optionNameMap, s)) {
|
||||
if (s in optionNameMap) {
|
||||
const opt = optionNameMap[s];
|
||||
|
||||
if (opt.isTSConfigOnly) {
|
||||
@ -668,6 +679,94 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate tsconfig configuration when running command line "--init"
|
||||
* @param options commandlineOptions to be generated into tsconfig.json
|
||||
* @param fileNames array of filenames to be generated into tsconfig.json
|
||||
*/
|
||||
/* @internal */
|
||||
export function generateTSConfig(options: CompilerOptions, fileNames: string[]): { compilerOptions: Map<CompilerOptionsValue> } {
|
||||
const compilerOptions = extend(options, defaultInitCompilerOptions);
|
||||
const configurations: any = {
|
||||
compilerOptions: serializeCompilerOptions(compilerOptions)
|
||||
};
|
||||
if (fileNames && fileNames.length) {
|
||||
// only set the files property if we have at least one file
|
||||
configurations.files = fileNames;
|
||||
}
|
||||
|
||||
return configurations;
|
||||
|
||||
function getCustomTypeMapOfCommandLineOption(optionDefinition: CommandLineOption): Map<string | number> | undefined {
|
||||
if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean") {
|
||||
// this is of a type CommandLineOptionOfPrimitiveType
|
||||
return undefined;
|
||||
}
|
||||
else if (optionDefinition.type === "list") {
|
||||
return getCustomTypeMapOfCommandLineOption((<CommandLineOptionOfListType>optionDefinition).element);
|
||||
}
|
||||
else {
|
||||
return (<CommandLineOptionOfCustomType>optionDefinition).type;
|
||||
}
|
||||
}
|
||||
|
||||
function getNameOfCompilerOptionValue(value: CompilerOptionsValue, customTypeMap: MapLike<string | number>): string | undefined {
|
||||
// There is a typeMap associated with this command-line option so use it to map value back to its name
|
||||
for (const key in customTypeMap) {
|
||||
if (customTypeMap[key] === value) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function serializeCompilerOptions(options: CompilerOptions): Map<CompilerOptionsValue> {
|
||||
const result = createMap<CompilerOptionsValue>();
|
||||
const optionsNameMap = getOptionNameMap().optionNameMap;
|
||||
|
||||
for (const name in options) {
|
||||
if (hasProperty(options, name)) {
|
||||
// tsconfig only options cannot be specified via command line,
|
||||
// so we can assume that only types that can appear here string | number | boolean
|
||||
switch (name) {
|
||||
case "init":
|
||||
case "watch":
|
||||
case "version":
|
||||
case "help":
|
||||
case "project":
|
||||
break;
|
||||
default:
|
||||
const value = options[name];
|
||||
let optionDefinition = optionsNameMap[name.toLowerCase()];
|
||||
if (optionDefinition) {
|
||||
const customTypeMap = getCustomTypeMapOfCommandLineOption(optionDefinition);
|
||||
if (!customTypeMap) {
|
||||
// There is no map associated with this compiler option then use the value as-is
|
||||
// This is the case if the value is expect to be string, number, boolean or list of string
|
||||
result[name] = value;
|
||||
}
|
||||
else {
|
||||
if (optionDefinition.type === "list") {
|
||||
const convertedValue: string[] = [];
|
||||
for (const element of value as (string | number)[]) {
|
||||
convertedValue.push(getNameOfCompilerOptionValue(element, customTypeMap));
|
||||
}
|
||||
result[name] = convertedValue;
|
||||
}
|
||||
else {
|
||||
// There is a typeMap associated with this command-line option so use it to map value back to its name
|
||||
result[name] = getNameOfCompilerOptionValue(value, customTypeMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the comments from a json like text.
|
||||
* Comments can be single line comments (starting with # or //) or multiline comments using / * * /
|
||||
@ -811,7 +910,7 @@ namespace ts {
|
||||
const optionNameMap = arrayToMap(optionDeclarations, opt => opt.name);
|
||||
|
||||
for (const id in jsonOptions) {
|
||||
if (hasProperty(optionNameMap, id)) {
|
||||
if (id in optionNameMap) {
|
||||
const opt = optionNameMap[id];
|
||||
defaultOptions[opt.name] = convertJsonOption(opt, jsonOptions[id], basePath, errors);
|
||||
}
|
||||
@ -848,7 +947,7 @@ namespace ts {
|
||||
|
||||
function convertJsonOptionOfCustomType(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) {
|
||||
const key = value.toLowerCase();
|
||||
if (hasProperty(opt.type, key)) {
|
||||
if (key in opt.type) {
|
||||
return opt.type[key];
|
||||
}
|
||||
else {
|
||||
@ -1011,7 +1110,7 @@ namespace ts {
|
||||
removeWildcardFilesWithLowerPriorityExtension(file, wildcardFileMap, supportedExtensions, keyMapper);
|
||||
|
||||
const key = keyMapper(file);
|
||||
if (!hasProperty(literalFileMap, key) && !hasProperty(wildcardFileMap, key)) {
|
||||
if (!(key in literalFileMap) && !(key in wildcardFileMap)) {
|
||||
wildcardFileMap[key] = file;
|
||||
}
|
||||
}
|
||||
@ -1076,7 +1175,7 @@ namespace ts {
|
||||
if (match) {
|
||||
const key = useCaseSensitiveFileNames ? match[0] : match[0].toLowerCase();
|
||||
const flags = watchRecursivePattern.test(name) ? WatchDirectoryFlags.Recursive : WatchDirectoryFlags.None;
|
||||
const existingFlags = getProperty(wildcardDirectories, key);
|
||||
const existingFlags = wildcardDirectories[key];
|
||||
if (existingFlags === undefined || existingFlags < flags) {
|
||||
wildcardDirectories[key] = flags;
|
||||
if (flags === WatchDirectoryFlags.Recursive) {
|
||||
@ -1088,11 +1187,9 @@ namespace ts {
|
||||
|
||||
// Remove any subpaths under an existing recursively watched directory.
|
||||
for (const key in wildcardDirectories) {
|
||||
if (hasProperty(wildcardDirectories, key)) {
|
||||
for (const recursiveKey of recursiveKeys) {
|
||||
if (key !== recursiveKey && containsPath(recursiveKey, key, path, !useCaseSensitiveFileNames)) {
|
||||
delete wildcardDirectories[key];
|
||||
}
|
||||
for (const recursiveKey of recursiveKeys) {
|
||||
if (key !== recursiveKey && containsPath(recursiveKey, key, path, !useCaseSensitiveFileNames)) {
|
||||
delete wildcardDirectories[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1115,7 +1212,7 @@ namespace ts {
|
||||
for (let i = ExtensionPriority.Highest; i < adjustedExtensionPriority; i++) {
|
||||
const higherPriorityExtension = extensions[i];
|
||||
const higherPriorityPath = keyMapper(changeExtension(file, higherPriorityExtension));
|
||||
if (hasProperty(literalFiles, higherPriorityPath) || hasProperty(wildcardFiles, higherPriorityPath)) {
|
||||
if (higherPriorityPath in literalFiles || higherPriorityPath in wildcardFiles) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,10 +21,8 @@ namespace ts {
|
||||
|
||||
const createObject = Object.create;
|
||||
|
||||
export function createMap<T>(): Map<T> {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
const map: Map<T> = createObject(null);
|
||||
/* tslint:enable:no-null-keyword */
|
||||
export function createMap<T>(template?: MapLike<T>): Map<T> {
|
||||
const map: Map<T> = createObject(null); // tslint:disable-line:no-null-keyword
|
||||
|
||||
// Using 'delete' on an object causes V8 to put the object in dictionary mode.
|
||||
// This disables creation of hidden classes, which are expensive when an object is
|
||||
@ -32,6 +30,12 @@ namespace ts {
|
||||
map["__"] = undefined;
|
||||
delete map["__"];
|
||||
|
||||
// Copies keys/values from template. Note that for..in will not throw if
|
||||
// template is undefined, and instead will just exit the loop.
|
||||
for (const key in template) if (hasOwnProperty.call(template, key)) {
|
||||
map[key] = template[key];
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@ -62,7 +66,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function contains(path: Path) {
|
||||
return hasProperty(files, toKey(path));
|
||||
return toKey(path) in files;
|
||||
}
|
||||
|
||||
function remove(path: Path) {
|
||||
@ -202,6 +206,21 @@ namespace ts {
|
||||
return array;
|
||||
}
|
||||
|
||||
export function removeWhere<T>(array: T[], f: (x: T) => boolean): boolean {
|
||||
let outIndex = 0;
|
||||
for (const item of array) {
|
||||
if (!f(item)) {
|
||||
array[outIndex] = item;
|
||||
outIndex++;
|
||||
}
|
||||
}
|
||||
if (outIndex !== array.length) {
|
||||
array.length = outIndex;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function filterMutate<T>(array: T[], f: (x: T) => boolean): void {
|
||||
let outIndex = 0;
|
||||
for (const item of array) {
|
||||
@ -364,82 +383,142 @@ namespace ts {
|
||||
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
/**
|
||||
* Indicates whether a map-like contains an own property with the specified key.
|
||||
*
|
||||
* NOTE: This is intended for use only with MapLike<T> objects. For Map<T> objects, use
|
||||
* the 'in' operator.
|
||||
*
|
||||
* @param map A map-like.
|
||||
* @param key A property key.
|
||||
*/
|
||||
export function hasProperty<T>(map: MapLike<T>, key: string): boolean {
|
||||
return hasOwnProperty.call(map, key);
|
||||
}
|
||||
|
||||
export function getKeys<T>(map: MapLike<T>): string[] {
|
||||
/**
|
||||
* Gets the value of an owned property in a map-like.
|
||||
*
|
||||
* NOTE: This is intended for use only with MapLike<T> objects. For Map<T> objects, use
|
||||
* an indexer.
|
||||
*
|
||||
* @param map A map-like.
|
||||
* @param key A property key.
|
||||
*/
|
||||
export function getProperty<T>(map: MapLike<T>, key: string): T | undefined {
|
||||
return hasOwnProperty.call(map, key) ? map[key] : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the owned, enumerable property keys of a map-like.
|
||||
*
|
||||
* NOTE: This is intended for use with MapLike<T> objects. For Map<T> objects, use
|
||||
* Object.keys instead as it offers better performance.
|
||||
*
|
||||
* @param map A map-like.
|
||||
*/
|
||||
export function getOwnKeys<T>(map: MapLike<T>): string[] {
|
||||
const keys: string[] = [];
|
||||
for (const key in map) {
|
||||
for (const key in map) if (hasOwnProperty.call(map, key)) {
|
||||
keys.push(key);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
export function getProperty<T>(map: MapLike<T>, key: string): T | undefined {
|
||||
return hasProperty(map, key) ? map[key] : undefined;
|
||||
/**
|
||||
* Enumerates the properties of a Map<T>, invoking a callback and returning the first truthy result.
|
||||
*
|
||||
* @param map A map for which properties should be enumerated.
|
||||
* @param callback A callback to invoke for each property.
|
||||
*/
|
||||
export function forEachProperty<T, U>(map: Map<T>, callback: (value: T, key: string) => U): U {
|
||||
let result: U;
|
||||
for (const key in map) {
|
||||
if (result = callback(map[key], key)) break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getOrUpdateProperty<T>(map: MapLike<T>, key: string, makeValue: () => T): T {
|
||||
return hasProperty(map, key) ? map[key] : map[key] = makeValue();
|
||||
/**
|
||||
* Returns true if a Map<T> has some matching property.
|
||||
*
|
||||
* @param map A map whose properties should be tested.
|
||||
* @param predicate An optional callback used to test each property.
|
||||
*/
|
||||
export function someProperties<T>(map: Map<T>, predicate?: (value: T, key: string) => boolean) {
|
||||
for (const key in map) {
|
||||
if (!predicate || predicate(map[key], key)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isEmpty<T>(map: MapLike<T>) {
|
||||
for (const id in map) {
|
||||
if (hasProperty(map, id)) {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Performs a shallow copy of the properties from a source Map<T> to a target MapLike<T>
|
||||
*
|
||||
* @param source A map from which properties should be copied.
|
||||
* @param target A map to which properties should be copied.
|
||||
*/
|
||||
export function copyProperties<T>(source: Map<T>, target: MapLike<T>): void {
|
||||
for (const key in source) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce the properties of a map.
|
||||
*
|
||||
* NOTE: This is intended for use with Map<T> objects. For MapLike<T> objects, use
|
||||
* reduceOwnProperties instead as it offers better runtime safety.
|
||||
*
|
||||
* @param map The map to reduce
|
||||
* @param callback An aggregation function that is called for each entry in the map
|
||||
* @param initial The initial value for the reduction.
|
||||
*/
|
||||
export function reduceProperties<T, U>(map: Map<T>, callback: (aggregate: U, value: T, key: string) => U, initial: U): U {
|
||||
let result = initial;
|
||||
for (const key in map) {
|
||||
result = callback(result, map[key], String(key));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce the properties defined on a map-like (but not from its prototype chain).
|
||||
*
|
||||
* NOTE: This is intended for use with MapLike<T> objects. For Map<T> objects, use
|
||||
* reduceProperties instead as it offers better performance.
|
||||
*
|
||||
* @param map The map-like to reduce
|
||||
* @param callback An aggregation function that is called for each entry in the map
|
||||
* @param initial The initial value for the reduction.
|
||||
*/
|
||||
export function reduceOwnProperties<T, U>(map: MapLike<T>, callback: (aggregate: U, value: T, key: string) => U, initial: U): U {
|
||||
let result = initial;
|
||||
for (const key in map) if (hasOwnProperty.call(map, key)) {
|
||||
result = callback(result, map[key], String(key));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a shallow equality comparison of the contents of two map-likes.
|
||||
*
|
||||
* @param left A map-like whose properties should be compared.
|
||||
* @param right A map-like whose properties should be compared.
|
||||
*/
|
||||
export function equalOwnProperties<T>(left: MapLike<T>, right: MapLike<T>, equalityComparer?: (left: T, right: T) => boolean) {
|
||||
if (left === right) return true;
|
||||
if (!left || !right) return false;
|
||||
for (const key in left) if (hasOwnProperty.call(left, key)) {
|
||||
if (!hasOwnProperty.call(right, key) === undefined) return false;
|
||||
if (equalityComparer ? !equalityComparer(left[key], right[key]) : left[key] !== right[key]) return false;
|
||||
}
|
||||
for (const key in right) if (hasOwnProperty.call(right, key)) {
|
||||
if (!hasOwnProperty.call(left, key)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export function clone<T>(object: T): T {
|
||||
const result: any = {};
|
||||
for (const id in object) {
|
||||
result[id] = (<any>object)[id];
|
||||
}
|
||||
return <T>result;
|
||||
}
|
||||
|
||||
export function extend<T1 extends MapLike<{}>, T2 extends MapLike<{}>>(first: T1 , second: T2): T1 & T2 {
|
||||
const result: T1 & T2 = <any>{};
|
||||
for (const id in first) {
|
||||
(result as any)[id] = first[id];
|
||||
}
|
||||
for (const id in second) {
|
||||
if (!hasProperty(result, id)) {
|
||||
(result as any)[id] = second[id];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function forEachValue<T, U>(map: MapLike<T>, callback: (value: T) => U): U {
|
||||
let result: U;
|
||||
for (const id in map) {
|
||||
if (result = callback(map[id])) break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function forEachKey<T, U>(map: MapLike<T>, callback: (key: string) => U): U {
|
||||
let result: U;
|
||||
for (const id in map) {
|
||||
if (result = callback(id)) break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function lookUp<T>(map: MapLike<T>, key: string): T {
|
||||
return hasProperty(map, key) ? map[key] : undefined;
|
||||
}
|
||||
|
||||
export function copyMap<T>(source: MapLike<T>, target: MapLike<T>): void {
|
||||
for (const p in source) {
|
||||
target[p] = source[p];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a map from the elements of an array.
|
||||
*
|
||||
@ -450,33 +529,40 @@ namespace ts {
|
||||
* the same key with the given 'makeKey' function, then the element with the higher
|
||||
* index in the array will be the one associated with the produced key.
|
||||
*/
|
||||
export function arrayToMap<T>(array: T[], makeKey: (value: T) => string): Map<T> {
|
||||
const result = createMap<T>();
|
||||
|
||||
forEach(array, value => {
|
||||
result[makeKey(value)] = value;
|
||||
});
|
||||
|
||||
export function arrayToMap<T>(array: T[], makeKey: (value: T) => string): Map<T>;
|
||||
export function arrayToMap<T, U>(array: T[], makeKey: (value: T) => string, makeValue: (value: T) => U): Map<U>;
|
||||
export function arrayToMap<T, U>(array: T[], makeKey: (value: T) => string, makeValue?: (value: T) => U): Map<T | U> {
|
||||
const result = createMap<T | U>();
|
||||
for (const value of array) {
|
||||
result[makeKey(value)] = makeValue ? makeValue(value) : value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce the properties of a map.
|
||||
*
|
||||
* @param map The map to reduce
|
||||
* @param callback An aggregation function that is called for each entry in the map
|
||||
* @param initial The initial value for the reduction.
|
||||
*/
|
||||
export function reduceProperties<T, U>(map: MapLike<T>, callback: (aggregate: U, value: T, key: string) => U, initial: U): U {
|
||||
let result = initial;
|
||||
if (map) {
|
||||
for (const key in map) {
|
||||
if (hasProperty(map, key)) {
|
||||
result = callback(result, map[key], String(key));
|
||||
}
|
||||
export function cloneMap<T>(map: Map<T>) {
|
||||
const clone = createMap<T>();
|
||||
copyProperties(map, clone);
|
||||
return clone;
|
||||
}
|
||||
|
||||
export function clone<T>(object: T): T {
|
||||
const result: any = {};
|
||||
for (const id in object) {
|
||||
if (hasOwnProperty.call(object, id)) {
|
||||
result[id] = (<any>object)[id];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function extend<T1, T2>(first: T1 , second: T2): T1 & T2 {
|
||||
const result: T1 & T2 = <any>{};
|
||||
for (const id in second) if (hasOwnProperty.call(second, id)) {
|
||||
(result as any)[id] = (second as any)[id];
|
||||
}
|
||||
for (const id in first) if (hasOwnProperty.call(first, id)) {
|
||||
(result as any)[id] = (first as any)[id];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -157,9 +157,7 @@ namespace ts {
|
||||
|
||||
if (usedTypeDirectiveReferences) {
|
||||
for (const directive in usedTypeDirectiveReferences) {
|
||||
if (hasProperty(usedTypeDirectiveReferences, directive)) {
|
||||
referencesOutput += `/// <reference types="${directive}" />${newLine}`;
|
||||
}
|
||||
referencesOutput += `/// <reference types="${directive}" />${newLine}`;
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,7 +270,7 @@ namespace ts {
|
||||
usedTypeDirectiveReferences = createMap<string>();
|
||||
}
|
||||
for (const directive of typeReferenceDirectives) {
|
||||
if (!hasProperty(usedTypeDirectiveReferences, directive)) {
|
||||
if (!(directive in usedTypeDirectiveReferences)) {
|
||||
usedTypeDirectiveReferences[directive] = directive;
|
||||
}
|
||||
}
|
||||
@ -537,14 +535,14 @@ namespace ts {
|
||||
// do not need to keep track of created temp names.
|
||||
function getExportDefaultTempVariableName(): string {
|
||||
const baseName = "_default";
|
||||
if (!hasProperty(currentIdentifiers, baseName)) {
|
||||
if (!(baseName in currentIdentifiers)) {
|
||||
return baseName;
|
||||
}
|
||||
let count = 0;
|
||||
while (true) {
|
||||
count++;
|
||||
const name = baseName + "_" + count;
|
||||
if (!hasProperty(currentIdentifiers, name)) {
|
||||
if (!(name in currentIdentifiers)) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2235,7 +2235,7 @@
|
||||
"category": "Error",
|
||||
"code": 4082
|
||||
},
|
||||
"Conflicting library definitions for '{0}' found at '{1}' and '{2}'. Copy the correct file to the 'typings' folder to resolve this conflict.": {
|
||||
"Conflicting definitions for '{0}' found at '{1}' and '{2}'. Consider installing a specific version of this library to resolve the conflict.": {
|
||||
"category": "Message",
|
||||
"code": 4090
|
||||
},
|
||||
@ -2832,6 +2832,10 @@
|
||||
"category": "Message",
|
||||
"code": 6137
|
||||
},
|
||||
"Property '{0}' is declared but never used.": {
|
||||
"category": "Error",
|
||||
"code": 6138
|
||||
},
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
"code": 7005
|
||||
|
||||
@ -24,7 +24,7 @@ namespace ts {
|
||||
Return = 1 << 3
|
||||
}
|
||||
|
||||
const entities: MapLike<number> = {
|
||||
const entities = createMap({
|
||||
"quot": 0x0022,
|
||||
"amp": 0x0026,
|
||||
"apos": 0x0027,
|
||||
@ -278,7 +278,7 @@ namespace ts {
|
||||
"clubs": 0x2663,
|
||||
"hearts": 0x2665,
|
||||
"diams": 0x2666
|
||||
};
|
||||
});
|
||||
|
||||
// Flags enum to track count of temp variables and a few dedicated names
|
||||
const enum TempFlags {
|
||||
@ -407,7 +407,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
|
||||
function isUniqueLocalName(name: string, container: Node): boolean {
|
||||
for (let node = container; isNodeDescendentOf(node, container); node = node.nextContainer) {
|
||||
if (node.locals && hasProperty(node.locals, name)) {
|
||||
if (node.locals && name in node.locals) {
|
||||
// We conservatively include alias symbols to cover cases where they're emitted as locals
|
||||
if (node.locals[name].flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) {
|
||||
return false;
|
||||
@ -531,7 +531,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
let currentText: string;
|
||||
let currentLineMap: number[];
|
||||
let currentFileIdentifiers: Map<string>;
|
||||
let renamedDependencies: MapLike<string>;
|
||||
let renamedDependencies: Map<string>;
|
||||
let isEs6Module: boolean;
|
||||
let isCurrentFileExternalModule: boolean;
|
||||
|
||||
@ -577,21 +577,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
|
||||
const setSourceMapWriterEmit = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? changeSourceMapEmit : function (writer: SourceMapWriter) { };
|
||||
|
||||
const moduleEmitDelegates: MapLike<(node: SourceFile, emitRelativePathAsModuleName?: boolean) => void> = {
|
||||
const moduleEmitDelegates = createMap<(node: SourceFile, emitRelativePathAsModuleName?: boolean) => void>({
|
||||
[ModuleKind.ES6]: emitES6Module,
|
||||
[ModuleKind.AMD]: emitAMDModule,
|
||||
[ModuleKind.System]: emitSystemModule,
|
||||
[ModuleKind.UMD]: emitUMDModule,
|
||||
[ModuleKind.CommonJS]: emitCommonJSModule,
|
||||
};
|
||||
});
|
||||
|
||||
const bundleEmitDelegates: MapLike<(node: SourceFile, emitRelativePathAsModuleName?: boolean) => void> = {
|
||||
const bundleEmitDelegates = createMap<(node: SourceFile, emitRelativePathAsModuleName?: boolean) => void>({
|
||||
[ModuleKind.ES6]() {},
|
||||
[ModuleKind.AMD]: emitAMDModule,
|
||||
[ModuleKind.System]: emitSystemModule,
|
||||
[ModuleKind.UMD]() {},
|
||||
[ModuleKind.CommonJS]() {},
|
||||
};
|
||||
});
|
||||
|
||||
return doEmit;
|
||||
|
||||
@ -669,8 +669,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
|
||||
function isUniqueName(name: string): boolean {
|
||||
return !resolver.hasGlobalName(name) &&
|
||||
!hasProperty(currentFileIdentifiers, name) &&
|
||||
!hasProperty(generatedNameSet, name);
|
||||
!(name in currentFileIdentifiers) &&
|
||||
!(name in generatedNameSet);
|
||||
}
|
||||
|
||||
// Return the next available name in the pattern _a ... _z, _0, _1, ...
|
||||
@ -2646,7 +2646,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
return false;
|
||||
}
|
||||
|
||||
return !exportEquals && exportSpecifiers && hasProperty(exportSpecifiers, (<Identifier>node).text);
|
||||
return !exportEquals && exportSpecifiers && (<Identifier>node).text in exportSpecifiers;
|
||||
}
|
||||
|
||||
function emitPrefixUnaryExpression(node: PrefixUnaryExpression) {
|
||||
@ -3263,7 +3263,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
write(", ");
|
||||
}
|
||||
|
||||
if (!hasProperty(seen, id.text)) {
|
||||
if (!(id.text in seen)) {
|
||||
emit(id);
|
||||
seen[id.text] = id.text;
|
||||
}
|
||||
@ -3970,7 +3970,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
return;
|
||||
}
|
||||
|
||||
if (!exportEquals && exportSpecifiers && hasProperty(exportSpecifiers, name.text)) {
|
||||
if (!exportEquals && exportSpecifiers && name.text in exportSpecifiers) {
|
||||
for (const specifier of exportSpecifiers[name.text]) {
|
||||
writeLine();
|
||||
emitStart(specifier.name);
|
||||
@ -5311,18 +5311,22 @@ const _super = (function (geti, seti) {
|
||||
emitSignatureParameters(ctor);
|
||||
}
|
||||
else {
|
||||
// Based on EcmaScript6 section 14.5.14: Runtime Semantics: ClassDefinitionEvaluation.
|
||||
// If constructor is empty, then,
|
||||
// If ClassHeritageopt is present, then
|
||||
// Let constructor be the result of parsing the String "constructor(... args){ super (...args);}" using the syntactic grammar with the goal symbol MethodDefinition.
|
||||
// The ES2015 spec specifies in 14.5.14. Runtime Semantics: ClassDefinitionEvaluation:
|
||||
// If constructor is empty, then
|
||||
// If ClassHeritag_eopt is present and protoParent is not null, then
|
||||
// Let constructor be the result of parsing the source text
|
||||
// constructor(...args) { super (...args);}
|
||||
// using the syntactic grammar with the goal symbol MethodDefinition[~Yield].
|
||||
// Else,
|
||||
// Let constructor be the result of parsing the String "constructor( ){ }" using the syntactic grammar with the goal symbol MethodDefinition
|
||||
if (baseTypeElement) {
|
||||
write("(...args)");
|
||||
}
|
||||
else {
|
||||
write("()");
|
||||
}
|
||||
// Let constructor be the result of parsing the source text
|
||||
// constructor( ){ }
|
||||
// using the syntactic grammar with the goal symbol MethodDefinition[~Yield].
|
||||
//
|
||||
// While we could emit the '...args' rest parameter, certain later tools in the pipeline might
|
||||
// downlevel the '...args' portion less efficiently by naively copying the contents of 'arguments' to an array.
|
||||
// Instead, we'll avoid using a rest parameter and spread into the super call as
|
||||
// 'super(...arguments)' instead of 'super(...args)', as you can see below.
|
||||
write("()");
|
||||
}
|
||||
}
|
||||
|
||||
@ -5360,7 +5364,8 @@ const _super = (function (geti, seti) {
|
||||
write("_super.apply(this, arguments);");
|
||||
}
|
||||
else {
|
||||
write("super(...args);");
|
||||
// See comment above on using '...arguments' instead of '...args'.
|
||||
write("super(...arguments);");
|
||||
}
|
||||
emitEnd(baseTypeElement);
|
||||
}
|
||||
@ -6461,7 +6466,7 @@ const _super = (function (geti, seti) {
|
||||
* Here we check if alternative name was provided for a given moduleName and return it if possible.
|
||||
*/
|
||||
function tryRenameExternalModule(moduleName: LiteralExpression): string {
|
||||
if (renamedDependencies && hasProperty(renamedDependencies, moduleName.text)) {
|
||||
if (renamedDependencies && moduleName.text in renamedDependencies) {
|
||||
return `"${renamedDependencies[moduleName.text]}"`;
|
||||
}
|
||||
return undefined;
|
||||
@ -6842,7 +6847,7 @@ const _super = (function (geti, seti) {
|
||||
// export { x, y }
|
||||
for (const specifier of (<ExportDeclaration>node).exportClause.elements) {
|
||||
const name = (specifier.propertyName || specifier.name).text;
|
||||
getOrUpdateProperty(exportSpecifiers, name, () => []).push(specifier);
|
||||
(exportSpecifiers[name] || (exportSpecifiers[name] = [])).push(specifier);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -6941,7 +6946,7 @@ const _super = (function (geti, seti) {
|
||||
}
|
||||
|
||||
// local names set should only be added if we have anything exported
|
||||
if (!exportedDeclarations && isEmpty(exportSpecifiers)) {
|
||||
if (!exportedDeclarations && !someProperties(exportSpecifiers)) {
|
||||
// no exported declarations (export var ...) or export specifiers (export {x})
|
||||
// check if we have any non star export declarations.
|
||||
let hasExportDeclarationWithExportClause = false;
|
||||
@ -7091,7 +7096,7 @@ const _super = (function (geti, seti) {
|
||||
if (name) {
|
||||
// do not emit duplicate entries (in case of declaration merging) in the list of hoisted variables
|
||||
const text = unescapeIdentifier(name.text);
|
||||
if (hasProperty(seen, text)) {
|
||||
if (text in seen) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
@ -7460,7 +7465,7 @@ const _super = (function (geti, seti) {
|
||||
// for deduplication purposes in key remove leading and trailing quotes so 'a' and "a" will be considered the same
|
||||
const key = text.substr(1, text.length - 2);
|
||||
|
||||
if (hasProperty(groupIndices, key)) {
|
||||
if (key in groupIndices) {
|
||||
// deduplicate/group entries in dependency list by the dependency name
|
||||
const groupIndex = groupIndices[key];
|
||||
dependencyGroups[groupIndex].push(externalImports[i]);
|
||||
|
||||
@ -417,14 +417,16 @@ namespace ts {
|
||||
case SyntaxKind.JSDocPropertyTag:
|
||||
return visitNode(cbNode, (<JSDocPropertyTag>node).typeExpression) ||
|
||||
visitNode(cbNode, (<JSDocPropertyTag>node).name);
|
||||
case SyntaxKind.JSDocLiteralType:
|
||||
return visitNode(cbNode, (<JSDocLiteralType>node).literal);
|
||||
}
|
||||
}
|
||||
|
||||
export function createSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, setParentNodes = false, scriptKind?: ScriptKind): SourceFile {
|
||||
const start = performance.mark();
|
||||
performance.mark("beforeParse");
|
||||
const result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind);
|
||||
|
||||
performance.measure("Parse", start);
|
||||
performance.mark("afterParse");
|
||||
performance.measure("Parse", "beforeParse", "afterParse");
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -5889,9 +5891,13 @@ namespace ts {
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.VoidKeyword:
|
||||
return parseTokenNode<JSDocType>();
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
return parseJSDocLiteralType();
|
||||
}
|
||||
|
||||
// TODO (drosen): Parse string literal types in JSDoc as well.
|
||||
return parseJSDocTypeReference();
|
||||
}
|
||||
|
||||
@ -6070,6 +6076,12 @@ namespace ts {
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function parseJSDocLiteralType(): JSDocLiteralType {
|
||||
const result = <JSDocLiteralType>createNode(SyntaxKind.JSDocLiteralType);
|
||||
result.literal = parseLiteralTypeNode();
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function parseJSDocUnknownOrNullableType(): JSDocUnknownType | JSDocNullableType {
|
||||
const pos = scanner.getStartPos();
|
||||
// skip the ?
|
||||
|
||||
@ -6,71 +6,57 @@ namespace ts {
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
/** Performance measurements for the compiler. */
|
||||
namespace ts.performance {
|
||||
/** Performance measurements for the compiler. */
|
||||
declare const onProfilerEvent: { (markName: string): void; profiler: boolean; };
|
||||
let profilerEvent: (markName: string) => void;
|
||||
let counters: MapLike<number>;
|
||||
let measures: MapLike<number>;
|
||||
|
||||
const profilerEvent = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true
|
||||
? onProfilerEvent
|
||||
: (markName: string) => { };
|
||||
|
||||
let enabled = false;
|
||||
let profilerStart = 0;
|
||||
let counts: Map<number>;
|
||||
let marks: Map<number>;
|
||||
let measures: Map<number>;
|
||||
|
||||
/**
|
||||
* Emit a performance event if ts-profiler is connected. This is primarily used
|
||||
* to generate heap snapshots.
|
||||
* Marks a performance event.
|
||||
*
|
||||
* @param eventName A name for the event.
|
||||
* @param markName The name of the mark.
|
||||
*/
|
||||
export function emit(eventName: string) {
|
||||
if (profilerEvent) {
|
||||
profilerEvent(eventName);
|
||||
export function mark(markName: string) {
|
||||
if (enabled) {
|
||||
marks[markName] = timestamp();
|
||||
counts[markName] = (counts[markName] || 0) + 1;
|
||||
profilerEvent(markName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments a counter with the specified name.
|
||||
*
|
||||
* @param counterName The name of the counter.
|
||||
*/
|
||||
export function increment(counterName: string) {
|
||||
if (counters) {
|
||||
counters[counterName] = (getProperty(counters, counterName) || 0) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the counter with the specified name.
|
||||
*
|
||||
* @param counterName The name of the counter.
|
||||
*/
|
||||
export function getCount(counterName: string) {
|
||||
return counters && getProperty(counters, counterName) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the start of a performance measurement.
|
||||
*/
|
||||
export function mark() {
|
||||
return measures ? timestamp() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a performance measurement with the specified name.
|
||||
*
|
||||
* @param measureName The name of the performance measurement.
|
||||
* @param marker The timestamp of the starting mark.
|
||||
* @param startMarkName The name of the starting mark. If not supplied, the point at which the
|
||||
* profiler was enabled is used.
|
||||
* @param endMarkName The name of the ending mark. If not supplied, the current timestamp is
|
||||
* used.
|
||||
*/
|
||||
export function measure(measureName: string, marker: number) {
|
||||
if (measures) {
|
||||
measures[measureName] = (getProperty(measures, measureName) || 0) + (timestamp() - marker);
|
||||
export function measure(measureName: string, startMarkName?: string, endMarkName?: string) {
|
||||
if (enabled) {
|
||||
const end = endMarkName && marks[endMarkName] || timestamp();
|
||||
const start = startMarkName && marks[startMarkName] || profilerStart;
|
||||
measures[measureName] = (measures[measureName] || 0) + (end - start);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate over each measure, performing some action
|
||||
*
|
||||
* @param cb The action to perform for each measure
|
||||
* Gets the number of times a marker was encountered.
|
||||
*
|
||||
* @param markName The name of the mark.
|
||||
*/
|
||||
export function forEachMeasure(cb: (measureName: string, duration: number) => void) {
|
||||
return forEachKey(measures, key => cb(key, measures[key]));
|
||||
export function getCount(markName: string) {
|
||||
return counts && counts[markName] || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,31 +65,31 @@ namespace ts.performance {
|
||||
* @param measureName The name of the measure whose durations should be accumulated.
|
||||
*/
|
||||
export function getDuration(measureName: string) {
|
||||
return measures && getProperty(measures, measureName) || 0;
|
||||
return measures && measures[measureName] || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate over each measure, performing some action
|
||||
*
|
||||
* @param cb The action to perform for each measure
|
||||
*/
|
||||
export function forEachMeasure(cb: (measureName: string, duration: number) => void) {
|
||||
for (const key in measures) {
|
||||
cb(key, measures[key]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Enables (and resets) performance measurements for the compiler. */
|
||||
export function enable() {
|
||||
counters = { };
|
||||
measures = {
|
||||
"I/O Read": 0,
|
||||
"I/O Write": 0,
|
||||
"Program": 0,
|
||||
"Parse": 0,
|
||||
"Bind": 0,
|
||||
"Check": 0,
|
||||
"Emit": 0,
|
||||
};
|
||||
|
||||
profilerEvent = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true
|
||||
? onProfilerEvent
|
||||
: undefined;
|
||||
counts = createMap<number>();
|
||||
marks = createMap<number>();
|
||||
measures = createMap<number>();
|
||||
enabled = true;
|
||||
profilerStart = timestamp();
|
||||
}
|
||||
|
||||
/** Disables (and clears) performance measurements for the compiler. */
|
||||
/** Disables performance measurements for the compiler. */
|
||||
export function disable() {
|
||||
counters = undefined;
|
||||
measures = undefined;
|
||||
profilerEvent = undefined;
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -501,7 +501,7 @@ namespace ts {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName);
|
||||
}
|
||||
matchedPattern = matchPatternOrExact(getKeys(state.compilerOptions.paths), moduleName);
|
||||
matchedPattern = matchPatternOrExact(getOwnKeys(state.compilerOptions.paths), moduleName);
|
||||
}
|
||||
|
||||
if (matchedPattern) {
|
||||
@ -831,14 +831,6 @@ namespace ts {
|
||||
: { resolvedModule: undefined, failedLookupLocations };
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const defaultInitCompilerOptions: CompilerOptions = {
|
||||
module: ModuleKind.CommonJS,
|
||||
target: ScriptTarget.ES5,
|
||||
noImplicitAny: false,
|
||||
sourceMap: false,
|
||||
};
|
||||
|
||||
interface OutputFingerprint {
|
||||
hash: string;
|
||||
byteOrderMark: boolean;
|
||||
@ -860,9 +852,10 @@ namespace ts {
|
||||
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile {
|
||||
let text: string;
|
||||
try {
|
||||
const start = performance.mark();
|
||||
performance.mark("beforeIORead");
|
||||
text = sys.readFile(fileName, options.charset);
|
||||
performance.measure("I/O Read", start);
|
||||
performance.mark("afterIORead");
|
||||
performance.measure("I/O Read", "beforeIORead", "afterIORead");
|
||||
}
|
||||
catch (e) {
|
||||
if (onError) {
|
||||
@ -877,7 +870,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function directoryExists(directoryPath: string): boolean {
|
||||
if (hasProperty(existingDirectories, directoryPath)) {
|
||||
if (directoryPath in existingDirectories) {
|
||||
return true;
|
||||
}
|
||||
if (sys.directoryExists(directoryPath)) {
|
||||
@ -905,7 +898,7 @@ namespace ts {
|
||||
const hash = sys.createHash(data);
|
||||
const mtimeBefore = sys.getModifiedTime(fileName);
|
||||
|
||||
if (mtimeBefore && hasProperty(outputFingerprints, fileName)) {
|
||||
if (mtimeBefore && fileName in outputFingerprints) {
|
||||
const fingerprint = outputFingerprints[fileName];
|
||||
|
||||
// If output has not been changed, and the file has no external modification
|
||||
@ -929,7 +922,7 @@ namespace ts {
|
||||
|
||||
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) {
|
||||
try {
|
||||
const start = performance.mark();
|
||||
performance.mark("beforeIOWrite");
|
||||
ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName)));
|
||||
|
||||
if (isWatchSet(options) && sys.createHash && sys.getModifiedTime) {
|
||||
@ -939,7 +932,8 @@ namespace ts {
|
||||
sys.writeFile(fileName, data, writeByteOrderMark);
|
||||
}
|
||||
|
||||
performance.measure("I/O Write", start);
|
||||
performance.mark("afterIOWrite");
|
||||
performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
|
||||
}
|
||||
catch (e) {
|
||||
if (onError) {
|
||||
@ -1042,14 +1036,9 @@ namespace ts {
|
||||
const resolutions: T[] = [];
|
||||
const cache = createMap<T>();
|
||||
for (const name of names) {
|
||||
let result: T;
|
||||
if (hasProperty(cache, name)) {
|
||||
result = cache[name];
|
||||
}
|
||||
else {
|
||||
result = loader(name, containingFile);
|
||||
cache[name] = result;
|
||||
}
|
||||
const result = name in cache
|
||||
? cache[name]
|
||||
: cache[name] = loader(name, containingFile);
|
||||
resolutions.push(result);
|
||||
}
|
||||
return resolutions;
|
||||
@ -1121,7 +1110,7 @@ namespace ts {
|
||||
// Track source files that are source files found by searching under node_modules, as these shouldn't be compiled.
|
||||
const sourceFilesFoundSearchingNodeModules = createMap<boolean>();
|
||||
|
||||
const start = performance.mark();
|
||||
performance.mark("beforeProgram");
|
||||
|
||||
host = host || createCompilerHost(options);
|
||||
|
||||
@ -1219,8 +1208,8 @@ namespace ts {
|
||||
};
|
||||
|
||||
verifyCompilerOptions();
|
||||
|
||||
performance.measure("Program", start);
|
||||
performance.mark("afterProgram");
|
||||
performance.measure("Program", "beforeProgram", "afterProgram");
|
||||
|
||||
return program;
|
||||
|
||||
@ -1250,7 +1239,7 @@ namespace ts {
|
||||
classifiableNames = createMap<string>();
|
||||
|
||||
for (const sourceFile of files) {
|
||||
copyMap(sourceFile.classifiableNames, classifiableNames);
|
||||
copyProperties(sourceFile.classifiableNames, classifiableNames);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1278,7 +1267,7 @@ namespace ts {
|
||||
(oldOptions.maxNodeModuleJsDepth !== options.maxNodeModuleJsDepth) ||
|
||||
!arrayIsEqualTo(oldOptions.typeRoots, oldOptions.typeRoots) ||
|
||||
!arrayIsEqualTo(oldOptions.rootDirs, options.rootDirs) ||
|
||||
!mapIsEqualTo(oldOptions.paths, options.paths)) {
|
||||
!equalOwnProperties(oldOptions.paths, options.paths)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1400,7 +1389,7 @@ namespace ts {
|
||||
getSourceFile: program.getSourceFile,
|
||||
getSourceFileByPath: program.getSourceFileByPath,
|
||||
getSourceFiles: program.getSourceFiles,
|
||||
isSourceFileFromExternalLibrary: (file: SourceFile) => !!lookUp(sourceFilesFoundSearchingNodeModules, file.path),
|
||||
isSourceFileFromExternalLibrary: (file: SourceFile) => !!sourceFilesFoundSearchingNodeModules[file.path],
|
||||
writeFile: writeFileCallback || (
|
||||
(fileName, data, writeByteOrderMark, onError, sourceFiles) => host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles)),
|
||||
isEmitBlocked,
|
||||
@ -1463,14 +1452,15 @@ namespace ts {
|
||||
// checked is to not pass the file to getEmitResolver.
|
||||
const emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile);
|
||||
|
||||
const start = performance.mark();
|
||||
performance.mark("beforeEmit");
|
||||
|
||||
const emitResult = emitFiles(
|
||||
emitResolver,
|
||||
getEmitHost(writeFileCallback),
|
||||
sourceFile);
|
||||
|
||||
performance.measure("Emit", start);
|
||||
performance.mark("afterEmit");
|
||||
performance.measure("Emit", "beforeEmit", "afterEmit");
|
||||
return emitResult;
|
||||
}
|
||||
|
||||
@ -1937,7 +1927,7 @@ namespace ts {
|
||||
|
||||
// If the file was previously found via a node_modules search, but is now being processed as a root file,
|
||||
// then everything it sucks in may also be marked incorrectly, and needs to be checked again.
|
||||
if (file && lookUp(sourceFilesFoundSearchingNodeModules, file.path) && currentNodeModulesDepth == 0) {
|
||||
if (file && sourceFilesFoundSearchingNodeModules[file.path] && currentNodeModulesDepth == 0) {
|
||||
sourceFilesFoundSearchingNodeModules[file.path] = false;
|
||||
if (!options.noResolve) {
|
||||
processReferencedFiles(file, getDirectoryPath(fileName), isDefaultLib);
|
||||
@ -1948,7 +1938,7 @@ namespace ts {
|
||||
processImportedModules(file, getDirectoryPath(fileName));
|
||||
}
|
||||
// See if we need to reprocess the imports due to prior skipped imports
|
||||
else if (file && lookUp(modulesWithElidedImports, file.path)) {
|
||||
else if (file && modulesWithElidedImports[file.path]) {
|
||||
if (currentNodeModulesDepth < maxNodeModulesJsDepth) {
|
||||
modulesWithElidedImports[file.path] = false;
|
||||
processImportedModules(file, getDirectoryPath(fileName));
|
||||
@ -2015,15 +2005,17 @@ namespace ts {
|
||||
}
|
||||
|
||||
function processTypeReferenceDirectives(file: SourceFile) {
|
||||
const typeDirectives = map(file.typeReferenceDirectives, l => l.fileName);
|
||||
// We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
|
||||
const typeDirectives = map(file.typeReferenceDirectives, ref => ref.fileName.toLocaleLowerCase());
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.fileName);
|
||||
|
||||
for (let i = 0; i < typeDirectives.length; i++) {
|
||||
const ref = file.typeReferenceDirectives[i];
|
||||
const resolvedTypeReferenceDirective = resolutions[i];
|
||||
// store resolved type directive on the file
|
||||
setResolvedTypeReferenceDirective(file, ref.fileName, resolvedTypeReferenceDirective);
|
||||
processTypeReferenceDirective(ref.fileName, resolvedTypeReferenceDirective, file, ref.pos, ref.end);
|
||||
const fileName = ref.fileName.toLocaleLowerCase();
|
||||
setResolvedTypeReferenceDirective(file, fileName, resolvedTypeReferenceDirective);
|
||||
processTypeReferenceDirective(fileName, resolvedTypeReferenceDirective, file, ref.pos, ref.end);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2048,7 +2040,7 @@ namespace ts {
|
||||
const otherFileText = host.readFile(resolvedTypeReferenceDirective.resolvedFileName);
|
||||
if (otherFileText !== getSourceFile(previousResolution.resolvedFileName).text) {
|
||||
fileProcessingDiagnostics.add(createDiagnostic(refFile, refPos, refEnd,
|
||||
Diagnostics.Conflicting_library_definitions_for_0_found_at_1_and_2_Copy_the_correct_file_to_the_typings_folder_to_resolve_this_conflict,
|
||||
Diagnostics.Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict,
|
||||
typeReferenceDirective,
|
||||
resolvedTypeReferenceDirective.resolvedFileName,
|
||||
previousResolution.resolvedFileName
|
||||
|
||||
@ -55,7 +55,7 @@ namespace ts {
|
||||
tryScan<T>(callback: () => T): T;
|
||||
}
|
||||
|
||||
const textToToken: MapLike<SyntaxKind> = {
|
||||
const textToToken = createMap({
|
||||
"abstract": SyntaxKind.AbstractKeyword,
|
||||
"any": SyntaxKind.AnyKeyword,
|
||||
"as": SyntaxKind.AsKeyword,
|
||||
@ -179,7 +179,7 @@ namespace ts {
|
||||
"|=": SyntaxKind.BarEqualsToken,
|
||||
"^=": SyntaxKind.CaretEqualsToken,
|
||||
"@": SyntaxKind.AtToken,
|
||||
};
|
||||
});
|
||||
|
||||
/*
|
||||
As per ECMAScript Language Specification 3th Edition, Section 7.6: Identifiers
|
||||
@ -271,12 +271,10 @@ namespace ts {
|
||||
lookupInUnicodeMap(code, unicodeES3IdentifierPart);
|
||||
}
|
||||
|
||||
function makeReverseMap(source: MapLike<number>): string[] {
|
||||
function makeReverseMap(source: Map<number>): string[] {
|
||||
const result: string[] = [];
|
||||
for (const name in source) {
|
||||
if (source.hasOwnProperty(name)) {
|
||||
result[source[name]] = name;
|
||||
}
|
||||
result[source[name]] = name;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -46,6 +46,7 @@ namespace ts {
|
||||
|
||||
export function createSourceMapWriter(host: EmitHost, writer: EmitTextWriter): SourceMapWriter {
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
const extendedDiagnostics = compilerOptions.extendedDiagnostics;
|
||||
let currentSourceFile: SourceFile;
|
||||
let sourceMapDir: string; // The directory in which sourcemap will be
|
||||
let stopOverridingSpan = false;
|
||||
@ -240,7 +241,9 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
const start = performance.mark();
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("beforeSourcemap");
|
||||
}
|
||||
|
||||
const sourceLinePos = getLineAndCharacterOfPosition(currentSourceFile, pos);
|
||||
|
||||
@ -282,7 +285,10 @@ namespace ts {
|
||||
|
||||
updateLastEncodedAndRecordedSpans();
|
||||
|
||||
performance.measure("Source Map", start);
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("afterSourcemap");
|
||||
performance.measure("Source Map", "beforeSourcemap", "afterSourcemap");
|
||||
}
|
||||
}
|
||||
|
||||
function getStartPos(range: TextRange) {
|
||||
|
||||
@ -122,11 +122,11 @@ namespace ts {
|
||||
const gutterSeparator = " ";
|
||||
const resetEscapeSequence = "\u001b[0m";
|
||||
const ellipsis = "...";
|
||||
const categoryFormatMap: MapLike<string> = {
|
||||
const categoryFormatMap = createMap<string>({
|
||||
[DiagnosticCategory.Warning]: yellowForegroundEscapeSequence,
|
||||
[DiagnosticCategory.Error]: redForegroundEscapeSequence,
|
||||
[DiagnosticCategory.Message]: blueForegroundEscapeSequence,
|
||||
};
|
||||
});
|
||||
|
||||
function formatAndReset(text: string, formatStyle: string) {
|
||||
return formatStyle + text + resetEscapeSequence;
|
||||
@ -445,10 +445,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
function cachedFileExists(fileName: string): boolean {
|
||||
if (hasProperty(cachedExistingFiles, fileName)) {
|
||||
return cachedExistingFiles[fileName];
|
||||
}
|
||||
return cachedExistingFiles[fileName] = hostFileExists(fileName);
|
||||
return fileName in cachedExistingFiles
|
||||
? cachedExistingFiles[fileName]
|
||||
: cachedExistingFiles[fileName] = hostFileExists(fileName);
|
||||
}
|
||||
|
||||
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void) {
|
||||
@ -704,9 +703,10 @@ namespace ts {
|
||||
description = getDiagnosticText(option.description);
|
||||
const options: string[] = [];
|
||||
const element = (<CommandLineOptionOfListType>option).element;
|
||||
forEachKey(<Map<number | string>>element.type, key => {
|
||||
const typeMap = <Map<number | string>>element.type;
|
||||
for (const key in typeMap) {
|
||||
options.push(`'${key}'`);
|
||||
});
|
||||
}
|
||||
optionsDescriptionMap[description] = options;
|
||||
}
|
||||
else {
|
||||
@ -763,68 +763,11 @@ namespace ts {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.A_tsconfig_json_file_is_already_defined_at_Colon_0, file), /* host */ undefined);
|
||||
}
|
||||
else {
|
||||
const compilerOptions = extend(options, defaultInitCompilerOptions);
|
||||
const configurations: any = {
|
||||
compilerOptions: serializeCompilerOptions(compilerOptions)
|
||||
};
|
||||
|
||||
if (fileNames && fileNames.length) {
|
||||
// only set the files property if we have at least one file
|
||||
configurations.files = fileNames;
|
||||
}
|
||||
else {
|
||||
configurations.exclude = ["node_modules"];
|
||||
if (compilerOptions.outDir) {
|
||||
configurations.exclude.push(compilerOptions.outDir);
|
||||
}
|
||||
}
|
||||
|
||||
sys.writeFile(file, JSON.stringify(configurations, undefined, 4));
|
||||
sys.writeFile(file, JSON.stringify(generateTSConfig(options, fileNames), undefined, 4));
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Successfully_created_a_tsconfig_json_file), /* host */ undefined);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
function serializeCompilerOptions(options: CompilerOptions): Map<string | number | boolean> {
|
||||
const result = createMap<string | number | boolean>();
|
||||
const optionsNameMap = getOptionNameMap().optionNameMap;
|
||||
|
||||
for (const name in options) {
|
||||
if (hasProperty(options, name)) {
|
||||
// tsconfig only options cannot be specified via command line,
|
||||
// so we can assume that only types that can appear here string | number | boolean
|
||||
const value = <string | number | boolean>options[name];
|
||||
switch (name) {
|
||||
case "init":
|
||||
case "watch":
|
||||
case "version":
|
||||
case "help":
|
||||
case "project":
|
||||
break;
|
||||
default:
|
||||
let optionDefinition = optionsNameMap[name.toLowerCase()];
|
||||
if (optionDefinition) {
|
||||
if (typeof optionDefinition.type === "string") {
|
||||
// string, number or boolean
|
||||
result[name] = value;
|
||||
}
|
||||
else {
|
||||
// Enum
|
||||
const typeMap = <Map<number>>optionDefinition.type;
|
||||
for (const key in typeMap) {
|
||||
if (hasProperty(typeMap, key)) {
|
||||
if (typeMap[key] === value)
|
||||
result[name] = key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -350,6 +350,7 @@ namespace ts {
|
||||
JSDocTypedefTag,
|
||||
JSDocPropertyTag,
|
||||
JSDocTypeLiteral,
|
||||
JSDocLiteralType,
|
||||
|
||||
// Synthesized list
|
||||
SyntaxList,
|
||||
@ -380,9 +381,9 @@ namespace ts {
|
||||
LastBinaryOperator = CaretEqualsToken,
|
||||
FirstNode = QualifiedName,
|
||||
FirstJSDocNode = JSDocTypeExpression,
|
||||
LastJSDocNode = JSDocTypeLiteral,
|
||||
LastJSDocNode = JSDocLiteralType,
|
||||
FirstJSDocTagNode = JSDocComment,
|
||||
LastJSDocTagNode = JSDocTypeLiteral
|
||||
LastJSDocTagNode = JSDocLiteralType
|
||||
}
|
||||
|
||||
export const enum NodeFlags {
|
||||
@ -1502,6 +1503,10 @@ namespace ts {
|
||||
type: JSDocType;
|
||||
}
|
||||
|
||||
export interface JSDocLiteralType extends JSDocType {
|
||||
literal: LiteralTypeNode;
|
||||
}
|
||||
|
||||
export type JSDocTypeReferencingNode = JSDocThisType | JSDocConstructorType | JSDocVariadicType | JSDocOptionalType | JSDocNullableType | JSDocNonNullableType;
|
||||
|
||||
// @kind(SyntaxKind.JSDocRecordMember)
|
||||
@ -1650,7 +1655,7 @@ namespace ts {
|
||||
|
||||
// this map is used by transpiler to supply alternative names for dependencies (i.e. in case of bundling)
|
||||
/* @internal */
|
||||
renamedDependencies?: MapLike<string>;
|
||||
renamedDependencies?: Map<string>;
|
||||
|
||||
/**
|
||||
* lib.d.ts should have a reference comment like
|
||||
@ -2157,6 +2162,8 @@ namespace ts {
|
||||
/* @internal */ exportSymbol?: Symbol; // Exported symbol associated with this symbol
|
||||
/* @internal */ constEnumOnlyModule?: boolean; // True if module contains only const enums or other modules with only const enums
|
||||
/* @internal */ isReferenced?: boolean; // True if the symbol is referenced elsewhere
|
||||
/* @internal */ isReplaceableByMethod?: boolean; // Can this Javascript class property be replaced by a method symbol?
|
||||
/* @internal */ isAssigned?: boolean; // True if the symbol is a parameter with assignments
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@ -2209,23 +2216,24 @@ namespace ts {
|
||||
AsyncMethodWithSuper = 0x00000800, // An async method that reads a value from a member of 'super'.
|
||||
AsyncMethodWithSuperBinding = 0x00001000, // An async method that assigns a value to a member of 'super'.
|
||||
CaptureArguments = 0x00002000, // Lexical 'arguments' used in body (for async functions)
|
||||
EnumValuesComputed = 0x00004000, // Values for enum members have been computed, and any errors have been reported for them.
|
||||
LexicalModuleMergesWithClass = 0x00008000, // Instantiated lexical module declaration is merged with a previous class declaration.
|
||||
LoopWithCapturedBlockScopedBinding = 0x00010000, // Loop that contains block scoped variable captured in closure
|
||||
CapturedBlockScopedBinding = 0x00020000, // Block-scoped binding that is captured in some function
|
||||
BlockScopedBindingInLoop = 0x00040000, // Block-scoped binding with declaration nested inside iteration statement
|
||||
ClassWithBodyScopedClassBinding = 0x00080000, // Decorated class that contains a binding to itself inside of the class body.
|
||||
BodyScopedClassBinding = 0x00100000, // Binding to a decorated class inside of the class's body.
|
||||
NeedsLoopOutParameter = 0x00200000, // Block scoped binding whose value should be explicitly copied outside of the converted loop
|
||||
EnumValuesComputed = 0x00004000, // Values for enum members have been computed, and any errors have been reported for them.
|
||||
LexicalModuleMergesWithClass = 0x00008000, // Instantiated lexical module declaration is merged with a previous class declaration.
|
||||
LoopWithCapturedBlockScopedBinding = 0x00010000, // Loop that contains block scoped variable captured in closure
|
||||
CapturedBlockScopedBinding = 0x00020000, // Block-scoped binding that is captured in some function
|
||||
BlockScopedBindingInLoop = 0x00040000, // Block-scoped binding with declaration nested inside iteration statement
|
||||
ClassWithBodyScopedClassBinding = 0x00080000, // Decorated class that contains a binding to itself inside of the class body.
|
||||
BodyScopedClassBinding = 0x00100000, // Binding to a decorated class inside of the class's body.
|
||||
NeedsLoopOutParameter = 0x00200000, // Block scoped binding whose value should be explicitly copied outside of the converted loop
|
||||
AssignmentsMarked = 0x00400000, // Parameter assignments have been marked
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface NodeLinks {
|
||||
flags?: NodeCheckFlags; // Set of flags specific to Node
|
||||
resolvedType?: Type; // Cached type of type node
|
||||
resolvedSignature?: Signature; // Cached signature of signature node or call expression
|
||||
resolvedSymbol?: Symbol; // Cached name resolution result
|
||||
resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result
|
||||
flags?: NodeCheckFlags; // Set of flags specific to Node
|
||||
enumMemberValue?: number; // Constant value of enum member
|
||||
isVisible?: boolean; // Is this node visible
|
||||
hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context
|
||||
@ -2742,7 +2750,7 @@ namespace ts {
|
||||
/* @internal */
|
||||
export interface CommandLineOptionBase {
|
||||
name: string;
|
||||
type: "string" | "number" | "boolean" | "object" | "list" | MapLike<number | string>; // a value of a primitive type, or an object literal mapping named values to actual values
|
||||
type: "string" | "number" | "boolean" | "object" | "list" | Map<number | string>; // a value of a primitive type, or an object literal mapping named values to actual values
|
||||
isFilePath?: boolean; // True if option value is a path or fileName
|
||||
shortName?: string; // A short mnemonic for convenience - for instance, 'h' can be used in place of 'help'
|
||||
description?: DiagnosticMessage; // The message describing what the command line switch does
|
||||
@ -2758,7 +2766,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export interface CommandLineOptionOfCustomType extends CommandLineOptionBase {
|
||||
type: MapLike<number | string>; // an object literal mapping named values to actual values
|
||||
type: Map<number | string>; // an object literal mapping named values to actual values
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
||||
@ -87,25 +87,6 @@ namespace ts {
|
||||
return node.end - node.pos;
|
||||
}
|
||||
|
||||
export function mapIsEqualTo<T>(map1: MapLike<T>, map2: MapLike<T>): boolean {
|
||||
if (!map1 || !map2) {
|
||||
return map1 === map2;
|
||||
}
|
||||
return containsAll(map1, map2) && containsAll(map2, map1);
|
||||
}
|
||||
|
||||
function containsAll<T>(map: MapLike<T>, other: MapLike<T>): boolean {
|
||||
for (const key in map) {
|
||||
if (!hasProperty(map, key)) {
|
||||
continue;
|
||||
}
|
||||
if (!hasProperty(other, key) || map[key] !== other[key]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export function arrayIsEqualTo<T>(array1: T[], array2: T[], equaler?: (a: T, b: T) => boolean): boolean {
|
||||
if (!array1 || !array2) {
|
||||
return array1 === array2;
|
||||
@ -2059,7 +2040,7 @@ namespace ts {
|
||||
// the map below must be updated. Note that this regexp *does not* include the 'delete' character.
|
||||
// There is no reason for this other than that JSON.stringify does not handle it either.
|
||||
const escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
|
||||
const escapedCharsMap: MapLike<string> = {
|
||||
const escapedCharsMap = createMap({
|
||||
"\0": "\\0",
|
||||
"\t": "\\t",
|
||||
"\v": "\\v",
|
||||
@ -2072,7 +2053,7 @@ namespace ts {
|
||||
"\u2028": "\\u2028", // lineSeparator
|
||||
"\u2029": "\\u2029", // paragraphSeparator
|
||||
"\u0085": "\\u0085" // nextLine
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
@ -2797,7 +2778,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function stringifyObject(value: any) {
|
||||
return `{${reduceProperties(value, stringifyProperty, "")}}`;
|
||||
return `{${reduceOwnProperties(value, stringifyProperty, "")}}`;
|
||||
}
|
||||
|
||||
function stringifyProperty(memo: string, value: any, key: string) {
|
||||
|
||||
@ -291,8 +291,8 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
|
||||
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ true);
|
||||
|
||||
const fullResults: ts.MapLike<TypeWriterResult[]> = {};
|
||||
const pullResults: ts.MapLike<TypeWriterResult[]> = {};
|
||||
const fullResults = ts.createMap<TypeWriterResult[]>();
|
||||
const pullResults = ts.createMap<TypeWriterResult[]>();
|
||||
|
||||
for (const sourceFile of allFiles) {
|
||||
fullResults[sourceFile.unitName] = fullWalker.getTypeAndSymbols(sourceFile.unitName);
|
||||
@ -338,7 +338,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
}
|
||||
}
|
||||
|
||||
function generateBaseLine(typeWriterResults: ts.MapLike<TypeWriterResult[]>, isSymbolBaseline: boolean): string {
|
||||
function generateBaseLine(typeWriterResults: ts.Map<TypeWriterResult[]>, isSymbolBaseline: boolean): string {
|
||||
const typeLines: string[] = [];
|
||||
const typeMap: { [fileName: string]: { [lineNum: number]: string[]; } } = {};
|
||||
|
||||
|
||||
@ -95,14 +95,14 @@ namespace FourSlash {
|
||||
|
||||
export import IndentStyle = ts.IndentStyle;
|
||||
|
||||
const entityMap: ts.MapLike<string> = {
|
||||
const entityMap = ts.createMap({
|
||||
"&": "&",
|
||||
"\"": """,
|
||||
"'": "'",
|
||||
"/": "/",
|
||||
"<": "<",
|
||||
">": ">"
|
||||
};
|
||||
});
|
||||
|
||||
export function escapeXmlAttributeValue(s: string) {
|
||||
return s.replace(/[&<>"'\/]/g, ch => entityMap[ch]);
|
||||
@ -204,7 +204,7 @@ namespace FourSlash {
|
||||
|
||||
public formatCodeOptions: ts.FormatCodeOptions;
|
||||
|
||||
private inputFiles: ts.MapLike<string> = {}; // Map between inputFile's fileName and its content for easily looking up when resolving references
|
||||
private inputFiles = ts.createMap<string>(); // Map between inputFile's fileName and its content for easily looking up when resolving references
|
||||
|
||||
// Add input file which has matched file name with the given reference-file path.
|
||||
// This is necessary when resolveReference flag is specified
|
||||
@ -301,11 +301,11 @@ namespace FourSlash {
|
||||
}
|
||||
else {
|
||||
// resolveReference file-option is not specified then do not resolve any files and include all inputFiles
|
||||
ts.forEachKey(this.inputFiles, fileName => {
|
||||
for (const fileName in this.inputFiles) {
|
||||
if (!Harness.isDefaultLibraryFile(fileName)) {
|
||||
this.languageServiceAdapterHost.addScript(fileName, this.inputFiles[fileName], /*isRootFile*/ true);
|
||||
}
|
||||
});
|
||||
}
|
||||
this.languageServiceAdapterHost.addScript(Harness.Compiler.defaultLibFileName,
|
||||
Harness.Compiler.getDefaultLibrarySourceFile().text, /*isRootFile*/ false);
|
||||
}
|
||||
@ -594,9 +594,9 @@ namespace FourSlash {
|
||||
|
||||
public noItemsWithSameNameButDifferentKind(): void {
|
||||
const completions = this.getCompletionListAtCaret();
|
||||
const uniqueItems: ts.MapLike<string> = {};
|
||||
const uniqueItems = ts.createMap<string>();
|
||||
for (const item of completions.entries) {
|
||||
if (!ts.hasProperty(uniqueItems, item.name)) {
|
||||
if (!(item.name in uniqueItems)) {
|
||||
uniqueItems[item.name] = item.kind;
|
||||
}
|
||||
else {
|
||||
@ -774,7 +774,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
public verifyRangesWithSameTextReferenceEachOther() {
|
||||
ts.forEachValue(this.rangesByText(), ranges => this.verifyRangesReferenceEachOther(ranges));
|
||||
ts.forEachProperty(this.rangesByText(), ranges => this.verifyRangesReferenceEachOther(ranges));
|
||||
}
|
||||
|
||||
private verifyReferencesWorker(references: ts.ReferenceEntry[], fileName: string, start: number, end: number, isWriteAccess?: boolean, isDefinition?: boolean) {
|
||||
@ -1631,11 +1631,12 @@ namespace FourSlash {
|
||||
return this.testData.ranges;
|
||||
}
|
||||
|
||||
public rangesByText(): ts.MapLike<Range[]> {
|
||||
const result: ts.MapLike<Range[]> = {};
|
||||
public rangesByText(): ts.Map<Range[]> {
|
||||
const result = ts.createMap<Range[]>();
|
||||
for (const range of this.getRanges()) {
|
||||
const text = this.rangeText(range);
|
||||
(ts.getProperty(result, text) || (result[text] = [])).push(range);
|
||||
const ranges = result[text] || (result[text] = []);
|
||||
ranges.push(range);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1890,7 +1891,7 @@ namespace FourSlash {
|
||||
|
||||
public verifyBraceCompletionAtPosition(negative: boolean, openingBrace: string) {
|
||||
|
||||
const openBraceMap: ts.MapLike<ts.CharacterCodes> = {
|
||||
const openBraceMap = ts.createMap<ts.CharacterCodes>({
|
||||
"(": ts.CharacterCodes.openParen,
|
||||
"{": ts.CharacterCodes.openBrace,
|
||||
"[": ts.CharacterCodes.openBracket,
|
||||
@ -1898,7 +1899,7 @@ namespace FourSlash {
|
||||
'"': ts.CharacterCodes.doubleQuote,
|
||||
"`": ts.CharacterCodes.backtick,
|
||||
"<": ts.CharacterCodes.lessThan
|
||||
};
|
||||
});
|
||||
|
||||
const charCode = openBraceMap[openingBrace];
|
||||
|
||||
@ -2738,7 +2739,7 @@ namespace FourSlashInterface {
|
||||
return this.state.getRanges();
|
||||
}
|
||||
|
||||
public rangesByText(): ts.MapLike<FourSlash.Range[]> {
|
||||
public rangesByText(): ts.Map<FourSlash.Range[]> {
|
||||
return this.state.rangesByText();
|
||||
}
|
||||
|
||||
|
||||
@ -848,9 +848,9 @@ namespace Harness {
|
||||
export const defaultLibFileName = "lib.d.ts";
|
||||
export const es2015DefaultLibFileName = "lib.es2015.d.ts";
|
||||
|
||||
const libFileNameSourceFileMap: ts.MapLike<ts.SourceFile> = {
|
||||
const libFileNameSourceFileMap= ts.createMap<ts.SourceFile>({
|
||||
[defaultLibFileName]: createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.es5.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest)
|
||||
};
|
||||
});
|
||||
|
||||
export function getDefaultLibrarySourceFile(fileName = defaultLibFileName): ts.SourceFile {
|
||||
if (!isDefaultLibraryFile(fileName)) {
|
||||
@ -1002,16 +1002,16 @@ namespace Harness {
|
||||
{ name: "symlink", type: "string" }
|
||||
];
|
||||
|
||||
let optionsIndex: ts.MapLike<ts.CommandLineOption>;
|
||||
let optionsIndex: ts.Map<ts.CommandLineOption>;
|
||||
function getCommandLineOption(name: string): ts.CommandLineOption {
|
||||
if (!optionsIndex) {
|
||||
optionsIndex = {};
|
||||
optionsIndex = ts.createMap<ts.CommandLineOption>();
|
||||
const optionDeclarations = harnessOptionDeclarations.concat(ts.optionDeclarations);
|
||||
for (const option of optionDeclarations) {
|
||||
optionsIndex[option.name.toLowerCase()] = option;
|
||||
}
|
||||
}
|
||||
return ts.lookUp(optionsIndex, name.toLowerCase());
|
||||
return optionsIndex[name.toLowerCase()];
|
||||
}
|
||||
|
||||
export function setCompilerOptionsFromHarnessSetting(settings: Harness.TestCaseParser.CompilerSettings, options: ts.CompilerOptions & HarnessOptions): void {
|
||||
@ -1569,6 +1569,7 @@ namespace Harness {
|
||||
|
||||
/** Support class for baseline files */
|
||||
export namespace Baseline {
|
||||
const NoContent = "<no content>";
|
||||
|
||||
export interface BaselineOptions {
|
||||
Subfolder?: string;
|
||||
@ -1635,14 +1636,6 @@ namespace Harness {
|
||||
throw new Error("The generated content was \"undefined\". Return \"null\" if no baselining is required.\"");
|
||||
}
|
||||
|
||||
// Store the content in the 'local' folder so we
|
||||
// can accept it later (manually)
|
||||
/* tslint:disable:no-null-keyword */
|
||||
if (actual !== null) {
|
||||
/* tslint:enable:no-null-keyword */
|
||||
IO.writeFile(actualFileName, actual);
|
||||
}
|
||||
|
||||
return actual;
|
||||
}
|
||||
|
||||
@ -1659,7 +1652,7 @@ namespace Harness {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
if (actual === null) {
|
||||
/* tslint:enable:no-null-keyword */
|
||||
actual = "<no content>";
|
||||
actual = NoContent;
|
||||
}
|
||||
|
||||
let expected = "<no content>";
|
||||
@ -1672,13 +1665,20 @@ namespace Harness {
|
||||
|
||||
function writeComparison(expected: string, actual: string, relativeFileName: string, actualFileName: string, descriptionForDescribe: string) {
|
||||
const encoded_actual = Utils.encodeString(actual);
|
||||
if (expected != encoded_actual) {
|
||||
if (expected !== encoded_actual) {
|
||||
if (actual === NoContent) {
|
||||
IO.writeFile(localPath(relativeFileName + ".delete"), "");
|
||||
}
|
||||
else {
|
||||
IO.writeFile(localPath(relativeFileName), actual);
|
||||
}
|
||||
// Overwrite & issue error
|
||||
const errMsg = "The baseline file " + relativeFileName + " has changed.";
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function runBaseline(
|
||||
descriptionForDescribe: string,
|
||||
relativeFileName: string,
|
||||
|
||||
@ -123,7 +123,7 @@ namespace Harness.LanguageService {
|
||||
}
|
||||
|
||||
export class LanguageServiceAdapterHost {
|
||||
protected fileNameToScript: ts.MapLike<ScriptInfo> = {};
|
||||
protected fileNameToScript = ts.createMap<ScriptInfo>();
|
||||
|
||||
constructor(protected cancellationToken = DefaultHostCancellationToken.Instance,
|
||||
protected settings = ts.getDefaultCompilerOptions()) {
|
||||
@ -135,7 +135,7 @@ namespace Harness.LanguageService {
|
||||
|
||||
public getFilenames(): string[] {
|
||||
const fileNames: string[] = [];
|
||||
ts.forEachValue(this.fileNameToScript, (scriptInfo) => {
|
||||
ts.forEachProperty(this.fileNameToScript, (scriptInfo) => {
|
||||
if (scriptInfo.isRootFile) {
|
||||
// only include root files here
|
||||
// usually it means that we won't include lib.d.ts in the list of root files so it won't mess the computation of compilation root dir.
|
||||
@ -146,7 +146,7 @@ namespace Harness.LanguageService {
|
||||
}
|
||||
|
||||
public getScriptInfo(fileName: string): ScriptInfo {
|
||||
return ts.lookUp(this.fileNameToScript, fileName);
|
||||
return this.fileNameToScript[fileName];
|
||||
}
|
||||
|
||||
public addScript(fileName: string, content: string, isRootFile: boolean): void {
|
||||
@ -235,7 +235,7 @@ namespace Harness.LanguageService {
|
||||
this.getModuleResolutionsForFile = (fileName) => {
|
||||
const scriptInfo = this.getScriptInfo(fileName);
|
||||
const preprocessInfo = ts.preProcessFile(scriptInfo.content, /*readImportFiles*/ true);
|
||||
const imports: ts.MapLike<string> = {};
|
||||
const imports = ts.createMap<string>();
|
||||
for (const module of preprocessInfo.importedFiles) {
|
||||
const resolutionInfo = ts.resolveModuleName(module.fileName, fileName, compilerOptions, moduleResolutionHost);
|
||||
if (resolutionInfo.resolvedModule) {
|
||||
@ -248,7 +248,7 @@ namespace Harness.LanguageService {
|
||||
const scriptInfo = this.getScriptInfo(fileName);
|
||||
if (scriptInfo) {
|
||||
const preprocessInfo = ts.preProcessFile(scriptInfo.content, /*readImportFiles*/ false);
|
||||
const resolutions: ts.MapLike<ts.ResolvedTypeReferenceDirective> = {};
|
||||
const resolutions = ts.createMap<ts.ResolvedTypeReferenceDirective>();
|
||||
const settings = this.nativeHost.getCompilationSettings();
|
||||
for (const typeReferenceDirective of preprocessInfo.typeReferenceDirectives) {
|
||||
const resolutionInfo = ts.resolveTypeReferenceDirective(typeReferenceDirective.fileName, fileName, settings, moduleResolutionHost);
|
||||
|
||||
@ -253,18 +253,15 @@ class ProjectRunner extends RunnerBase {
|
||||
moduleResolution: ts.ModuleResolutionKind.Classic, // currently all tests use classic module resolution kind, this will change in the future
|
||||
};
|
||||
// Set the values specified using json
|
||||
const optionNameMap: ts.MapLike<ts.CommandLineOption> = {};
|
||||
ts.forEach(ts.optionDeclarations, option => {
|
||||
optionNameMap[option.name] = option;
|
||||
});
|
||||
const optionNameMap = ts.arrayToMap(ts.optionDeclarations, option => option.name);
|
||||
for (const name in testCase) {
|
||||
if (name !== "mapRoot" && name !== "sourceRoot" && ts.hasProperty(optionNameMap, name)) {
|
||||
if (name !== "mapRoot" && name !== "sourceRoot" && name in optionNameMap) {
|
||||
const option = optionNameMap[name];
|
||||
const optType = option.type;
|
||||
let value = <any>testCase[name];
|
||||
if (typeof optType !== "string") {
|
||||
const key = value.toLowerCase();
|
||||
if (ts.hasProperty(optType, key)) {
|
||||
if (key in optType) {
|
||||
value = optType[key];
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,7 +198,8 @@ namespace RWC {
|
||||
}
|
||||
// Do not include the library in the baselines to avoid noise
|
||||
const baselineFiles = inputFiles.concat(otherFiles).filter(f => !Harness.isDefaultLibraryFile(f.unitName));
|
||||
return Harness.Compiler.getErrorBaseline(baselineFiles, compilerResult.errors);
|
||||
const errors = compilerResult.errors.filter(e => !Harness.isDefaultLibraryFile(e.file.fileName));
|
||||
return Harness.Compiler.getErrorBaseline(baselineFiles, errors);
|
||||
}, false, baselineOpts);
|
||||
});
|
||||
|
||||
|
||||
@ -89,6 +89,7 @@
|
||||
"./unittests/convertCompilerOptionsFromJson.ts",
|
||||
"./unittests/convertTypingOptionsFromJson.ts",
|
||||
"./unittests/tsserverProjectSystem.ts",
|
||||
"./unittests/matchFiles.ts"
|
||||
"./unittests/matchFiles.ts",
|
||||
"./unittests/initializeTSConfig.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@ -6,17 +6,17 @@ namespace ts {
|
||||
content: string;
|
||||
}
|
||||
|
||||
function createDefaultServerHost(fileMap: MapLike<File>): server.ServerHost {
|
||||
const existingDirectories: MapLike<boolean> = {};
|
||||
forEachValue(fileMap, v => {
|
||||
let dir = getDirectoryPath(v.name);
|
||||
function createDefaultServerHost(fileMap: Map<File>): server.ServerHost {
|
||||
const existingDirectories = createMap<boolean>();
|
||||
for (const name in fileMap) {
|
||||
let dir = getDirectoryPath(name);
|
||||
let previous: string;
|
||||
do {
|
||||
existingDirectories[dir] = true;
|
||||
previous = dir;
|
||||
dir = getDirectoryPath(dir);
|
||||
} while (dir !== previous);
|
||||
});
|
||||
}
|
||||
return {
|
||||
args: <string[]>[],
|
||||
newLine: "\r\n",
|
||||
@ -24,7 +24,7 @@ namespace ts {
|
||||
write: (s: string) => {
|
||||
},
|
||||
readFile: (path: string, encoding?: string): string => {
|
||||
return hasProperty(fileMap, path) && fileMap[path].content;
|
||||
return path in fileMap ? fileMap[path].content : undefined;
|
||||
},
|
||||
writeFile: (path: string, data: string, writeByteOrderMark?: boolean) => {
|
||||
throw new Error("NYI");
|
||||
@ -33,10 +33,10 @@ namespace ts {
|
||||
throw new Error("NYI");
|
||||
},
|
||||
fileExists: (path: string): boolean => {
|
||||
return hasProperty(fileMap, path);
|
||||
return path in fileMap;
|
||||
},
|
||||
directoryExists: (path: string): boolean => {
|
||||
return hasProperty(existingDirectories, path);
|
||||
return existingDirectories[path] || false;
|
||||
},
|
||||
createDirectory: (path: string) => {
|
||||
},
|
||||
@ -101,7 +101,7 @@ namespace ts {
|
||||
content: `foo()`
|
||||
};
|
||||
|
||||
const serverHost = createDefaultServerHost({ [root.name]: root, [imported.name]: imported });
|
||||
const serverHost = createDefaultServerHost(createMap({ [root.name]: root, [imported.name]: imported }));
|
||||
const { project, rootScriptInfo } = createProject(root.name, serverHost);
|
||||
|
||||
// ensure that imported file was found
|
||||
@ -193,7 +193,7 @@ namespace ts {
|
||||
content: `export var y = 1`
|
||||
};
|
||||
|
||||
const fileMap: MapLike<File> = { [root.name]: root };
|
||||
const fileMap = createMap({ [root.name]: root });
|
||||
const serverHost = createDefaultServerHost(fileMap);
|
||||
const originalFileExists = serverHost.fileExists;
|
||||
|
||||
|
||||
44
src/harness/unittests/initializeTSConfig.ts
Normal file
44
src/harness/unittests/initializeTSConfig.ts
Normal file
@ -0,0 +1,44 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\..\compiler\commandLineParser.ts" />
|
||||
|
||||
namespace ts {
|
||||
describe("initTSConfig", () => {
|
||||
function initTSConfigCorrectly(name: string, commandLinesArgs: string[]) {
|
||||
describe(name, () => {
|
||||
const commandLine = parseCommandLine(commandLinesArgs);
|
||||
const initResult = generateTSConfig(commandLine.options, commandLine.fileNames);
|
||||
const outputFileName = `tsConfig/${name.replace(/[^a-z0-9\-. ]/ig, "")}/tsconfig.json`;
|
||||
|
||||
it(`Correct output for ${outputFileName}`, () => {
|
||||
Harness.Baseline.runBaseline("Correct output", outputFileName, () => {
|
||||
if (initResult) {
|
||||
return JSON.stringify(initResult, undefined, 4);
|
||||
}
|
||||
else {
|
||||
// This can happen if compiler recieve invalid compiler-options
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
initTSConfigCorrectly("Default initialized TSConfig", ["--init"]);
|
||||
|
||||
initTSConfigCorrectly("Initialized TSConfig with files options", ["--init", "file0.st", "file1.ts", "file2.ts"]);
|
||||
|
||||
initTSConfigCorrectly("Initialized TSConfig with boolean value compiler options", ["--init", "--noUnusedLocals"]);
|
||||
|
||||
initTSConfigCorrectly("Initialized TSConfig with enum value compiler options", ["--init", "--target", "es5", "--jsx", "react"]);
|
||||
|
||||
initTSConfigCorrectly("Initialized TSConfig with list compiler options", ["--init", "--types", "jquery,mocha"]);
|
||||
|
||||
initTSConfigCorrectly("Initialized TSConfig with list compiler options with enum value", ["--init", "--lib", "es5,es2015.core"]);
|
||||
|
||||
initTSConfigCorrectly("Initialized TSConfig with incorrect compiler option", ["--init", "--someNonExistOption"]);
|
||||
|
||||
initTSConfigCorrectly("Initialized TSConfig with incorrect compiler option value", ["--init", "--lib", "nonExistLib,es5,es2015.promise"]);
|
||||
});
|
||||
}
|
||||
@ -10,7 +10,7 @@ namespace ts {
|
||||
const map = arrayToMap(files, f => f.name);
|
||||
|
||||
if (hasDirectoryExists) {
|
||||
const directories: MapLike<string> = {};
|
||||
const directories = createMap<string>();
|
||||
for (const f of files) {
|
||||
let name = getDirectoryPath(f.name);
|
||||
while (true) {
|
||||
@ -25,19 +25,19 @@ namespace ts {
|
||||
return {
|
||||
readFile,
|
||||
directoryExists: path => {
|
||||
return hasProperty(directories, path);
|
||||
return path in directories;
|
||||
},
|
||||
fileExists: path => {
|
||||
assert.isTrue(hasProperty(directories, getDirectoryPath(path)), `'fileExists' '${path}' request in non-existing directory`);
|
||||
return hasProperty(map, path);
|
||||
assert.isTrue(getDirectoryPath(path) in directories, `'fileExists' '${path}' request in non-existing directory`);
|
||||
return path in map;
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
return { readFile, fileExists: path => hasProperty(map, path), };
|
||||
return { readFile, fileExists: path => path in map, };
|
||||
}
|
||||
function readFile(path: string): string {
|
||||
return hasProperty(map, path) ? map[path].content : undefined;
|
||||
return path in map ? map[path].content : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,12 +282,12 @@ namespace ts {
|
||||
});
|
||||
|
||||
describe("Module resolution - relative imports", () => {
|
||||
function test(files: MapLike<string>, currentDirectory: string, rootFiles: string[], expectedFilesCount: number, relativeNamesToCheck: string[]) {
|
||||
function test(files: Map<string>, currentDirectory: string, rootFiles: string[], expectedFilesCount: number, relativeNamesToCheck: string[]) {
|
||||
const options: CompilerOptions = { module: ModuleKind.CommonJS };
|
||||
const host: CompilerHost = {
|
||||
getSourceFile: (fileName: string, languageVersion: ScriptTarget) => {
|
||||
const path = normalizePath(combinePaths(currentDirectory, fileName));
|
||||
return hasProperty(files, path) ? createSourceFile(fileName, files[path], languageVersion) : undefined;
|
||||
return path in files ? createSourceFile(fileName, files[path], languageVersion) : undefined;
|
||||
},
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
writeFile: (fileName, content): void => { throw new Error("NotImplemented"); },
|
||||
@ -298,7 +298,7 @@ namespace ts {
|
||||
useCaseSensitiveFileNames: () => false,
|
||||
fileExists: fileName => {
|
||||
const path = normalizePath(combinePaths(currentDirectory, fileName));
|
||||
return hasProperty(files, path);
|
||||
return path in files;
|
||||
},
|
||||
readFile: (fileName): string => { throw new Error("NotImplemented"); }
|
||||
};
|
||||
@ -318,7 +318,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
it("should find all modules", () => {
|
||||
const files: MapLike<string> = {
|
||||
const files = createMap({
|
||||
"/a/b/c/first/shared.ts": `
|
||||
class A {}
|
||||
export = A`,
|
||||
@ -332,37 +332,33 @@ import Shared = require('../first/shared');
|
||||
class C {}
|
||||
export = C;
|
||||
`
|
||||
};
|
||||
});
|
||||
test(files, "/a/b/c/first/second", ["class_a.ts"], 3, ["../../../c/third/class_c.ts"]);
|
||||
});
|
||||
|
||||
it("should find modules in node_modules", () => {
|
||||
const files: MapLike<string> = {
|
||||
const files = createMap({
|
||||
"/parent/node_modules/mod/index.d.ts": "export var x",
|
||||
"/parent/app/myapp.ts": `import {x} from "mod"`
|
||||
};
|
||||
});
|
||||
test(files, "/parent/app", ["myapp.ts"], 2, []);
|
||||
});
|
||||
|
||||
it("should find file referenced via absolute and relative names", () => {
|
||||
const files: MapLike<string> = {
|
||||
const files = createMap({
|
||||
"/a/b/c.ts": `/// <reference path="b.ts"/>`,
|
||||
"/a/b/b.ts": "var x"
|
||||
};
|
||||
});
|
||||
test(files, "/a/b", ["c.ts", "/a/b/b.ts"], 2, []);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Files with different casing", () => {
|
||||
const library = createSourceFile("lib.d.ts", "", ScriptTarget.ES5);
|
||||
function test(files: MapLike<string>, options: CompilerOptions, currentDirectory: string, useCaseSensitiveFileNames: boolean, rootFiles: string[], diagnosticCodes: number[]): void {
|
||||
function test(files: Map<string>, options: CompilerOptions, currentDirectory: string, useCaseSensitiveFileNames: boolean, rootFiles: string[], diagnosticCodes: number[]): void {
|
||||
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
if (!useCaseSensitiveFileNames) {
|
||||
const f: MapLike<string> = {};
|
||||
for (const fileName in files) {
|
||||
f[getCanonicalFileName(fileName)] = files[fileName];
|
||||
}
|
||||
files = f;
|
||||
files = reduceProperties(files, (files, file, fileName) => (files[getCanonicalFileName(fileName)] = file, files), createMap<string>());
|
||||
}
|
||||
|
||||
const host: CompilerHost = {
|
||||
@ -371,7 +367,7 @@ export = C;
|
||||
return library;
|
||||
}
|
||||
const path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName)));
|
||||
return hasProperty(files, path) ? createSourceFile(fileName, files[path], languageVersion) : undefined;
|
||||
return path in files ? createSourceFile(fileName, files[path], languageVersion) : undefined;
|
||||
},
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
writeFile: (fileName, content): void => { throw new Error("NotImplemented"); },
|
||||
@ -382,7 +378,7 @@ export = C;
|
||||
useCaseSensitiveFileNames: () => useCaseSensitiveFileNames,
|
||||
fileExists: fileName => {
|
||||
const path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName)));
|
||||
return hasProperty(files, path);
|
||||
return path in files;
|
||||
},
|
||||
readFile: (fileName): string => { throw new Error("NotImplemented"); }
|
||||
};
|
||||
@ -395,57 +391,57 @@ export = C;
|
||||
}
|
||||
|
||||
it("should succeed when the same file is referenced using absolute and relative names", () => {
|
||||
const files: MapLike<string> = {
|
||||
const files = createMap({
|
||||
"/a/b/c.ts": `/// <reference path="d.ts"/>`,
|
||||
"/a/b/d.ts": "var x"
|
||||
};
|
||||
});
|
||||
test(files, { module: ts.ModuleKind.AMD }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "/a/b/d.ts"], []);
|
||||
});
|
||||
|
||||
it("should fail when two files used in program differ only in casing (tripleslash references)", () => {
|
||||
const files: MapLike<string> = {
|
||||
const files = createMap({
|
||||
"/a/b/c.ts": `/// <reference path="D.ts"/>`,
|
||||
"/a/b/d.ts": "var x"
|
||||
};
|
||||
});
|
||||
test(files, { module: ts.ModuleKind.AMD, forceConsistentCasingInFileNames: true }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "d.ts"], [1149]);
|
||||
});
|
||||
|
||||
it("should fail when two files used in program differ only in casing (imports)", () => {
|
||||
const files: MapLike<string> = {
|
||||
const files = createMap({
|
||||
"/a/b/c.ts": `import {x} from "D"`,
|
||||
"/a/b/d.ts": "export var x"
|
||||
};
|
||||
});
|
||||
test(files, { module: ts.ModuleKind.AMD, forceConsistentCasingInFileNames: true }, "/a/b", /*useCaseSensitiveFileNames*/ false, ["c.ts", "d.ts"], [1149]);
|
||||
});
|
||||
|
||||
it("should fail when two files used in program differ only in casing (imports, relative module names)", () => {
|
||||
const files: MapLike<string> = {
|
||||
const files = createMap({
|
||||
"moduleA.ts": `import {x} from "./ModuleB"`,
|
||||
"moduleB.ts": "export var x"
|
||||
};
|
||||
});
|
||||
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", /*useCaseSensitiveFileNames*/ false, ["moduleA.ts", "moduleB.ts"], [1149]);
|
||||
});
|
||||
|
||||
it("should fail when two files exist on disk that differs only in casing", () => {
|
||||
const files: MapLike<string> = {
|
||||
const files = createMap({
|
||||
"/a/b/c.ts": `import {x} from "D"`,
|
||||
"/a/b/D.ts": "export var x",
|
||||
"/a/b/d.ts": "export var y"
|
||||
};
|
||||
});
|
||||
test(files, { module: ts.ModuleKind.AMD }, "/a/b", /*useCaseSensitiveFileNames*/ true, ["c.ts", "d.ts"], [1149]);
|
||||
});
|
||||
|
||||
it("should fail when module name in 'require' calls has inconsistent casing", () => {
|
||||
const files: MapLike<string> = {
|
||||
const files = createMap({
|
||||
"moduleA.ts": `import a = require("./ModuleC")`,
|
||||
"moduleB.ts": `import a = require("./moduleC")`,
|
||||
"moduleC.ts": "export var x"
|
||||
};
|
||||
});
|
||||
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "", /*useCaseSensitiveFileNames*/ false, ["moduleA.ts", "moduleB.ts", "moduleC.ts"], [1149, 1149]);
|
||||
});
|
||||
|
||||
it("should fail when module names in 'require' calls has inconsistent casing and current directory has uppercase chars", () => {
|
||||
const files: MapLike<string> = {
|
||||
const files = createMap({
|
||||
"/a/B/c/moduleA.ts": `import a = require("./ModuleC")`,
|
||||
"/a/B/c/moduleB.ts": `import a = require("./moduleC")`,
|
||||
"/a/B/c/moduleC.ts": "export var x",
|
||||
@ -453,11 +449,11 @@ export = C;
|
||||
import a = require("./moduleA");
|
||||
import b = require("./moduleB");
|
||||
`
|
||||
};
|
||||
});
|
||||
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], [1149]);
|
||||
});
|
||||
it("should not fail when module names in 'require' calls has consistent casing and current directory has uppercase chars", () => {
|
||||
const files: MapLike<string> = {
|
||||
const files = createMap({
|
||||
"/a/B/c/moduleA.ts": `import a = require("./moduleC")`,
|
||||
"/a/B/c/moduleB.ts": `import a = require("./moduleC")`,
|
||||
"/a/B/c/moduleC.ts": "export var x",
|
||||
@ -465,7 +461,7 @@ import b = require("./moduleB");
|
||||
import a = require("./moduleA");
|
||||
import b = require("./moduleB");
|
||||
`
|
||||
};
|
||||
});
|
||||
test(files, { module: ts.ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], []);
|
||||
});
|
||||
});
|
||||
@ -1023,7 +1019,7 @@ import b = require("./moduleB");
|
||||
const names = map(files, f => f.name);
|
||||
const sourceFiles = arrayToMap(map(files, f => createSourceFile(f.name, f.content, ScriptTarget.ES6)), f => f.fileName);
|
||||
const compilerHost: CompilerHost = {
|
||||
fileExists : fileName => hasProperty(sourceFiles, fileName),
|
||||
fileExists : fileName => fileName in sourceFiles,
|
||||
getSourceFile: fileName => sourceFiles[fileName],
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
writeFile(file, text) {
|
||||
@ -1034,7 +1030,7 @@ import b = require("./moduleB");
|
||||
getCanonicalFileName: f => f.toLowerCase(),
|
||||
getNewLine: () => "\r\n",
|
||||
useCaseSensitiveFileNames: () => false,
|
||||
readFile: fileName => hasProperty(sourceFiles, fileName) ? sourceFiles[fileName].text : undefined
|
||||
readFile: fileName => fileName in sourceFiles ? sourceFiles[fileName].text : undefined
|
||||
};
|
||||
const program1 = createProgram(names, {}, compilerHost);
|
||||
const diagnostics1 = program1.getFileProcessingDiagnostics().getDiagnostics();
|
||||
|
||||
@ -95,13 +95,14 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createSourceFileWithText(fileName: string, sourceText: SourceText, target: ScriptTarget) {
|
||||
const file = <SourceFileWithText>createSourceFile(fileName, sourceText.getFullText(), target);
|
||||
file.sourceText = sourceText;
|
||||
return file;
|
||||
}
|
||||
|
||||
function createTestCompilerHost(texts: NamedSourceText[], target: ScriptTarget): CompilerHost {
|
||||
const files: MapLike<SourceFileWithText> = {};
|
||||
for (const t of texts) {
|
||||
const file = <SourceFileWithText>createSourceFile(t.name, t.text.getFullText(), target);
|
||||
file.sourceText = t.text;
|
||||
files[t.name] = file;
|
||||
}
|
||||
const files = arrayToMap(texts, t => t.name, t => createSourceFileWithText(t.name, t.text, target));
|
||||
|
||||
return {
|
||||
getSourceFile(fileName): SourceFile {
|
||||
@ -128,10 +129,9 @@ namespace ts {
|
||||
getNewLine(): string {
|
||||
return sys ? sys.newLine : newLine;
|
||||
},
|
||||
fileExists: fileName => hasProperty(files, fileName),
|
||||
fileExists: fileName => fileName in files,
|
||||
readFile: fileName => {
|
||||
const file = lookUp(files, fileName);
|
||||
return file && file.text;
|
||||
return fileName in files ? files[fileName].text : undefined;
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -152,29 +152,29 @@ namespace ts {
|
||||
return program;
|
||||
}
|
||||
|
||||
function getSizeOfMap(map: MapLike<any>): number {
|
||||
let size = 0;
|
||||
for (const id in map) {
|
||||
if (hasProperty(map, id)) {
|
||||
size++;
|
||||
function checkResolvedModule(expected: ResolvedModule, actual: ResolvedModule): boolean {
|
||||
if (!expected === !actual) {
|
||||
if (expected) {
|
||||
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
|
||||
assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return size;
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkResolvedModule(expected: ResolvedModule, actual: ResolvedModule): void {
|
||||
assert.isTrue(actual !== undefined);
|
||||
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
|
||||
assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`);
|
||||
function checkResolvedTypeDirective(expected: ResolvedTypeReferenceDirective, actual: ResolvedTypeReferenceDirective): boolean {
|
||||
if (!expected === !actual) {
|
||||
if (expected) {
|
||||
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
|
||||
assert.isTrue(expected.primary === actual.primary, `'primary': expected '${expected.primary}' to be equal to '${actual.primary}'`);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkResolvedTypeDirective(expected: ResolvedTypeReferenceDirective, actual: ResolvedTypeReferenceDirective): void {
|
||||
assert.isTrue(actual !== undefined);
|
||||
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
|
||||
assert.isTrue(expected.primary === actual.primary, `'primary': expected '${expected.primary}' to be equal to '${actual.primary}'`);
|
||||
}
|
||||
|
||||
function checkCache<T>(caption: string, program: Program, fileName: string, expectedContent: MapLike<T>, getCache: (f: SourceFile) => MapLike<T>, entryChecker: (expected: T, original: T) => void): void {
|
||||
function checkCache<T>(caption: string, program: Program, fileName: string, expectedContent: Map<T>, getCache: (f: SourceFile) => Map<T>, entryChecker: (expected: T, original: T) => boolean): void {
|
||||
const file = program.getSourceFile(fileName);
|
||||
assert.isTrue(file !== undefined, `cannot find file ${fileName}`);
|
||||
const cache = getCache(file);
|
||||
@ -183,31 +183,15 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
assert.isTrue(cache !== undefined, `expected ${caption} to be set`);
|
||||
const actualCacheSize = getSizeOfMap(cache);
|
||||
const expectedSize = getSizeOfMap(expectedContent);
|
||||
assert.isTrue(actualCacheSize === expectedSize, `expected actual size: ${actualCacheSize} to be equal to ${expectedSize}`);
|
||||
|
||||
for (const id in expectedContent) {
|
||||
if (hasProperty(expectedContent, id)) {
|
||||
|
||||
if (expectedContent[id]) {
|
||||
const expected = expectedContent[id];
|
||||
const actual = cache[id];
|
||||
entryChecker(expected, actual);
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert.isTrue(cache[id] === undefined);
|
||||
}
|
||||
}
|
||||
assert.isTrue(equalOwnProperties(expectedContent, cache, entryChecker), `contents of ${caption} did not match the expected contents.`);
|
||||
}
|
||||
}
|
||||
|
||||
function checkResolvedModulesCache(program: Program, fileName: string, expectedContent: MapLike<ResolvedModule>): void {
|
||||
function checkResolvedModulesCache(program: Program, fileName: string, expectedContent: Map<ResolvedModule>): void {
|
||||
checkCache("resolved modules", program, fileName, expectedContent, f => f.resolvedModules, checkResolvedModule);
|
||||
}
|
||||
|
||||
function checkResolvedTypeDirectivesCache(program: Program, fileName: string, expectedContent: MapLike<ResolvedTypeReferenceDirective>): void {
|
||||
function checkResolvedTypeDirectivesCache(program: Program, fileName: string, expectedContent: Map<ResolvedTypeReferenceDirective>): void {
|
||||
checkCache("resolved type directives", program, fileName, expectedContent, f => f.resolvedTypeReferenceDirectiveNames, checkResolvedTypeDirective);
|
||||
}
|
||||
|
||||
@ -313,6 +297,8 @@ namespace ts {
|
||||
});
|
||||
|
||||
it("resolution cache follows imports", () => {
|
||||
(<any>Error).stackTraceLimit = Infinity;
|
||||
|
||||
const files = [
|
||||
{ name: "a.ts", text: SourceText.New("", "import {_} from 'b'", "var x = 1") },
|
||||
{ name: "b.ts", text: SourceText.New("", "", "var y = 2") },
|
||||
@ -320,7 +306,7 @@ namespace ts {
|
||||
const options: CompilerOptions = { target };
|
||||
|
||||
const program_1 = newProgram(files, ["a.ts"], options);
|
||||
checkResolvedModulesCache(program_1, "a.ts", { "b": { resolvedFileName: "b.ts" } });
|
||||
checkResolvedModulesCache(program_1, "a.ts", createMap({ "b": { resolvedFileName: "b.ts" } }));
|
||||
checkResolvedModulesCache(program_1, "b.ts", undefined);
|
||||
|
||||
const program_2 = updateProgram(program_1, ["a.ts"], options, files => {
|
||||
@ -329,7 +315,7 @@ namespace ts {
|
||||
assert.isTrue(program_1.structureIsReused);
|
||||
|
||||
// content of resolution cache should not change
|
||||
checkResolvedModulesCache(program_1, "a.ts", { "b": { resolvedFileName: "b.ts" } });
|
||||
checkResolvedModulesCache(program_1, "a.ts", createMap({ "b": { resolvedFileName: "b.ts" } }));
|
||||
checkResolvedModulesCache(program_1, "b.ts", undefined);
|
||||
|
||||
// imports has changed - program is not reused
|
||||
@ -346,7 +332,7 @@ namespace ts {
|
||||
files[0].text = files[0].text.updateImportsAndExports(newImports);
|
||||
});
|
||||
assert.isTrue(!program_3.structureIsReused);
|
||||
checkResolvedModulesCache(program_4, "a.ts", { "b": { resolvedFileName: "b.ts" }, "c": undefined });
|
||||
checkResolvedModulesCache(program_4, "a.ts", createMap({ "b": { resolvedFileName: "b.ts" }, "c": undefined }));
|
||||
});
|
||||
|
||||
it("resolved type directives cache follows type directives", () => {
|
||||
@ -357,7 +343,7 @@ namespace ts {
|
||||
const options: CompilerOptions = { target, typeRoots: ["/types"] };
|
||||
|
||||
const program_1 = newProgram(files, ["/a.ts"], options);
|
||||
checkResolvedTypeDirectivesCache(program_1, "/a.ts", { "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } });
|
||||
checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMap({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }));
|
||||
checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", undefined);
|
||||
|
||||
const program_2 = updateProgram(program_1, ["/a.ts"], options, files => {
|
||||
@ -366,7 +352,7 @@ namespace ts {
|
||||
assert.isTrue(program_1.structureIsReused);
|
||||
|
||||
// content of resolution cache should not change
|
||||
checkResolvedTypeDirectivesCache(program_1, "/a.ts", { "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } });
|
||||
checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMap({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }));
|
||||
checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", undefined);
|
||||
|
||||
// type reference directives has changed - program is not reused
|
||||
@ -384,7 +370,7 @@ namespace ts {
|
||||
files[0].text = files[0].text.updateReferences(newReferences);
|
||||
});
|
||||
assert.isTrue(!program_3.structureIsReused);
|
||||
checkResolvedTypeDirectivesCache(program_1, "/a.ts", { "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } });
|
||||
checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMap({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -362,13 +362,13 @@ namespace ts.server {
|
||||
class InProcClient {
|
||||
private server: InProcSession;
|
||||
private seq = 0;
|
||||
private callbacks: ts.MapLike<(resp: protocol.Response) => void> = {};
|
||||
private eventHandlers: ts.MapLike<(args: any) => void> = {};
|
||||
private callbacks = createMap<(resp: protocol.Response) => void>();
|
||||
private eventHandlers = createMap<(args: any) => void>();
|
||||
|
||||
handle(msg: protocol.Message): void {
|
||||
if (msg.type === "response") {
|
||||
const response = <protocol.Response>msg;
|
||||
if (this.callbacks[response.request_seq]) {
|
||||
if (response.request_seq in this.callbacks) {
|
||||
this.callbacks[response.request_seq](response);
|
||||
delete this.callbacks[response.request_seq];
|
||||
}
|
||||
@ -380,7 +380,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
emit(name: string, args: any): void {
|
||||
if (this.eventHandlers[name]) {
|
||||
if (name in this.eventHandlers) {
|
||||
this.eventHandlers[name](args);
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,20 +68,10 @@ namespace ts {
|
||||
return entry;
|
||||
}
|
||||
|
||||
function sizeOfMap(map: MapLike<any>): number {
|
||||
let n = 0;
|
||||
for (const name in map) {
|
||||
if (hasProperty(map, name)) {
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
function checkMapKeys(caption: string, map: MapLike<any>, expectedKeys: string[]) {
|
||||
assert.equal(sizeOfMap(map), expectedKeys.length, `${caption}: incorrect size of map`);
|
||||
function checkMapKeys(caption: string, map: Map<any>, expectedKeys: string[]) {
|
||||
assert.equal(reduceProperties(map, count => count + 1, 0), expectedKeys.length, `${caption}: incorrect size of map`);
|
||||
for (const name of expectedKeys) {
|
||||
assert.isTrue(hasProperty(map, name), `${caption} is expected to contain ${name}, actual keys: ${getKeys(map)}`);
|
||||
assert.isTrue(name in map, `${caption} is expected to contain ${name}, actual keys: ${Object.keys(map)}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,8 +116,8 @@ namespace ts {
|
||||
private getCanonicalFileName: (s: string) => string;
|
||||
private toPath: (f: string) => Path;
|
||||
private callbackQueue: TimeOutCallback[] = [];
|
||||
readonly watchedDirectories: MapLike<{ cb: DirectoryWatcherCallback, recursive: boolean }[]> = {};
|
||||
readonly watchedFiles: MapLike<FileWatcherCallback[]> = {};
|
||||
readonly watchedDirectories = createMap<{ cb: DirectoryWatcherCallback, recursive: boolean }[]>();
|
||||
readonly watchedFiles = createMap<FileWatcherCallback[]>();
|
||||
|
||||
constructor(public useCaseSensitiveFileNames: boolean, private executingFilePath: string, private currentDirectory: string, fileOrFolderList: FileOrFolder[]) {
|
||||
this.getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
@ -208,7 +198,7 @@ namespace ts {
|
||||
|
||||
watchDirectory(directoryName: string, callback: DirectoryWatcherCallback, recursive: boolean): DirectoryWatcher {
|
||||
const path = this.toPath(directoryName);
|
||||
const callbacks = lookUp(this.watchedDirectories, path) || (this.watchedDirectories[path] = []);
|
||||
const callbacks = this.watchedDirectories[path] || (this.watchedDirectories[path] = []);
|
||||
callbacks.push({ cb: callback, recursive });
|
||||
return {
|
||||
referenceCount: 0,
|
||||
@ -229,7 +219,7 @@ namespace ts {
|
||||
|
||||
triggerDirectoryWatcherCallback(directoryName: string, fileName: string): void {
|
||||
const path = this.toPath(directoryName);
|
||||
const callbacks = lookUp(this.watchedDirectories, path);
|
||||
const callbacks = this.watchedDirectories[path];
|
||||
if (callbacks) {
|
||||
for (const callback of callbacks) {
|
||||
callback.cb(fileName);
|
||||
@ -239,7 +229,7 @@ namespace ts {
|
||||
|
||||
triggerFileWatcherCallback(fileName: string, removed?: boolean): void {
|
||||
const path = this.toPath(fileName);
|
||||
const callbacks = lookUp(this.watchedFiles, path);
|
||||
const callbacks = this.watchedFiles[path];
|
||||
if (callbacks) {
|
||||
for (const callback of callbacks) {
|
||||
callback(path, removed);
|
||||
@ -249,7 +239,7 @@ namespace ts {
|
||||
|
||||
watchFile(fileName: string, callback: FileWatcherCallback) {
|
||||
const path = this.toPath(fileName);
|
||||
const callbacks = lookUp(this.watchedFiles, path) || (this.watchedFiles[path] = []);
|
||||
const callbacks = this.watchedFiles[path] || (this.watchedFiles[path] = []);
|
||||
callbacks.push(callback);
|
||||
return {
|
||||
close: () => {
|
||||
@ -594,7 +584,7 @@ namespace ts {
|
||||
content: `{
|
||||
"compilerOptions": {
|
||||
"target": "es6"
|
||||
},
|
||||
},
|
||||
"files": [ "main.ts" ]
|
||||
}`
|
||||
};
|
||||
@ -621,7 +611,7 @@ namespace ts {
|
||||
content: `{
|
||||
"compilerOptions": {
|
||||
"target": "es6"
|
||||
},
|
||||
},
|
||||
"files": [ "main.ts" ]
|
||||
}`
|
||||
};
|
||||
|
||||
4
src/lib/es2015.core.d.ts
vendored
4
src/lib/es2015.core.d.ts
vendored
@ -68,6 +68,10 @@ interface ArrayConstructor {
|
||||
of<T>(...items: T[]): Array<T>;
|
||||
}
|
||||
|
||||
interface DateConstructor {
|
||||
new (value: Date): Date;
|
||||
}
|
||||
|
||||
interface Function {
|
||||
/**
|
||||
* Returns the name of the function. Function names are read-only and can not be changed.
|
||||
|
||||
7
src/lib/es5.d.ts
vendored
7
src/lib/es5.d.ts
vendored
@ -1006,7 +1006,12 @@ interface ReadonlyArray<T> {
|
||||
* Combines two or more arrays.
|
||||
* @param items Additional items to add to the end of array1.
|
||||
*/
|
||||
concat(...items: T[]): T[];
|
||||
concat(...items: T[][]): T[];
|
||||
/**
|
||||
* Combines two or more arrays.
|
||||
* @param items Additional items to add to the end of array1.
|
||||
*/
|
||||
concat(...items: (T | T[])[]): T[];
|
||||
/**
|
||||
* Adds all the elements of an array separated by the specified separator string.
|
||||
* @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma.
|
||||
|
||||
@ -37,7 +37,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private getLineMap(fileName: string): number[] {
|
||||
let lineMap = ts.lookUp(this.lineMaps, fileName);
|
||||
let lineMap = this.lineMaps[fileName];
|
||||
if (!lineMap) {
|
||||
const scriptSnapshot = this.host.getScriptSnapshot(fileName);
|
||||
lineMap = this.lineMaps[fileName] = ts.computeLineStarts(scriptSnapshot.getText(0, scriptSnapshot.getLength()));
|
||||
|
||||
@ -136,9 +136,9 @@ namespace ts.server {
|
||||
|
||||
for (const name of names) {
|
||||
// check if this is a duplicate entry in the list
|
||||
let resolution = lookUp(newResolutions, name);
|
||||
let resolution = newResolutions[name];
|
||||
if (!resolution) {
|
||||
const existingResolution = currentResolutionsInFile && ts.lookUp(currentResolutionsInFile, name);
|
||||
const existingResolution = currentResolutionsInFile && currentResolutionsInFile[name];
|
||||
if (moduleResolutionIsValid(existingResolution)) {
|
||||
// ok, it is safe to use existing name resolution results
|
||||
resolution = existingResolution;
|
||||
@ -563,7 +563,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
let strBuilder = "";
|
||||
ts.forEachValue(this.filenameToSourceFile,
|
||||
ts.forEachProperty(this.filenameToSourceFile,
|
||||
sourceFile => { strBuilder += sourceFile.fileName + "\n"; });
|
||||
return strBuilder;
|
||||
}
|
||||
@ -857,7 +857,7 @@ namespace ts.server {
|
||||
if (project.isConfiguredProject()) {
|
||||
project.projectFileWatcher.close();
|
||||
project.directoryWatcher.close();
|
||||
forEachValue(project.directoriesWatchedForWildcards, watcher => { watcher.close(); });
|
||||
forEachProperty(project.directoriesWatchedForWildcards, watcher => { watcher.close(); });
|
||||
delete project.directoriesWatchedForWildcards;
|
||||
this.configuredProjects = copyListRemovingItem(project, this.configuredProjects);
|
||||
}
|
||||
@ -1124,7 +1124,7 @@ namespace ts.server {
|
||||
|
||||
getScriptInfo(filename: string) {
|
||||
filename = ts.normalizePath(filename);
|
||||
return ts.lookUp(this.filenameToScriptInfo, filename);
|
||||
return this.filenameToScriptInfo[filename];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1133,7 +1133,7 @@ namespace ts.server {
|
||||
*/
|
||||
openFile(fileName: string, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind) {
|
||||
fileName = ts.normalizePath(fileName);
|
||||
let info = ts.lookUp(this.filenameToScriptInfo, fileName);
|
||||
let info = this.filenameToScriptInfo[fileName];
|
||||
if (!info) {
|
||||
let content: string;
|
||||
if (this.host.fileExists(fileName)) {
|
||||
@ -1246,7 +1246,7 @@ namespace ts.server {
|
||||
* @param filename is absolute pathname
|
||||
*/
|
||||
closeClientFile(filename: string) {
|
||||
const info = ts.lookUp(this.filenameToScriptInfo, filename);
|
||||
const info = this.filenameToScriptInfo[filename];
|
||||
if (info) {
|
||||
this.closeOpenFile(info);
|
||||
info.isOpen = false;
|
||||
@ -1255,14 +1255,14 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
getProjectForFile(filename: string) {
|
||||
const scriptInfo = ts.lookUp(this.filenameToScriptInfo, filename);
|
||||
const scriptInfo = this.filenameToScriptInfo[filename];
|
||||
if (scriptInfo) {
|
||||
return scriptInfo.defaultProject;
|
||||
}
|
||||
}
|
||||
|
||||
printProjectsForFile(filename: string) {
|
||||
const scriptInfo = ts.lookUp(this.filenameToScriptInfo, filename);
|
||||
const scriptInfo = this.filenameToScriptInfo[filename];
|
||||
if (scriptInfo) {
|
||||
this.psLogger.startGroup();
|
||||
this.psLogger.info("Projects for " + filename);
|
||||
@ -1419,7 +1419,7 @@ namespace ts.server {
|
||||
/*recursive*/ true
|
||||
);
|
||||
|
||||
project.directoriesWatchedForWildcards = reduceProperties(projectOptions.wildcardDirectories, (watchers, flag, directory) => {
|
||||
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}`);
|
||||
|
||||
@ -1061,7 +1061,7 @@ namespace ts.server {
|
||||
return { response, responseRequired: true };
|
||||
}
|
||||
|
||||
private handlers: MapLike<(request: protocol.Request) => { response?: any, responseRequired?: boolean }> = {
|
||||
private handlers = createMap<(request: protocol.Request) => { response?: any, responseRequired?: boolean }>({
|
||||
[CommandNames.Exit]: () => {
|
||||
this.exit();
|
||||
return { responseRequired: false };
|
||||
@ -1198,9 +1198,10 @@ namespace ts.server {
|
||||
this.reloadProjects();
|
||||
return { responseRequired: false };
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
public addProtocolHandler(command: string, handler: (request: protocol.Request) => { response?: any, responseRequired: boolean }) {
|
||||
if (this.handlers[command]) {
|
||||
if (command in this.handlers) {
|
||||
throw new Error(`Protocol handler already exists for command "${command}"`);
|
||||
}
|
||||
this.handlers[command] = handler;
|
||||
|
||||
@ -58,12 +58,7 @@ namespace ts.JsTyping {
|
||||
|
||||
if (!safeList) {
|
||||
const result = readConfigFile(safeListPath, (path: string) => host.readFile(path));
|
||||
if (result.config) {
|
||||
safeList = result.config;
|
||||
}
|
||||
else {
|
||||
safeList = createMap<string>();
|
||||
};
|
||||
safeList = createMap<string>(result.config);
|
||||
}
|
||||
|
||||
const filesToWatch: string[] = [];
|
||||
@ -93,7 +88,7 @@ namespace ts.JsTyping {
|
||||
|
||||
// Add the cached typing locations for inferred typings that are already installed
|
||||
for (const name in packageNameToTypingLocation) {
|
||||
if (hasProperty(inferredTypings, name) && !inferredTypings[name]) {
|
||||
if (name in inferredTypings && !inferredTypings[name]) {
|
||||
inferredTypings[name] = packageNameToTypingLocation[name];
|
||||
}
|
||||
}
|
||||
@ -124,7 +119,7 @@ namespace ts.JsTyping {
|
||||
}
|
||||
|
||||
for (const typing of typingNames) {
|
||||
if (!hasProperty(inferredTypings, typing)) {
|
||||
if (!(typing in inferredTypings)) {
|
||||
inferredTypings[typing] = undefined;
|
||||
}
|
||||
}
|
||||
@ -139,16 +134,16 @@ namespace ts.JsTyping {
|
||||
const jsonConfig: PackageJson = result.config;
|
||||
filesToWatch.push(jsonPath);
|
||||
if (jsonConfig.dependencies) {
|
||||
mergeTypings(getKeys(jsonConfig.dependencies));
|
||||
mergeTypings(getOwnKeys(jsonConfig.dependencies));
|
||||
}
|
||||
if (jsonConfig.devDependencies) {
|
||||
mergeTypings(getKeys(jsonConfig.devDependencies));
|
||||
mergeTypings(getOwnKeys(jsonConfig.devDependencies));
|
||||
}
|
||||
if (jsonConfig.optionalDependencies) {
|
||||
mergeTypings(getKeys(jsonConfig.optionalDependencies));
|
||||
mergeTypings(getOwnKeys(jsonConfig.optionalDependencies));
|
||||
}
|
||||
if (jsonConfig.peerDependencies) {
|
||||
mergeTypings(getKeys(jsonConfig.peerDependencies));
|
||||
mergeTypings(getOwnKeys(jsonConfig.peerDependencies));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -167,7 +162,7 @@ namespace ts.JsTyping {
|
||||
mergeTypings(cleanedTypingNames);
|
||||
}
|
||||
else {
|
||||
mergeTypings(filter(cleanedTypingNames, f => hasProperty(safeList, f)));
|
||||
mergeTypings(filter(cleanedTypingNames, f => f in safeList));
|
||||
}
|
||||
|
||||
const hasJsxFile = forEach(fileNames, f => scriptKindIs(f, /*LanguageServiceHost*/ undefined, ScriptKind.JSX));
|
||||
|
||||
@ -15,7 +15,7 @@ namespace ts.NavigateTo {
|
||||
|
||||
const nameToDeclarations = sourceFile.getNamedDeclarations();
|
||||
for (const name in nameToDeclarations) {
|
||||
const declarations = getProperty(nameToDeclarations, name);
|
||||
const declarations = nameToDeclarations[name];
|
||||
if (declarations) {
|
||||
// First do a quick check to see if the name of the declaration matches the
|
||||
// last portion of the (possibly) dotted name they're searching for.
|
||||
|
||||
@ -243,7 +243,7 @@ namespace ts.NavigationBar {
|
||||
return true;
|
||||
}
|
||||
|
||||
const itemsWithSameName = getProperty(nameToItems, name);
|
||||
const itemsWithSameName = nameToItems[name];
|
||||
if (!itemsWithSameName) {
|
||||
nameToItems[name] = child;
|
||||
return true;
|
||||
|
||||
@ -188,7 +188,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getWordSpans(word: string): TextSpan[] {
|
||||
if (!hasProperty(stringToWordSpans, word)) {
|
||||
if (!(word in stringToWordSpans)) {
|
||||
stringToWordSpans[word] = breakIntoWordSpans(word);
|
||||
}
|
||||
|
||||
|
||||
@ -990,7 +990,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getDeclarations(name: string) {
|
||||
return getProperty(result, name) || (result[name] = []);
|
||||
return result[name] || (result[name] = []);
|
||||
}
|
||||
|
||||
function getDeclarationName(declaration: Declaration) {
|
||||
@ -2042,7 +2042,7 @@ namespace ts {
|
||||
function fixupCompilerOptions(options: CompilerOptions, diagnostics: Diagnostic[]): CompilerOptions {
|
||||
// Lazily create this value to fix module loading errors.
|
||||
commandLineOptionsStringToEnum = commandLineOptionsStringToEnum || <CommandLineOptionOfCustomType[]>filter(optionDeclarations, o =>
|
||||
typeof o.type === "object" && !forEachValue(<Map<any>>o.type, v => typeof v !== "number"));
|
||||
typeof o.type === "object" && !forEachProperty(o.type, v => typeof v !== "number"));
|
||||
|
||||
options = clone(options);
|
||||
|
||||
@ -2058,7 +2058,7 @@ namespace ts {
|
||||
options[opt.name] = parseCustomTypeOption(opt, value, diagnostics);
|
||||
}
|
||||
else {
|
||||
if (!forEachValue(opt.type, v => v === value)) {
|
||||
if (!forEachProperty(opt.type, v => v === value)) {
|
||||
// Supplied value isn't a valid enum value.
|
||||
diagnostics.push(createCompilerDiagnosticForInvalidCustomType(opt));
|
||||
}
|
||||
@ -2117,7 +2117,9 @@ namespace ts {
|
||||
sourceFile.moduleName = transpileOptions.moduleName;
|
||||
}
|
||||
|
||||
sourceFile.renamedDependencies = transpileOptions.renamedDependencies;
|
||||
if (transpileOptions.renamedDependencies) {
|
||||
sourceFile.renamedDependencies = createMap(transpileOptions.renamedDependencies);
|
||||
}
|
||||
|
||||
const newLine = getNewLineCharacter(options);
|
||||
|
||||
@ -2251,7 +2253,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getBucketForCompilationSettings(key: DocumentRegistryBucketKey, createIfMissing: boolean): FileMap<DocumentRegistryEntry> {
|
||||
let bucket = lookUp(buckets, key);
|
||||
let bucket = buckets[key];
|
||||
if (!bucket && createIfMissing) {
|
||||
buckets[key] = bucket = createFileMap<DocumentRegistryEntry>();
|
||||
}
|
||||
@ -2260,7 +2262,7 @@ namespace ts {
|
||||
|
||||
function reportStats() {
|
||||
const bucketInfoArray = Object.keys(buckets).filter(name => name && name.charAt(0) === "_").map(name => {
|
||||
const entries = lookUp(buckets, name);
|
||||
const entries = buckets[name];
|
||||
const sourceFiles: { name: string; refCount: number; references: string[]; }[] = [];
|
||||
entries.forEachValue((key, entry) => {
|
||||
sourceFiles.push({
|
||||
@ -3099,7 +3101,7 @@ namespace ts {
|
||||
oldSettings.allowJs !== newSettings.allowJs ||
|
||||
oldSettings.disableSizeLimit !== oldSettings.disableSizeLimit ||
|
||||
oldSettings.baseUrl !== newSettings.baseUrl ||
|
||||
!mapIsEqualTo(oldSettings.paths, newSettings.paths));
|
||||
!equalOwnProperties(oldSettings.paths, newSettings.paths));
|
||||
|
||||
// Now create a new compiler
|
||||
const compilerHost: CompilerHost = {
|
||||
@ -3114,7 +3116,6 @@ namespace ts {
|
||||
getCurrentDirectory: () => currentDirectory,
|
||||
fileExists: (fileName): boolean => {
|
||||
// stub missing host functionality
|
||||
Debug.assert(!host.resolveModuleNames || !host.resolveTypeReferenceDirectives);
|
||||
return hostCache.getOrCreateEntry(fileName) !== undefined;
|
||||
},
|
||||
readFile: (fileName): string => {
|
||||
@ -3788,7 +3789,11 @@ namespace ts {
|
||||
// other than those within the declared type.
|
||||
isNewIdentifierLocation = true;
|
||||
|
||||
// If the object literal is being assigned to something of type 'null | { hello: string }',
|
||||
// it clearly isn't trying to satisfy the 'null' type. So we grab the non-nullable type if possible.
|
||||
typeForObject = typeChecker.getContextualType(<ObjectLiteralExpression>objectLikeContainer);
|
||||
typeForObject = typeForObject && typeForObject.getNonNullableType();
|
||||
|
||||
existingMembers = (<ObjectLiteralExpression>objectLikeContainer).properties;
|
||||
}
|
||||
else if (objectLikeContainer.kind === SyntaxKind.ObjectBindingPattern) {
|
||||
@ -3800,7 +3805,7 @@ namespace ts {
|
||||
// We don't want to complete using the type acquired by the shape
|
||||
// of the binding pattern; we are only interested in types acquired
|
||||
// through type declaration or inference.
|
||||
// Also proceed if rootDeclaration is parameter and if its containing function expression\arrow function is contextually typed -
|
||||
// Also proceed if rootDeclaration is a parameter and if its containing function expression/arrow function is contextually typed -
|
||||
// type of parameter will flow in from the contextual type of the function
|
||||
let canGetType = !!(rootDeclaration.initializer || rootDeclaration.type);
|
||||
if (!canGetType && rootDeclaration.kind === SyntaxKind.Parameter) {
|
||||
@ -4114,11 +4119,11 @@ namespace ts {
|
||||
existingImportsOrExports[name.text] = true;
|
||||
}
|
||||
|
||||
if (isEmpty(existingImportsOrExports)) {
|
||||
if (!someProperties(existingImportsOrExports)) {
|
||||
return filter(exportsOfModule, e => e.name !== "default");
|
||||
}
|
||||
|
||||
return filter(exportsOfModule, e => e.name !== "default" && !lookUp(existingImportsOrExports, e.name));
|
||||
return filter(exportsOfModule, e => e.name !== "default" && !existingImportsOrExports[e.name]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4165,7 +4170,7 @@ namespace ts {
|
||||
existingMemberNames[existingName] = true;
|
||||
}
|
||||
|
||||
return filter(contextualMemberSymbols, m => !lookUp(existingMemberNames, m.name));
|
||||
return filter(contextualMemberSymbols, m => !existingMemberNames[m.name]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4187,7 +4192,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
return filter(symbols, a => !lookUp(seenNames, a.name));
|
||||
return filter(symbols, a => !seenNames[a.name]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4247,7 +4252,7 @@ namespace ts {
|
||||
addRange(entries, keywordCompletions);
|
||||
}
|
||||
|
||||
return { isMemberCompletion, isNewIdentifierLocation, entries };
|
||||
return { isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation || isSourceFileJavaScript(sourceFile), entries };
|
||||
|
||||
function getJavaScriptCompletionEntries(sourceFile: SourceFile, position: number, uniqueNames: Map<string>): CompletionEntry[] {
|
||||
const entries: CompletionEntry[] = [];
|
||||
@ -4323,7 +4328,7 @@ namespace ts {
|
||||
const entry = createCompletionEntry(symbol, location, performCharacterChecks);
|
||||
if (entry) {
|
||||
const id = escapeIdentifier(entry.name);
|
||||
if (!lookUp(uniqueNames, id)) {
|
||||
if (!uniqueNames[id]) {
|
||||
entries.push(entry);
|
||||
uniqueNames[id] = id;
|
||||
}
|
||||
@ -5151,7 +5156,7 @@ namespace ts {
|
||||
// Type reference directives
|
||||
const typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position);
|
||||
if (typeReferenceDirective) {
|
||||
const referenceFile = lookUp(program.getResolvedTypeReferenceDirectives(), typeReferenceDirective.fileName);
|
||||
const referenceFile = program.getResolvedTypeReferenceDirectives()[typeReferenceDirective.fileName];
|
||||
if (referenceFile && referenceFile.resolvedFileName) {
|
||||
return [getDefinitionInfoForFileReference(typeReferenceDirective.fileName, referenceFile.resolvedFileName)];
|
||||
}
|
||||
@ -5323,7 +5328,7 @@ namespace ts {
|
||||
for (const referencedSymbol of referencedSymbols) {
|
||||
for (const referenceEntry of referencedSymbol.references) {
|
||||
const fileName = referenceEntry.fileName;
|
||||
let documentHighlights = getProperty(fileNameToDocumentHighlights, fileName);
|
||||
let documentHighlights = fileNameToDocumentHighlights[fileName];
|
||||
if (!documentHighlights) {
|
||||
documentHighlights = { fileName, highlightSpans: [] };
|
||||
|
||||
@ -6068,7 +6073,7 @@ namespace ts {
|
||||
|
||||
const nameTable = getNameTable(sourceFile);
|
||||
|
||||
if (lookUp(nameTable, internedName) !== undefined) {
|
||||
if (nameTable[internedName] !== undefined) {
|
||||
result = result || [];
|
||||
getReferencesInNode(sourceFile, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result, symbolToIndex);
|
||||
}
|
||||
@ -6745,7 +6750,7 @@ namespace ts {
|
||||
// the function will add any found symbol of the property-name, then its sub-routine will call
|
||||
// getPropertySymbolsFromBaseTypes again to walk up any base types to prevent revisiting already
|
||||
// visited symbol, interface "C", the sub-routine will pass the current symbol as previousIterationSymbol.
|
||||
if (hasProperty(previousIterationSymbolsCache, symbol.name)) {
|
||||
if (symbol.name in previousIterationSymbolsCache) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -311,9 +311,9 @@ namespace ts {
|
||||
// 'in' does not have this effect.
|
||||
if ("getModuleResolutionsForFile" in this.shimHost) {
|
||||
this.resolveModuleNames = (moduleNames: string[], containingFile: string) => {
|
||||
const resolutionsInFile = <Map<string>>JSON.parse(this.shimHost.getModuleResolutionsForFile(containingFile));
|
||||
const resolutionsInFile = <MapLike<string>>JSON.parse(this.shimHost.getModuleResolutionsForFile(containingFile));
|
||||
return map(moduleNames, name => {
|
||||
const result = lookUp(resolutionsInFile, name);
|
||||
const result = getProperty(resolutionsInFile, name);
|
||||
return result ? { resolvedFileName: result } : undefined;
|
||||
});
|
||||
};
|
||||
@ -323,8 +323,8 @@ namespace ts {
|
||||
}
|
||||
if ("getTypeReferenceDirectiveResolutionsForFile" in this.shimHost) {
|
||||
this.resolveTypeReferenceDirectives = (typeDirectiveNames: string[], containingFile: string) => {
|
||||
const typeDirectivesForFile = <Map<ResolvedTypeReferenceDirective>>JSON.parse(this.shimHost.getTypeReferenceDirectiveResolutionsForFile(containingFile));
|
||||
return map(typeDirectiveNames, name => lookUp(typeDirectivesForFile, name));
|
||||
const typeDirectivesForFile = <MapLike<ResolvedTypeReferenceDirective>>JSON.parse(this.shimHost.getTypeReferenceDirectiveResolutionsForFile(containingFile));
|
||||
return map(typeDirectiveNames, name => getProperty(typeDirectivesForFile, name));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,7 +237,7 @@ namespace ts.SignatureHelp {
|
||||
const typeChecker = program.getTypeChecker();
|
||||
for (const sourceFile of program.getSourceFiles()) {
|
||||
const nameToDeclarations = sourceFile.getNamedDeclarations();
|
||||
const declarations = getProperty(nameToDeclarations, name.text);
|
||||
const declarations = nameToDeclarations[name.text];
|
||||
|
||||
if (declarations) {
|
||||
for (const declaration of declarations) {
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
tests/cases/conformance/ambient/ambientShorthand_isImplicitAny.ts(1,16): error TS7005: Variable '"jquery"' implicitly has an 'any' type.
|
||||
|
||||
|
||||
==== tests/cases/conformance/ambient/ambientShorthand_isImplicitAny.ts (1 errors) ====
|
||||
declare module "jquery";
|
||||
~~~~~~~~
|
||||
!!! error TS7005: Variable '"jquery"' implicitly has an 'any' type.
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
//// [ambientShorthand_isImplicitAny.ts]
|
||||
declare module "jquery";
|
||||
|
||||
|
||||
//// [ambientShorthand_isImplicitAny.js]
|
||||
@ -0,0 +1,46 @@
|
||||
tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(13,1): error TS2322: Type 'A[]' is not assignable to type 'ReadonlyArray<B>'.
|
||||
Types of property 'concat' are incompatible.
|
||||
Type '{ (...items: A[][]): A[]; (...items: (A | A[])[]): A[]; }' is not assignable to type '{ <U extends ReadonlyArray<B>>(...items: U[]): B[]; (...items: B[][]): B[]; (...items: (B | B[])[]): B[]; }'.
|
||||
Type 'A[]' is not assignable to type 'B[]'.
|
||||
Type 'A' is not assignable to type 'B'.
|
||||
Property 'b' is missing in type 'A'.
|
||||
tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error TS2322: Type 'C<A>' is not assignable to type 'ReadonlyArray<B>'.
|
||||
Types of property 'concat' are incompatible.
|
||||
Type '{ (...items: A[][]): A[]; (...items: (A | A[])[]): A[]; }' is not assignable to type '{ <U extends ReadonlyArray<B>>(...items: U[]): B[]; (...items: B[][]): B[]; (...items: (B | B[])[]): B[]; }'.
|
||||
Type 'A[]' is not assignable to type 'B[]'.
|
||||
Type 'A' is not assignable to type 'B'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts (2 errors) ====
|
||||
class A { a }
|
||||
class B extends A { b }
|
||||
class C<T> extends Array<T> { c }
|
||||
declare var ara: A[];
|
||||
declare var arb: B[];
|
||||
declare var cra: C<A>;
|
||||
declare var crb: C<B>;
|
||||
declare var rra: ReadonlyArray<A>;
|
||||
declare var rrb: ReadonlyArray<B>;
|
||||
rra = ara;
|
||||
rrb = arb; // OK, Array<B> is assignable to ReadonlyArray<A>
|
||||
rra = arb;
|
||||
rrb = ara; // error: 'A' is not assignable to 'B'
|
||||
~~~
|
||||
!!! error TS2322: Type 'A[]' is not assignable to type 'ReadonlyArray<B>'.
|
||||
!!! error TS2322: Types of property 'concat' are incompatible.
|
||||
!!! error TS2322: Type '{ (...items: A[][]): A[]; (...items: (A | A[])[]): A[]; }' is not assignable to type '{ <U extends ReadonlyArray<B>>(...items: U[]): B[]; (...items: B[][]): B[]; (...items: (B | B[])[]): B[]; }'.
|
||||
!!! error TS2322: Type 'A[]' is not assignable to type 'B[]'.
|
||||
!!! error TS2322: Type 'A' is not assignable to type 'B'.
|
||||
!!! error TS2322: Property 'b' is missing in type 'A'.
|
||||
|
||||
rra = cra;
|
||||
rra = crb; // OK, C<B> is assignable to ReadonlyArray<A>
|
||||
rrb = crb;
|
||||
rrb = cra; // error: 'A' is not assignable to 'B'
|
||||
~~~
|
||||
!!! error TS2322: Type 'C<A>' is not assignable to type 'ReadonlyArray<B>'.
|
||||
!!! error TS2322: Types of property 'concat' are incompatible.
|
||||
!!! error TS2322: Type '{ (...items: A[][]): A[]; (...items: (A | A[])[]): A[]; }' is not assignable to type '{ <U extends ReadonlyArray<B>>(...items: U[]): B[]; (...items: B[][]): B[]; (...items: (B | B[])[]): B[]; }'.
|
||||
!!! error TS2322: Type 'A[]' is not assignable to type 'B[]'.
|
||||
!!! error TS2322: Type 'A' is not assignable to type 'B'.
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
//// [arrayOfSubtypeIsAssignableToReadonlyArray.ts]
|
||||
class A { a }
|
||||
class B extends A { b }
|
||||
class C<T> extends Array<T> { c }
|
||||
declare var ara: A[];
|
||||
declare var arb: B[];
|
||||
declare var cra: C<A>;
|
||||
declare var crb: C<B>;
|
||||
declare var rra: ReadonlyArray<A>;
|
||||
declare var rrb: ReadonlyArray<B>;
|
||||
rra = ara;
|
||||
rrb = arb; // OK, Array<B> is assignable to ReadonlyArray<A>
|
||||
rra = arb;
|
||||
rrb = ara; // error: 'A' is not assignable to 'B'
|
||||
|
||||
rra = cra;
|
||||
rra = crb; // OK, C<B> is assignable to ReadonlyArray<A>
|
||||
rrb = crb;
|
||||
rrb = cra; // error: 'A' is not assignable to 'B'
|
||||
|
||||
|
||||
//// [arrayOfSubtypeIsAssignableToReadonlyArray.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var A = (function () {
|
||||
function A() {
|
||||
}
|
||||
return A;
|
||||
}());
|
||||
var B = (function (_super) {
|
||||
__extends(B, _super);
|
||||
function B() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
return B;
|
||||
}(A));
|
||||
var C = (function (_super) {
|
||||
__extends(C, _super);
|
||||
function C() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
return C;
|
||||
}(Array));
|
||||
rra = ara;
|
||||
rrb = arb; // OK, Array<B> is assignable to ReadonlyArray<A>
|
||||
rra = arb;
|
||||
rrb = ara; // error: 'A' is not assignable to 'B'
|
||||
rra = cra;
|
||||
rra = crb; // OK, C<B> is assignable to ReadonlyArray<A>
|
||||
rrb = crb;
|
||||
rrb = cra; // error: 'A' is not assignable to 'B'
|
||||
@ -13,14 +13,14 @@ let C = class extends class extends class {
|
||||
}
|
||||
}
|
||||
{
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.b = 2;
|
||||
}
|
||||
}
|
||||
{
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.c = 3;
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,8 +37,8 @@ class D {
|
||||
}
|
||||
}
|
||||
class E extends D {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.z = true;
|
||||
}
|
||||
}
|
||||
|
||||
33
tests/baselines/reference/exportDefaultProperty2.js
Normal file
33
tests/baselines/reference/exportDefaultProperty2.js
Normal file
@ -0,0 +1,33 @@
|
||||
//// [tests/cases/compiler/exportDefaultProperty2.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
// This test is just like exportEqualsProperty2, but with `export default`.
|
||||
|
||||
class C {
|
||||
static B: number;
|
||||
}
|
||||
namespace C {
|
||||
export interface B { c: number }
|
||||
}
|
||||
|
||||
export default C.B;
|
||||
|
||||
//// [b.ts]
|
||||
import B from "./a.ts";
|
||||
const x: B = { c: B };
|
||||
|
||||
|
||||
//// [a.js]
|
||||
// This test is just like exportEqualsProperty2, but with `export default`.
|
||||
"use strict";
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
exports.__esModule = true;
|
||||
exports["default"] = C.B;
|
||||
//// [b.js]
|
||||
"use strict";
|
||||
var a_ts_1 = require("./a.ts");
|
||||
var x = { c: a_ts_1["default"] };
|
||||
32
tests/baselines/reference/exportDefaultProperty2.symbols
Normal file
32
tests/baselines/reference/exportDefaultProperty2.symbols
Normal file
@ -0,0 +1,32 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
// This test is just like exportEqualsProperty2, but with `export default`.
|
||||
|
||||
class C {
|
||||
>C : Symbol(C, Decl(a.ts, 0, 0), Decl(a.ts, 4, 1))
|
||||
|
||||
static B: number;
|
||||
>B : Symbol(default, Decl(a.ts, 2, 9), Decl(a.ts, 5, 13))
|
||||
}
|
||||
namespace C {
|
||||
>C : Symbol(C, Decl(a.ts, 0, 0), Decl(a.ts, 4, 1))
|
||||
|
||||
export interface B { c: number }
|
||||
>B : Symbol(B, Decl(a.ts, 2, 9), Decl(a.ts, 5, 13))
|
||||
>c : Symbol(B.c, Decl(a.ts, 6, 24))
|
||||
}
|
||||
|
||||
export default C.B;
|
||||
>C.B : Symbol(default, Decl(a.ts, 2, 9), Decl(a.ts, 5, 13))
|
||||
>C : Symbol(C, Decl(a.ts, 0, 0), Decl(a.ts, 4, 1))
|
||||
>B : Symbol(default, Decl(a.ts, 2, 9), Decl(a.ts, 5, 13))
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
import B from "./a.ts";
|
||||
>B : Symbol(B, Decl(b.ts, 0, 6))
|
||||
|
||||
const x: B = { c: B };
|
||||
>x : Symbol(x, Decl(b.ts, 1, 5))
|
||||
>B : Symbol(B, Decl(b.ts, 0, 6))
|
||||
>c : Symbol(c, Decl(b.ts, 1, 14))
|
||||
>B : Symbol(B, Decl(b.ts, 0, 6))
|
||||
|
||||
33
tests/baselines/reference/exportDefaultProperty2.types
Normal file
33
tests/baselines/reference/exportDefaultProperty2.types
Normal file
@ -0,0 +1,33 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
// This test is just like exportEqualsProperty2, but with `export default`.
|
||||
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
static B: number;
|
||||
>B : number
|
||||
}
|
||||
namespace C {
|
||||
>C : typeof C
|
||||
|
||||
export interface B { c: number }
|
||||
>B : B
|
||||
>c : number
|
||||
}
|
||||
|
||||
export default C.B;
|
||||
>C.B : number
|
||||
>C : typeof C
|
||||
>B : number
|
||||
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
import B from "./a.ts";
|
||||
>B : number
|
||||
|
||||
const x: B = { c: B };
|
||||
>x : B
|
||||
>B : B
|
||||
>{ c: B } : { c: number; }
|
||||
>c : number
|
||||
>B : number
|
||||
|
||||
32
tests/baselines/reference/exportEqualsProperty2.js
Normal file
32
tests/baselines/reference/exportEqualsProperty2.js
Normal file
@ -0,0 +1,32 @@
|
||||
//// [tests/cases/compiler/exportEqualsProperty2.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
// This test is just like exportDefaultProperty2, but with `export =`.
|
||||
|
||||
class C {
|
||||
static B: number;
|
||||
}
|
||||
namespace C {
|
||||
export interface B { c: number }
|
||||
}
|
||||
|
||||
export = C.B;
|
||||
|
||||
//// [b.ts]
|
||||
import B = require("./a.ts");
|
||||
const x: B = { c: B };
|
||||
|
||||
|
||||
//// [a.js]
|
||||
// This test is just like exportDefaultProperty2, but with `export =`.
|
||||
"use strict";
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
module.exports = C.B;
|
||||
//// [b.js]
|
||||
"use strict";
|
||||
var B = require("./a.ts");
|
||||
var x = { c: B };
|
||||
32
tests/baselines/reference/exportEqualsProperty2.symbols
Normal file
32
tests/baselines/reference/exportEqualsProperty2.symbols
Normal file
@ -0,0 +1,32 @@
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
import B = require("./a.ts");
|
||||
>B : Symbol(B, Decl(b.ts, 0, 0))
|
||||
|
||||
const x: B = { c: B };
|
||||
>x : Symbol(x, Decl(b.ts, 1, 5))
|
||||
>B : Symbol(B, Decl(b.ts, 0, 0))
|
||||
>c : Symbol(c, Decl(b.ts, 1, 14))
|
||||
>B : Symbol(B, Decl(b.ts, 0, 0))
|
||||
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
// This test is just like exportDefaultProperty2, but with `export =`.
|
||||
|
||||
class C {
|
||||
>C : Symbol(C, Decl(a.ts, 0, 0), Decl(a.ts, 4, 1))
|
||||
|
||||
static B: number;
|
||||
>B : Symbol(C.B, Decl(a.ts, 2, 9), Decl(a.ts, 5, 13))
|
||||
}
|
||||
namespace C {
|
||||
>C : Symbol(C, Decl(a.ts, 0, 0), Decl(a.ts, 4, 1))
|
||||
|
||||
export interface B { c: number }
|
||||
>B : Symbol(B, Decl(a.ts, 2, 9), Decl(a.ts, 5, 13))
|
||||
>c : Symbol(B.c, Decl(a.ts, 6, 24))
|
||||
}
|
||||
|
||||
export = C.B;
|
||||
>C.B : Symbol(C.B, Decl(a.ts, 2, 9), Decl(a.ts, 5, 13))
|
||||
>C : Symbol(C, Decl(a.ts, 0, 0), Decl(a.ts, 4, 1))
|
||||
>B : Symbol(C.B, Decl(a.ts, 2, 9), Decl(a.ts, 5, 13))
|
||||
|
||||
33
tests/baselines/reference/exportEqualsProperty2.types
Normal file
33
tests/baselines/reference/exportEqualsProperty2.types
Normal file
@ -0,0 +1,33 @@
|
||||
=== tests/cases/compiler/b.ts ===
|
||||
import B = require("./a.ts");
|
||||
>B : number
|
||||
|
||||
const x: B = { c: B };
|
||||
>x : B
|
||||
>B : B
|
||||
>{ c: B } : { c: number; }
|
||||
>c : number
|
||||
>B : number
|
||||
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
// This test is just like exportDefaultProperty2, but with `export =`.
|
||||
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
static B: number;
|
||||
>B : number
|
||||
}
|
||||
namespace C {
|
||||
>C : typeof C
|
||||
|
||||
export interface B { c: number }
|
||||
>B : B
|
||||
>c : number
|
||||
}
|
||||
|
||||
export = C.B;
|
||||
>C.B : number
|
||||
>C : typeof C
|
||||
>B : number
|
||||
|
||||
65
tests/baselines/reference/implicitConstParameters.errors.txt
Normal file
65
tests/baselines/reference/implicitConstParameters.errors.txt
Normal file
@ -0,0 +1,65 @@
|
||||
tests/cases/compiler/implicitConstParameters.ts(39,27): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/compiler/implicitConstParameters.ts(45,27): error TS2532: Object is possibly 'undefined'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/implicitConstParameters.ts (2 errors) ====
|
||||
|
||||
function doSomething(cb: () => void) {
|
||||
cb();
|
||||
}
|
||||
|
||||
function fn(x: number | string) {
|
||||
if (typeof x === 'number') {
|
||||
doSomething(() => x.toFixed());
|
||||
}
|
||||
}
|
||||
|
||||
function f1(x: string | undefined) {
|
||||
if (!x) {
|
||||
return;
|
||||
}
|
||||
doSomething(() => x.length);
|
||||
}
|
||||
|
||||
function f2(x: string | undefined) {
|
||||
if (x) {
|
||||
doSomething(() => {
|
||||
doSomething(() => x.length);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function f3(x: string | undefined) {
|
||||
inner();
|
||||
function inner() {
|
||||
if (x) {
|
||||
doSomething(() => x.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function f4(x: string | undefined) {
|
||||
x = "abc"; // causes x to be considered non-const
|
||||
if (x) {
|
||||
doSomething(() => x.length);
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
}
|
||||
|
||||
function f5(x: string | undefined) {
|
||||
if (x) {
|
||||
doSomething(() => x.length);
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
x = "abc"; // causes x to be considered non-const
|
||||
}
|
||||
|
||||
|
||||
function f6(x: string | undefined) {
|
||||
const y = x || "";
|
||||
if (x) {
|
||||
doSomething(() => y.length);
|
||||
}
|
||||
}
|
||||
106
tests/baselines/reference/implicitConstParameters.js
Normal file
106
tests/baselines/reference/implicitConstParameters.js
Normal file
@ -0,0 +1,106 @@
|
||||
//// [implicitConstParameters.ts]
|
||||
|
||||
function doSomething(cb: () => void) {
|
||||
cb();
|
||||
}
|
||||
|
||||
function fn(x: number | string) {
|
||||
if (typeof x === 'number') {
|
||||
doSomething(() => x.toFixed());
|
||||
}
|
||||
}
|
||||
|
||||
function f1(x: string | undefined) {
|
||||
if (!x) {
|
||||
return;
|
||||
}
|
||||
doSomething(() => x.length);
|
||||
}
|
||||
|
||||
function f2(x: string | undefined) {
|
||||
if (x) {
|
||||
doSomething(() => {
|
||||
doSomething(() => x.length);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function f3(x: string | undefined) {
|
||||
inner();
|
||||
function inner() {
|
||||
if (x) {
|
||||
doSomething(() => x.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function f4(x: string | undefined) {
|
||||
x = "abc"; // causes x to be considered non-const
|
||||
if (x) {
|
||||
doSomething(() => x.length);
|
||||
}
|
||||
}
|
||||
|
||||
function f5(x: string | undefined) {
|
||||
if (x) {
|
||||
doSomething(() => x.length);
|
||||
}
|
||||
x = "abc"; // causes x to be considered non-const
|
||||
}
|
||||
|
||||
|
||||
function f6(x: string | undefined) {
|
||||
const y = x || "";
|
||||
if (x) {
|
||||
doSomething(() => y.length);
|
||||
}
|
||||
}
|
||||
|
||||
//// [implicitConstParameters.js]
|
||||
function doSomething(cb) {
|
||||
cb();
|
||||
}
|
||||
function fn(x) {
|
||||
if (typeof x === 'number') {
|
||||
doSomething(function () { return x.toFixed(); });
|
||||
}
|
||||
}
|
||||
function f1(x) {
|
||||
if (!x) {
|
||||
return;
|
||||
}
|
||||
doSomething(function () { return x.length; });
|
||||
}
|
||||
function f2(x) {
|
||||
if (x) {
|
||||
doSomething(function () {
|
||||
doSomething(function () { return x.length; });
|
||||
});
|
||||
}
|
||||
}
|
||||
function f3(x) {
|
||||
inner();
|
||||
function inner() {
|
||||
if (x) {
|
||||
doSomething(function () { return x.length; });
|
||||
}
|
||||
}
|
||||
}
|
||||
function f4(x) {
|
||||
x = "abc"; // causes x to be considered non-const
|
||||
if (x) {
|
||||
doSomething(function () { return x.length; });
|
||||
}
|
||||
}
|
||||
function f5(x) {
|
||||
if (x) {
|
||||
doSomething(function () { return x.length; });
|
||||
}
|
||||
x = "abc"; // causes x to be considered non-const
|
||||
}
|
||||
function f6(x) {
|
||||
var y = x || "";
|
||||
if (x) {
|
||||
doSomething(function () { return y.length; });
|
||||
}
|
||||
}
|
||||
22
tests/baselines/reference/indexWithUndefinedAndNull.js
Normal file
22
tests/baselines/reference/indexWithUndefinedAndNull.js
Normal file
@ -0,0 +1,22 @@
|
||||
//// [indexWithUndefinedAndNull.ts]
|
||||
interface N {
|
||||
[n: number]: string;
|
||||
}
|
||||
interface S {
|
||||
[s: string]: number;
|
||||
}
|
||||
let n: N;
|
||||
let s: S;
|
||||
let str: string = n[undefined];
|
||||
str = n[null];
|
||||
let num: number = s[undefined];
|
||||
num = s[null];
|
||||
|
||||
|
||||
//// [indexWithUndefinedAndNull.js]
|
||||
var n;
|
||||
var s;
|
||||
var str = n[undefined];
|
||||
str = n[null];
|
||||
var num = s[undefined];
|
||||
num = s[null];
|
||||
39
tests/baselines/reference/indexWithUndefinedAndNull.symbols
Normal file
39
tests/baselines/reference/indexWithUndefinedAndNull.symbols
Normal file
@ -0,0 +1,39 @@
|
||||
=== tests/cases/compiler/indexWithUndefinedAndNull.ts ===
|
||||
interface N {
|
||||
>N : Symbol(N, Decl(indexWithUndefinedAndNull.ts, 0, 0))
|
||||
|
||||
[n: number]: string;
|
||||
>n : Symbol(n, Decl(indexWithUndefinedAndNull.ts, 1, 5))
|
||||
}
|
||||
interface S {
|
||||
>S : Symbol(S, Decl(indexWithUndefinedAndNull.ts, 2, 1))
|
||||
|
||||
[s: string]: number;
|
||||
>s : Symbol(s, Decl(indexWithUndefinedAndNull.ts, 4, 5))
|
||||
}
|
||||
let n: N;
|
||||
>n : Symbol(n, Decl(indexWithUndefinedAndNull.ts, 6, 3))
|
||||
>N : Symbol(N, Decl(indexWithUndefinedAndNull.ts, 0, 0))
|
||||
|
||||
let s: S;
|
||||
>s : Symbol(s, Decl(indexWithUndefinedAndNull.ts, 7, 3))
|
||||
>S : Symbol(S, Decl(indexWithUndefinedAndNull.ts, 2, 1))
|
||||
|
||||
let str: string = n[undefined];
|
||||
>str : Symbol(str, Decl(indexWithUndefinedAndNull.ts, 8, 3))
|
||||
>n : Symbol(n, Decl(indexWithUndefinedAndNull.ts, 6, 3))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
str = n[null];
|
||||
>str : Symbol(str, Decl(indexWithUndefinedAndNull.ts, 8, 3))
|
||||
>n : Symbol(n, Decl(indexWithUndefinedAndNull.ts, 6, 3))
|
||||
|
||||
let num: number = s[undefined];
|
||||
>num : Symbol(num, Decl(indexWithUndefinedAndNull.ts, 10, 3))
|
||||
>s : Symbol(s, Decl(indexWithUndefinedAndNull.ts, 7, 3))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
num = s[null];
|
||||
>num : Symbol(num, Decl(indexWithUndefinedAndNull.ts, 10, 3))
|
||||
>s : Symbol(s, Decl(indexWithUndefinedAndNull.ts, 7, 3))
|
||||
|
||||
47
tests/baselines/reference/indexWithUndefinedAndNull.types
Normal file
47
tests/baselines/reference/indexWithUndefinedAndNull.types
Normal file
@ -0,0 +1,47 @@
|
||||
=== tests/cases/compiler/indexWithUndefinedAndNull.ts ===
|
||||
interface N {
|
||||
>N : N
|
||||
|
||||
[n: number]: string;
|
||||
>n : number
|
||||
}
|
||||
interface S {
|
||||
>S : S
|
||||
|
||||
[s: string]: number;
|
||||
>s : string
|
||||
}
|
||||
let n: N;
|
||||
>n : N
|
||||
>N : N
|
||||
|
||||
let s: S;
|
||||
>s : S
|
||||
>S : S
|
||||
|
||||
let str: string = n[undefined];
|
||||
>str : string
|
||||
>n[undefined] : string
|
||||
>n : N
|
||||
>undefined : undefined
|
||||
|
||||
str = n[null];
|
||||
>str = n[null] : string
|
||||
>str : string
|
||||
>n[null] : string
|
||||
>n : N
|
||||
>null : null
|
||||
|
||||
let num: number = s[undefined];
|
||||
>num : number
|
||||
>s[undefined] : number
|
||||
>s : S
|
||||
>undefined : undefined
|
||||
|
||||
num = s[null];
|
||||
>num = s[null] : number
|
||||
>num : number
|
||||
>s[null] : number
|
||||
>s : S
|
||||
>null : null
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts(9,19): error TS2454: Variable 'n' is used before being assigned.
|
||||
tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts(9,19): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.
|
||||
tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts(10,7): error TS2454: Variable 'n' is used before being assigned.
|
||||
tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts(10,7): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.
|
||||
tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts(11,19): error TS2454: Variable 's' is used before being assigned.
|
||||
tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts(11,19): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.
|
||||
tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts(12,7): error TS2454: Variable 's' is used before being assigned.
|
||||
tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts(12,7): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/indexWithUndefinedAndNullStrictNullChecks.ts (8 errors) ====
|
||||
interface N {
|
||||
[n: number]: string;
|
||||
}
|
||||
interface S {
|
||||
[s: string]: number;
|
||||
}
|
||||
let n: N;
|
||||
let s: S;
|
||||
let str: string = n[undefined];
|
||||
~
|
||||
!!! error TS2454: Variable 'n' is used before being assigned.
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.
|
||||
str = n[null];
|
||||
~
|
||||
!!! error TS2454: Variable 'n' is used before being assigned.
|
||||
~~~~~~~
|
||||
!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.
|
||||
let num: number = s[undefined];
|
||||
~
|
||||
!!! error TS2454: Variable 's' is used before being assigned.
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.
|
||||
num = s[null];
|
||||
~
|
||||
!!! error TS2454: Variable 's' is used before being assigned.
|
||||
~~~~~~~
|
||||
!!! error TS2342: An index expression argument must be of type 'string', 'number', 'symbol', or 'any'.
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
//// [indexWithUndefinedAndNullStrictNullChecks.ts]
|
||||
interface N {
|
||||
[n: number]: string;
|
||||
}
|
||||
interface S {
|
||||
[s: string]: number;
|
||||
}
|
||||
let n: N;
|
||||
let s: S;
|
||||
let str: string = n[undefined];
|
||||
str = n[null];
|
||||
let num: number = s[undefined];
|
||||
num = s[null];
|
||||
|
||||
|
||||
//// [indexWithUndefinedAndNullStrictNullChecks.js]
|
||||
var n;
|
||||
var s;
|
||||
var str = n[undefined];
|
||||
str = n[null];
|
||||
var num = s[undefined];
|
||||
num = s[null];
|
||||
24
tests/baselines/reference/jsdocLiteral.js
Normal file
24
tests/baselines/reference/jsdocLiteral.js
Normal file
@ -0,0 +1,24 @@
|
||||
//// [in.js]
|
||||
/**
|
||||
* @param {'literal'} p1
|
||||
* @param {"literal"} p2
|
||||
* @param {'literal' | 'other'} p3
|
||||
* @param {'literal' | number} p4
|
||||
* @param {12 | true | 'str'} p5
|
||||
*/
|
||||
function f(p1, p2, p3, p4, p5) {
|
||||
return p1 + p2 + p3 + p4 + p5 + '.';
|
||||
}
|
||||
|
||||
|
||||
//// [out.js]
|
||||
/**
|
||||
* @param {'literal'} p1
|
||||
* @param {"literal"} p2
|
||||
* @param {'literal' | 'other'} p3
|
||||
* @param {'literal' | number} p4
|
||||
* @param {12 | true | 'str'} p5
|
||||
*/
|
||||
function f(p1, p2, p3, p4, p5) {
|
||||
return p1 + p2 + p3 + p4 + p5 + '.';
|
||||
}
|
||||
24
tests/baselines/reference/jsdocLiteral.symbols
Normal file
24
tests/baselines/reference/jsdocLiteral.symbols
Normal file
@ -0,0 +1,24 @@
|
||||
=== tests/cases/conformance/jsdoc/in.js ===
|
||||
/**
|
||||
* @param {'literal'} p1
|
||||
* @param {"literal"} p2
|
||||
* @param {'literal' | 'other'} p3
|
||||
* @param {'literal' | number} p4
|
||||
* @param {12 | true | 'str'} p5
|
||||
*/
|
||||
function f(p1, p2, p3, p4, p5) {
|
||||
>f : Symbol(f, Decl(in.js, 0, 0))
|
||||
>p1 : Symbol(p1, Decl(in.js, 7, 11))
|
||||
>p2 : Symbol(p2, Decl(in.js, 7, 14))
|
||||
>p3 : Symbol(p3, Decl(in.js, 7, 18))
|
||||
>p4 : Symbol(p4, Decl(in.js, 7, 22))
|
||||
>p5 : Symbol(p5, Decl(in.js, 7, 26))
|
||||
|
||||
return p1 + p2 + p3 + p4 + p5 + '.';
|
||||
>p1 : Symbol(p1, Decl(in.js, 7, 11))
|
||||
>p2 : Symbol(p2, Decl(in.js, 7, 14))
|
||||
>p3 : Symbol(p3, Decl(in.js, 7, 18))
|
||||
>p4 : Symbol(p4, Decl(in.js, 7, 22))
|
||||
>p5 : Symbol(p5, Decl(in.js, 7, 26))
|
||||
}
|
||||
|
||||
30
tests/baselines/reference/jsdocLiteral.types
Normal file
30
tests/baselines/reference/jsdocLiteral.types
Normal file
@ -0,0 +1,30 @@
|
||||
=== tests/cases/conformance/jsdoc/in.js ===
|
||||
/**
|
||||
* @param {'literal'} p1
|
||||
* @param {"literal"} p2
|
||||
* @param {'literal' | 'other'} p3
|
||||
* @param {'literal' | number} p4
|
||||
* @param {12 | true | 'str'} p5
|
||||
*/
|
||||
function f(p1, p2, p3, p4, p5) {
|
||||
>f : (p1: "literal", p2: "literal", p3: "literal" | "other", p4: number | "literal", p5: true | 12 | "str") => string
|
||||
>p1 : "literal"
|
||||
>p2 : "literal"
|
||||
>p3 : "literal" | "other"
|
||||
>p4 : number | "literal"
|
||||
>p5 : true | 12 | "str"
|
||||
|
||||
return p1 + p2 + p3 + p4 + p5 + '.';
|
||||
>p1 + p2 + p3 + p4 + p5 + '.' : string
|
||||
>p1 + p2 + p3 + p4 + p5 : string
|
||||
>p1 + p2 + p3 + p4 : string
|
||||
>p1 + p2 + p3 : string
|
||||
>p1 + p2 : string
|
||||
>p1 : "literal"
|
||||
>p2 : "literal"
|
||||
>p3 : "literal" | "other"
|
||||
>p4 : number | "literal"
|
||||
>p5 : true | 12 | "str"
|
||||
>'.' : string
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/node_modules/bar/index.d.ts(1,1): message TS4090: Conflicting library definitions for 'alpha' found at '/node_modules/bar/node_modules/alpha/index.d.ts' and '/node_modules/foo/node_modules/alpha/index.d.ts'. Copy the correct file to the 'typings' folder to resolve this conflict.
|
||||
/node_modules/bar/index.d.ts(1,1): message TS4090: Conflicting definitions for 'alpha' found at '/node_modules/bar/node_modules/alpha/index.d.ts' and '/node_modules/foo/node_modules/alpha/index.d.ts'. Consider installing a specific version of this library to resolve the conflict.
|
||||
|
||||
|
||||
==== /src/root.ts (0 errors) ====
|
||||
@ -18,7 +18,7 @@
|
||||
==== /node_modules/bar/index.d.ts (1 errors) ====
|
||||
/// <reference types="alpha" />
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! message TS4090: Conflicting library definitions for 'alpha' found at '/node_modules/bar/node_modules/alpha/index.d.ts' and '/node_modules/foo/node_modules/alpha/index.d.ts'. Copy the correct file to the 'typings' folder to resolve this conflict.
|
||||
!!! message TS4090: Conflicting definitions for 'alpha' found at '/node_modules/bar/node_modules/alpha/index.d.ts' and '/node_modules/foo/node_modules/alpha/index.d.ts'. Consider installing a specific version of this library to resolve the conflict.
|
||||
declare var bar: any;
|
||||
|
||||
==== /node_modules/bar/node_modules/alpha/index.d.ts (0 errors) ====
|
||||
|
||||
@ -1,11 +1,38 @@
|
||||
//// [input.js]
|
||||
|
||||
function C() {
|
||||
this.m = null;
|
||||
}
|
||||
C.prototype.m = function() {
|
||||
this.nothing();
|
||||
};
|
||||
}
|
||||
class X {
|
||||
constructor() {
|
||||
this.m = this.m.bind(this);
|
||||
this.mistake = 'frankly, complete nonsense';
|
||||
}
|
||||
m() {
|
||||
}
|
||||
mistake() {
|
||||
}
|
||||
}
|
||||
let x = new X();
|
||||
X.prototype.mistake = false;
|
||||
x.m();
|
||||
x.mistake;
|
||||
class Y {
|
||||
mistake() {
|
||||
}
|
||||
m() {
|
||||
}
|
||||
constructor() {
|
||||
this.m = this.m.bind(this);
|
||||
this.mistake = 'even more nonsense';
|
||||
}
|
||||
}
|
||||
Y.prototype.mistake = true;
|
||||
let y = new Y();
|
||||
y.m();
|
||||
y.mistake();
|
||||
|
||||
|
||||
//// [output.js]
|
||||
@ -15,3 +42,33 @@ function C() {
|
||||
C.prototype.m = function () {
|
||||
this.nothing();
|
||||
};
|
||||
var X = (function () {
|
||||
function X() {
|
||||
this.m = this.m.bind(this);
|
||||
this.mistake = 'frankly, complete nonsense';
|
||||
}
|
||||
X.prototype.m = function () {
|
||||
};
|
||||
X.prototype.mistake = function () {
|
||||
};
|
||||
return X;
|
||||
}());
|
||||
var x = new X();
|
||||
X.prototype.mistake = false;
|
||||
x.m();
|
||||
x.mistake;
|
||||
var Y = (function () {
|
||||
function Y() {
|
||||
this.m = this.m.bind(this);
|
||||
this.mistake = 'even more nonsense';
|
||||
}
|
||||
Y.prototype.mistake = function () {
|
||||
};
|
||||
Y.prototype.m = function () {
|
||||
};
|
||||
return Y;
|
||||
}());
|
||||
Y.prototype.mistake = true;
|
||||
var y = new Y();
|
||||
y.m();
|
||||
y.mistake();
|
||||
|
||||
@ -1,19 +1,106 @@
|
||||
=== tests/cases/conformance/salsa/input.js ===
|
||||
|
||||
function C() {
|
||||
>C : Symbol(C, Decl(input.js, 0, 0))
|
||||
|
||||
this.m = null;
|
||||
>m : Symbol(C.m, Decl(input.js, 1, 14), Decl(input.js, 3, 1))
|
||||
>m : Symbol(C.m, Decl(input.js, 0, 14), Decl(input.js, 2, 1))
|
||||
}
|
||||
C.prototype.m = function() {
|
||||
>C.prototype : Symbol(C.m, Decl(input.js, 1, 14), Decl(input.js, 3, 1))
|
||||
>C.prototype : Symbol(C.m, Decl(input.js, 0, 14), Decl(input.js, 2, 1))
|
||||
>C : Symbol(C, Decl(input.js, 0, 0))
|
||||
>prototype : Symbol(Function.prototype, Decl(lib.d.ts, --, --))
|
||||
>m : Symbol(C.m, Decl(input.js, 1, 14), Decl(input.js, 3, 1))
|
||||
>m : Symbol(C.m, Decl(input.js, 0, 14), Decl(input.js, 2, 1))
|
||||
|
||||
this.nothing();
|
||||
>this : Symbol(C, Decl(input.js, 0, 0))
|
||||
}
|
||||
class X {
|
||||
>X : Symbol(X, Decl(input.js, 5, 1))
|
||||
|
||||
};
|
||||
constructor() {
|
||||
this.m = this.m.bind(this);
|
||||
>this.m : Symbol(X.m, Decl(input.js, 10, 5))
|
||||
>this : Symbol(X, Decl(input.js, 5, 1))
|
||||
>m : Symbol(X.m, Decl(input.js, 7, 19))
|
||||
>this.m.bind : Symbol(Function.bind, Decl(lib.d.ts, --, --))
|
||||
>this.m : Symbol(X.m, Decl(input.js, 10, 5))
|
||||
>this : Symbol(X, Decl(input.js, 5, 1))
|
||||
>m : Symbol(X.m, Decl(input.js, 10, 5))
|
||||
>bind : Symbol(Function.bind, Decl(lib.d.ts, --, --))
|
||||
>this : Symbol(X, Decl(input.js, 5, 1))
|
||||
|
||||
this.mistake = 'frankly, complete nonsense';
|
||||
>this.mistake : Symbol(X.mistake, Decl(input.js, 12, 5))
|
||||
>this : Symbol(X, Decl(input.js, 5, 1))
|
||||
>mistake : Symbol(X.mistake, Decl(input.js, 8, 35))
|
||||
}
|
||||
m() {
|
||||
>m : Symbol(X.m, Decl(input.js, 10, 5))
|
||||
}
|
||||
mistake() {
|
||||
>mistake : Symbol(X.mistake, Decl(input.js, 12, 5))
|
||||
}
|
||||
}
|
||||
let x = new X();
|
||||
>x : Symbol(x, Decl(input.js, 16, 3))
|
||||
>X : Symbol(X, Decl(input.js, 5, 1))
|
||||
|
||||
X.prototype.mistake = false;
|
||||
>X.prototype.mistake : Symbol(X.mistake, Decl(input.js, 12, 5))
|
||||
>X : Symbol(X, Decl(input.js, 5, 1))
|
||||
>prototype : Symbol(X.prototype)
|
||||
|
||||
x.m();
|
||||
>x.m : Symbol(X.m, Decl(input.js, 10, 5))
|
||||
>x : Symbol(x, Decl(input.js, 16, 3))
|
||||
>m : Symbol(X.m, Decl(input.js, 10, 5))
|
||||
|
||||
x.mistake;
|
||||
>x.mistake : Symbol(X.mistake, Decl(input.js, 12, 5))
|
||||
>x : Symbol(x, Decl(input.js, 16, 3))
|
||||
>mistake : Symbol(X.mistake, Decl(input.js, 12, 5))
|
||||
|
||||
class Y {
|
||||
>Y : Symbol(Y, Decl(input.js, 19, 10))
|
||||
|
||||
mistake() {
|
||||
>mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35))
|
||||
}
|
||||
m() {
|
||||
>m : Symbol(Y.m, Decl(input.js, 22, 5), Decl(input.js, 25, 19))
|
||||
}
|
||||
constructor() {
|
||||
this.m = this.m.bind(this);
|
||||
>this.m : Symbol(Y.m, Decl(input.js, 22, 5), Decl(input.js, 25, 19))
|
||||
>this : Symbol(Y, Decl(input.js, 19, 10))
|
||||
>m : Symbol(Y.m, Decl(input.js, 22, 5), Decl(input.js, 25, 19))
|
||||
>this.m : Symbol(Y.m, Decl(input.js, 22, 5), Decl(input.js, 25, 19))
|
||||
>this : Symbol(Y, Decl(input.js, 19, 10))
|
||||
>m : Symbol(Y.m, Decl(input.js, 22, 5), Decl(input.js, 25, 19))
|
||||
>this : Symbol(Y, Decl(input.js, 19, 10))
|
||||
|
||||
this.mistake = 'even more nonsense';
|
||||
>this.mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35))
|
||||
>this : Symbol(Y, Decl(input.js, 19, 10))
|
||||
>mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35))
|
||||
}
|
||||
}
|
||||
Y.prototype.mistake = true;
|
||||
>Y.prototype.mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35))
|
||||
>Y : Symbol(Y, Decl(input.js, 19, 10))
|
||||
>prototype : Symbol(Y.prototype)
|
||||
|
||||
let y = new Y();
|
||||
>y : Symbol(y, Decl(input.js, 31, 3))
|
||||
>Y : Symbol(Y, Decl(input.js, 19, 10))
|
||||
|
||||
y.m();
|
||||
>y.m : Symbol(Y.m, Decl(input.js, 22, 5), Decl(input.js, 25, 19))
|
||||
>y : Symbol(y, Decl(input.js, 31, 3))
|
||||
>m : Symbol(Y.m, Decl(input.js, 22, 5), Decl(input.js, 25, 19))
|
||||
|
||||
y.mistake();
|
||||
>y.mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35))
|
||||
>y : Symbol(y, Decl(input.js, 31, 3))
|
||||
>mistake : Symbol(Y.mistake, Decl(input.js, 20, 9), Decl(input.js, 26, 35))
|
||||
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
=== tests/cases/conformance/salsa/input.js ===
|
||||
|
||||
function C() {
|
||||
>C : () => void
|
||||
|
||||
@ -24,6 +23,117 @@ C.prototype.m = function() {
|
||||
>this.nothing : any
|
||||
>this : { m: () => void; }
|
||||
>nothing : any
|
||||
}
|
||||
class X {
|
||||
>X : X
|
||||
|
||||
};
|
||||
constructor() {
|
||||
this.m = this.m.bind(this);
|
||||
>this.m = this.m.bind(this) : any
|
||||
>this.m : () => void
|
||||
>this : this
|
||||
>m : () => void
|
||||
>this.m.bind(this) : any
|
||||
>this.m.bind : (this: Function, thisArg: any, ...argArray: any[]) => any
|
||||
>this.m : () => void
|
||||
>this : this
|
||||
>m : () => void
|
||||
>bind : (this: Function, thisArg: any, ...argArray: any[]) => any
|
||||
>this : this
|
||||
|
||||
this.mistake = 'frankly, complete nonsense';
|
||||
>this.mistake = 'frankly, complete nonsense' : string
|
||||
>this.mistake : () => void
|
||||
>this : this
|
||||
>mistake : () => void
|
||||
>'frankly, complete nonsense' : string
|
||||
}
|
||||
m() {
|
||||
>m : () => void
|
||||
}
|
||||
mistake() {
|
||||
>mistake : () => void
|
||||
}
|
||||
}
|
||||
let x = new X();
|
||||
>x : X
|
||||
>new X() : X
|
||||
>X : typeof X
|
||||
|
||||
X.prototype.mistake = false;
|
||||
>X.prototype.mistake = false : boolean
|
||||
>X.prototype.mistake : () => void
|
||||
>X.prototype : X
|
||||
>X : typeof X
|
||||
>prototype : X
|
||||
>mistake : () => void
|
||||
>false : boolean
|
||||
|
||||
x.m();
|
||||
>x.m() : void
|
||||
>x.m : () => void
|
||||
>x : X
|
||||
>m : () => void
|
||||
|
||||
x.mistake;
|
||||
>x.mistake : () => void
|
||||
>x : X
|
||||
>mistake : () => void
|
||||
|
||||
class Y {
|
||||
>Y : Y
|
||||
|
||||
mistake() {
|
||||
>mistake : any
|
||||
}
|
||||
m() {
|
||||
>m : any
|
||||
}
|
||||
constructor() {
|
||||
this.m = this.m.bind(this);
|
||||
>this.m = this.m.bind(this) : any
|
||||
>this.m : any
|
||||
>this : this
|
||||
>m : any
|
||||
>this.m.bind(this) : any
|
||||
>this.m.bind : any
|
||||
>this.m : any
|
||||
>this : this
|
||||
>m : any
|
||||
>bind : any
|
||||
>this : this
|
||||
|
||||
this.mistake = 'even more nonsense';
|
||||
>this.mistake = 'even more nonsense' : string
|
||||
>this.mistake : any
|
||||
>this : this
|
||||
>mistake : any
|
||||
>'even more nonsense' : string
|
||||
}
|
||||
}
|
||||
Y.prototype.mistake = true;
|
||||
>Y.prototype.mistake = true : boolean
|
||||
>Y.prototype.mistake : any
|
||||
>Y.prototype : Y
|
||||
>Y : typeof Y
|
||||
>prototype : Y
|
||||
>mistake : any
|
||||
>true : boolean
|
||||
|
||||
let y = new Y();
|
||||
>y : Y
|
||||
>new Y() : Y
|
||||
>Y : typeof Y
|
||||
|
||||
y.m();
|
||||
>y.m() : any
|
||||
>y.m : any
|
||||
>y : Y
|
||||
>m : any
|
||||
|
||||
y.mistake();
|
||||
>y.mistake() : any
|
||||
>y.mistake : any
|
||||
>y : Y
|
||||
>mistake : any
|
||||
|
||||
|
||||
63
tests/baselines/reference/nestedLoopTypeGuards.js
Normal file
63
tests/baselines/reference/nestedLoopTypeGuards.js
Normal file
@ -0,0 +1,63 @@
|
||||
//// [nestedLoopTypeGuards.ts]
|
||||
// Repros from #10378
|
||||
|
||||
function f1() {
|
||||
var a: boolean | number | string;
|
||||
if (typeof a !== 'boolean') {
|
||||
// a is narrowed to "number | string"
|
||||
for (var i = 0; i < 1; i++) {
|
||||
for (var j = 0; j < 1; j++) {}
|
||||
if (typeof a === 'string') {
|
||||
// a is narrowed to "string'
|
||||
for (var j = 0; j < 1; j++) {
|
||||
a.length; // Should not error here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function f2() {
|
||||
var a: string | number;
|
||||
if (typeof a === 'string') {
|
||||
while (1) {
|
||||
while (1) {}
|
||||
if (typeof a === 'string') {
|
||||
while (1) {
|
||||
a.length; // Should not error here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//// [nestedLoopTypeGuards.js]
|
||||
// Repros from #10378
|
||||
function f1() {
|
||||
var a;
|
||||
if (typeof a !== 'boolean') {
|
||||
// a is narrowed to "number | string"
|
||||
for (var i = 0; i < 1; i++) {
|
||||
for (var j = 0; j < 1; j++) { }
|
||||
if (typeof a === 'string') {
|
||||
// a is narrowed to "string'
|
||||
for (var j = 0; j < 1; j++) {
|
||||
a.length; // Should not error here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function f2() {
|
||||
var a;
|
||||
if (typeof a === 'string') {
|
||||
while (1) {
|
||||
while (1) { }
|
||||
if (typeof a === 'string') {
|
||||
while (1) {
|
||||
a.length; // Should not error here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
66
tests/baselines/reference/nestedLoopTypeGuards.symbols
Normal file
66
tests/baselines/reference/nestedLoopTypeGuards.symbols
Normal file
@ -0,0 +1,66 @@
|
||||
=== tests/cases/compiler/nestedLoopTypeGuards.ts ===
|
||||
// Repros from #10378
|
||||
|
||||
function f1() {
|
||||
>f1 : Symbol(f1, Decl(nestedLoopTypeGuards.ts, 0, 0))
|
||||
|
||||
var a: boolean | number | string;
|
||||
>a : Symbol(a, Decl(nestedLoopTypeGuards.ts, 3, 7))
|
||||
|
||||
if (typeof a !== 'boolean') {
|
||||
>a : Symbol(a, Decl(nestedLoopTypeGuards.ts, 3, 7))
|
||||
|
||||
// a is narrowed to "number | string"
|
||||
for (var i = 0; i < 1; i++) {
|
||||
>i : Symbol(i, Decl(nestedLoopTypeGuards.ts, 6, 16))
|
||||
>i : Symbol(i, Decl(nestedLoopTypeGuards.ts, 6, 16))
|
||||
>i : Symbol(i, Decl(nestedLoopTypeGuards.ts, 6, 16))
|
||||
|
||||
for (var j = 0; j < 1; j++) {}
|
||||
>j : Symbol(j, Decl(nestedLoopTypeGuards.ts, 7, 20), Decl(nestedLoopTypeGuards.ts, 10, 24))
|
||||
>j : Symbol(j, Decl(nestedLoopTypeGuards.ts, 7, 20), Decl(nestedLoopTypeGuards.ts, 10, 24))
|
||||
>j : Symbol(j, Decl(nestedLoopTypeGuards.ts, 7, 20), Decl(nestedLoopTypeGuards.ts, 10, 24))
|
||||
|
||||
if (typeof a === 'string') {
|
||||
>a : Symbol(a, Decl(nestedLoopTypeGuards.ts, 3, 7))
|
||||
|
||||
// a is narrowed to "string'
|
||||
for (var j = 0; j < 1; j++) {
|
||||
>j : Symbol(j, Decl(nestedLoopTypeGuards.ts, 7, 20), Decl(nestedLoopTypeGuards.ts, 10, 24))
|
||||
>j : Symbol(j, Decl(nestedLoopTypeGuards.ts, 7, 20), Decl(nestedLoopTypeGuards.ts, 10, 24))
|
||||
>j : Symbol(j, Decl(nestedLoopTypeGuards.ts, 7, 20), Decl(nestedLoopTypeGuards.ts, 10, 24))
|
||||
|
||||
a.length; // Should not error here
|
||||
>a.length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
>a : Symbol(a, Decl(nestedLoopTypeGuards.ts, 3, 7))
|
||||
>length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function f2() {
|
||||
>f2 : Symbol(f2, Decl(nestedLoopTypeGuards.ts, 16, 1))
|
||||
|
||||
var a: string | number;
|
||||
>a : Symbol(a, Decl(nestedLoopTypeGuards.ts, 19, 7))
|
||||
|
||||
if (typeof a === 'string') {
|
||||
>a : Symbol(a, Decl(nestedLoopTypeGuards.ts, 19, 7))
|
||||
|
||||
while (1) {
|
||||
while (1) {}
|
||||
if (typeof a === 'string') {
|
||||
>a : Symbol(a, Decl(nestedLoopTypeGuards.ts, 19, 7))
|
||||
|
||||
while (1) {
|
||||
a.length; // Should not error here
|
||||
>a.length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
>a : Symbol(a, Decl(nestedLoopTypeGuards.ts, 19, 7))
|
||||
>length : Symbol(String.length, Decl(lib.d.ts, --, --))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
96
tests/baselines/reference/nestedLoopTypeGuards.types
Normal file
96
tests/baselines/reference/nestedLoopTypeGuards.types
Normal file
@ -0,0 +1,96 @@
|
||||
=== tests/cases/compiler/nestedLoopTypeGuards.ts ===
|
||||
// Repros from #10378
|
||||
|
||||
function f1() {
|
||||
>f1 : () => void
|
||||
|
||||
var a: boolean | number | string;
|
||||
>a : string | number | boolean
|
||||
|
||||
if (typeof a !== 'boolean') {
|
||||
>typeof a !== 'boolean' : boolean
|
||||
>typeof a : string
|
||||
>a : string | number | boolean
|
||||
>'boolean' : "boolean"
|
||||
|
||||
// a is narrowed to "number | string"
|
||||
for (var i = 0; i < 1; i++) {
|
||||
>i : number
|
||||
>0 : number
|
||||
>i < 1 : boolean
|
||||
>i : number
|
||||
>1 : number
|
||||
>i++ : number
|
||||
>i : number
|
||||
|
||||
for (var j = 0; j < 1; j++) {}
|
||||
>j : number
|
||||
>0 : number
|
||||
>j < 1 : boolean
|
||||
>j : number
|
||||
>1 : number
|
||||
>j++ : number
|
||||
>j : number
|
||||
|
||||
if (typeof a === 'string') {
|
||||
>typeof a === 'string' : boolean
|
||||
>typeof a : string
|
||||
>a : string | number
|
||||
>'string' : "string"
|
||||
|
||||
// a is narrowed to "string'
|
||||
for (var j = 0; j < 1; j++) {
|
||||
>j : number
|
||||
>0 : number
|
||||
>j < 1 : boolean
|
||||
>j : number
|
||||
>1 : number
|
||||
>j++ : number
|
||||
>j : number
|
||||
|
||||
a.length; // Should not error here
|
||||
>a.length : number
|
||||
>a : string
|
||||
>length : number
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function f2() {
|
||||
>f2 : () => void
|
||||
|
||||
var a: string | number;
|
||||
>a : string | number
|
||||
|
||||
if (typeof a === 'string') {
|
||||
>typeof a === 'string' : boolean
|
||||
>typeof a : string
|
||||
>a : string | number
|
||||
>'string' : "string"
|
||||
|
||||
while (1) {
|
||||
>1 : number
|
||||
|
||||
while (1) {}
|
||||
>1 : number
|
||||
|
||||
if (typeof a === 'string') {
|
||||
>typeof a === 'string' : boolean
|
||||
>typeof a : string
|
||||
>a : string
|
||||
>'string' : "string"
|
||||
|
||||
while (1) {
|
||||
>1 : number
|
||||
|
||||
a.length; // Should not error here
|
||||
>a.length : number
|
||||
>a : string
|
||||
>length : number
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
22
tests/baselines/reference/noErrorTruncation.errors.txt
Normal file
22
tests/baselines/reference/noErrorTruncation.errors.txt
Normal file
@ -0,0 +1,22 @@
|
||||
tests/cases/compiler/noErrorTruncation.ts(10,7): error TS2322: Type 'number' is not assignable to type '{ someLongOptionA: string; } | { someLongOptionB: string; } | { someLongOptionC: string; } | { someLongOptionD: string; } | { someLongOptionE: string; } | { someLongOptionF: string; }'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/noErrorTruncation.ts (1 errors) ====
|
||||
// @noErrorTruncation
|
||||
|
||||
type SomeLongOptionA = { someLongOptionA: string }
|
||||
type SomeLongOptionB = { someLongOptionB: string }
|
||||
type SomeLongOptionC = { someLongOptionC: string }
|
||||
type SomeLongOptionD = { someLongOptionD: string }
|
||||
type SomeLongOptionE = { someLongOptionE: string }
|
||||
type SomeLongOptionF = { someLongOptionF: string }
|
||||
|
||||
const x: SomeLongOptionA
|
||||
~
|
||||
!!! error TS2322: Type 'number' is not assignable to type '{ someLongOptionA: string; } | { someLongOptionB: string; } | { someLongOptionC: string; } | { someLongOptionD: string; } | { someLongOptionE: string; } | { someLongOptionF: string; }'.
|
||||
| SomeLongOptionB
|
||||
| SomeLongOptionC
|
||||
| SomeLongOptionD
|
||||
| SomeLongOptionE
|
||||
| SomeLongOptionF = 42;
|
||||
|
||||
21
tests/baselines/reference/noErrorTruncation.js
Normal file
21
tests/baselines/reference/noErrorTruncation.js
Normal file
@ -0,0 +1,21 @@
|
||||
//// [noErrorTruncation.ts]
|
||||
// @noErrorTruncation
|
||||
|
||||
type SomeLongOptionA = { someLongOptionA: string }
|
||||
type SomeLongOptionB = { someLongOptionB: string }
|
||||
type SomeLongOptionC = { someLongOptionC: string }
|
||||
type SomeLongOptionD = { someLongOptionD: string }
|
||||
type SomeLongOptionE = { someLongOptionE: string }
|
||||
type SomeLongOptionF = { someLongOptionF: string }
|
||||
|
||||
const x: SomeLongOptionA
|
||||
| SomeLongOptionB
|
||||
| SomeLongOptionC
|
||||
| SomeLongOptionD
|
||||
| SomeLongOptionE
|
||||
| SomeLongOptionF = 42;
|
||||
|
||||
|
||||
//// [noErrorTruncation.js]
|
||||
// @noErrorTruncation
|
||||
var x = 42;
|
||||
@ -15,11 +15,14 @@ tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(5,18): error TS
|
||||
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(7,5): error TS1182: A destructuring declaration must have an initializer.
|
||||
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(7,13): error TS7008: Member 'b3' implicitly has an 'any' type.
|
||||
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(7,25): error TS7008: Member 'b3' implicitly has an 'any' type.
|
||||
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(9,6): error TS7031: Binding element 'a1' implicitly has an 'any' type.
|
||||
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(9,26): error TS7031: Binding element 'b1' implicitly has an 'any' type.
|
||||
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(9,6): error TS7031: Binding element 'a4' implicitly has an 'any' type.
|
||||
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(9,26): error TS7031: Binding element 'b4' implicitly has an 'any' type.
|
||||
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(9,46): error TS7005: Variable 'c4' implicitly has an 'any' type.
|
||||
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(9,62): error TS7005: Variable 'd4' implicitly has an 'any' type.
|
||||
tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(11,6): error TS7031: Binding element 'a5' implicitly has an 'any' type.
|
||||
|
||||
|
||||
==== tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts (19 errors) ====
|
||||
==== tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts (22 errors) ====
|
||||
var [a], {b}, c, d; // error
|
||||
~~~
|
||||
!!! error TS1182: A destructuring declaration must have an initializer.
|
||||
@ -62,8 +65,16 @@ tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration.ts(9,26): error TS
|
||||
~~
|
||||
!!! error TS7008: Member 'b3' implicitly has an 'any' type.
|
||||
|
||||
var [a1] = [undefined], {b1} = { b1: null }, c1 = undefined, d1 = null; // error
|
||||
var [a4] = [undefined], {b4} = { b4: null }, c4 = undefined, d4 = null; // error
|
||||
~~
|
||||
!!! error TS7031: Binding element 'a1' implicitly has an 'any' type.
|
||||
!!! error TS7031: Binding element 'a4' implicitly has an 'any' type.
|
||||
~~
|
||||
!!! error TS7031: Binding element 'b1' implicitly has an 'any' type.
|
||||
!!! error TS7031: Binding element 'b4' implicitly has an 'any' type.
|
||||
~~
|
||||
!!! error TS7005: Variable 'c4' implicitly has an 'any' type.
|
||||
~~
|
||||
!!! error TS7005: Variable 'd4' implicitly has an 'any' type.
|
||||
|
||||
var [a5 = undefined] = []; // error
|
||||
~~
|
||||
!!! error TS7031: Binding element 'a5' implicitly has an 'any' type.
|
||||
@ -7,11 +7,14 @@ var [a2]: [any], {b2}: { b2: any }, c2: any, d2: any;
|
||||
|
||||
var {b3}: { b3 }, c3: { b3 }; // error in type instead
|
||||
|
||||
var [a1] = [undefined], {b1} = { b1: null }, c1 = undefined, d1 = null; // error
|
||||
var [a4] = [undefined], {b4} = { b4: null }, c4 = undefined, d4 = null; // error
|
||||
|
||||
var [a5 = undefined] = []; // error
|
||||
|
||||
//// [noImplicitAnyDestructuringVarDeclaration.js]
|
||||
var a = (void 0)[0], b = (void 0).b, c, d; // error
|
||||
var _a = (void 0)[0], a1 = _a === void 0 ? undefined : _a, _b = (void 0).b1, b1 = _b === void 0 ? null : _b, c1 = undefined, d1 = null; // error
|
||||
var a2 = (void 0)[0], b2 = (void 0).b2, c2, d2;
|
||||
var b3 = (void 0).b3, c3; // error in type instead
|
||||
var a1 = [undefined][0], b1 = { b1: null }.b1, c1 = undefined, d1 = null; // error
|
||||
var a4 = [undefined][0], b4 = { b4: null }.b4, c4 = undefined, d4 = null; // error
|
||||
var _c = [][0], a5 = _c === void 0 ? undefined : _c; // error
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
//// [noImplicitAnyDestructuringVarDeclaration2.ts]
|
||||
let [a, b, c] = [1, 2, 3]; // no error
|
||||
let [a1 = 10, b1 = 10, c1 = 10] = [1, 2, 3]; // no error
|
||||
let [a2 = undefined, b2 = undefined, c2 = undefined] = [1, 2, 3]; // no error
|
||||
let [a3 = <any>undefined, b3 = <any>null, c3 = <any>undefined] = [1, 2, 3]; // no error
|
||||
let [a4] = [<any>undefined], [b4] = [<any>null], c4 = <any>undefined, d4 = <any>null; // no error
|
||||
|
||||
let {x, y, z} = { x: 1, y: 2, z: 3 }; // no error
|
||||
let {x1 = 10, y1 = 10, z1 = 10} = { x1: 1, y1: 2, z1: 3 }; // no error
|
||||
let {x2 = undefined, y2 = undefined, z2 = undefined} = { x2: 1, y2: 2, z2: 3 }; // no error
|
||||
let {x3 = <any>undefined, y3 = <any>null, z3 = <any>undefined} = { x3: 1, y3: 2, z3: 3 }; // no error
|
||||
let {x4} = { x4: <any>undefined }, {y4} = { y4: <any>null }; // no error
|
||||
|
||||
|
||||
//// [noImplicitAnyDestructuringVarDeclaration2.js]
|
||||
var _a = [1, 2, 3], a = _a[0], b = _a[1], c = _a[2]; // no error
|
||||
var _b = [1, 2, 3], _c = _b[0], a1 = _c === void 0 ? 10 : _c, _d = _b[1], b1 = _d === void 0 ? 10 : _d, _e = _b[2], c1 = _e === void 0 ? 10 : _e; // no error
|
||||
var _f = [1, 2, 3], _g = _f[0], a2 = _g === void 0 ? undefined : _g, _h = _f[1], b2 = _h === void 0 ? undefined : _h, _j = _f[2], c2 = _j === void 0 ? undefined : _j; // no error
|
||||
var _k = [1, 2, 3], _l = _k[0], a3 = _l === void 0 ? undefined : _l, _m = _k[1], b3 = _m === void 0 ? null : _m, _o = _k[2], c3 = _o === void 0 ? undefined : _o; // no error
|
||||
var a4 = [undefined][0], b4 = [null][0], c4 = undefined, d4 = null; // no error
|
||||
var _p = { x: 1, y: 2, z: 3 }, x = _p.x, y = _p.y, z = _p.z; // no error
|
||||
var _q = { x1: 1, y1: 2, z1: 3 }, _r = _q.x1, x1 = _r === void 0 ? 10 : _r, _s = _q.y1, y1 = _s === void 0 ? 10 : _s, _t = _q.z1, z1 = _t === void 0 ? 10 : _t; // no error
|
||||
var _u = { x2: 1, y2: 2, z2: 3 }, _v = _u.x2, x2 = _v === void 0 ? undefined : _v, _w = _u.y2, y2 = _w === void 0 ? undefined : _w, _x = _u.z2, z2 = _x === void 0 ? undefined : _x; // no error
|
||||
var _y = { x3: 1, y3: 2, z3: 3 }, _z = _y.x3, x3 = _z === void 0 ? undefined : _z, _0 = _y.y3, y3 = _0 === void 0 ? null : _0, _1 = _y.z3, z3 = _1 === void 0 ? undefined : _1; // no error
|
||||
var x4 = { x4: undefined }.x4, y4 = { y4: null }.y4; // no error
|
||||
@ -0,0 +1,78 @@
|
||||
=== tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts ===
|
||||
let [a, b, c] = [1, 2, 3]; // no error
|
||||
>a : Symbol(a, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 0, 5))
|
||||
>b : Symbol(b, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 0, 7))
|
||||
>c : Symbol(c, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 0, 10))
|
||||
|
||||
let [a1 = 10, b1 = 10, c1 = 10] = [1, 2, 3]; // no error
|
||||
>a1 : Symbol(a1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 1, 5))
|
||||
>b1 : Symbol(b1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 1, 13))
|
||||
>c1 : Symbol(c1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 1, 22))
|
||||
|
||||
let [a2 = undefined, b2 = undefined, c2 = undefined] = [1, 2, 3]; // no error
|
||||
>a2 : Symbol(a2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 2, 5))
|
||||
>undefined : Symbol(undefined)
|
||||
>b2 : Symbol(b2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 2, 20))
|
||||
>undefined : Symbol(undefined)
|
||||
>c2 : Symbol(c2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 2, 36))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
let [a3 = <any>undefined, b3 = <any>null, c3 = <any>undefined] = [1, 2, 3]; // no error
|
||||
>a3 : Symbol(a3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 3, 5))
|
||||
>undefined : Symbol(undefined)
|
||||
>b3 : Symbol(b3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 3, 25))
|
||||
>c3 : Symbol(c3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 3, 41))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
let [a4] = [<any>undefined], [b4] = [<any>null], c4 = <any>undefined, d4 = <any>null; // no error
|
||||
>a4 : Symbol(a4, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 4, 5))
|
||||
>undefined : Symbol(undefined)
|
||||
>b4 : Symbol(b4, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 4, 30))
|
||||
>c4 : Symbol(c4, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 4, 48))
|
||||
>undefined : Symbol(undefined)
|
||||
>d4 : Symbol(d4, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 4, 69))
|
||||
|
||||
let {x, y, z} = { x: 1, y: 2, z: 3 }; // no error
|
||||
>x : Symbol(x, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 6, 5))
|
||||
>y : Symbol(y, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 6, 7))
|
||||
>z : Symbol(z, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 6, 10))
|
||||
>x : Symbol(x, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 6, 17))
|
||||
>y : Symbol(y, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 6, 23))
|
||||
>z : Symbol(z, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 6, 29))
|
||||
|
||||
let {x1 = 10, y1 = 10, z1 = 10} = { x1: 1, y1: 2, z1: 3 }; // no error
|
||||
>x1 : Symbol(x1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 7, 5))
|
||||
>y1 : Symbol(y1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 7, 13))
|
||||
>z1 : Symbol(z1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 7, 22))
|
||||
>x1 : Symbol(x1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 7, 35))
|
||||
>y1 : Symbol(y1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 7, 42))
|
||||
>z1 : Symbol(z1, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 7, 49))
|
||||
|
||||
let {x2 = undefined, y2 = undefined, z2 = undefined} = { x2: 1, y2: 2, z2: 3 }; // no error
|
||||
>x2 : Symbol(x2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 8, 5))
|
||||
>undefined : Symbol(undefined)
|
||||
>y2 : Symbol(y2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 8, 20))
|
||||
>undefined : Symbol(undefined)
|
||||
>z2 : Symbol(z2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 8, 36))
|
||||
>undefined : Symbol(undefined)
|
||||
>x2 : Symbol(x2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 8, 56))
|
||||
>y2 : Symbol(y2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 8, 63))
|
||||
>z2 : Symbol(z2, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 8, 70))
|
||||
|
||||
let {x3 = <any>undefined, y3 = <any>null, z3 = <any>undefined} = { x3: 1, y3: 2, z3: 3 }; // no error
|
||||
>x3 : Symbol(x3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 9, 5))
|
||||
>undefined : Symbol(undefined)
|
||||
>y3 : Symbol(y3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 9, 25))
|
||||
>z3 : Symbol(z3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 9, 41))
|
||||
>undefined : Symbol(undefined)
|
||||
>x3 : Symbol(x3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 9, 66))
|
||||
>y3 : Symbol(y3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 9, 73))
|
||||
>z3 : Symbol(z3, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 9, 80))
|
||||
|
||||
let {x4} = { x4: <any>undefined }, {y4} = { y4: <any>null }; // no error
|
||||
>x4 : Symbol(x4, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 10, 5))
|
||||
>x4 : Symbol(x4, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 10, 12))
|
||||
>undefined : Symbol(undefined)
|
||||
>y4 : Symbol(y4, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 10, 36))
|
||||
>y4 : Symbol(y4, Decl(noImplicitAnyDestructuringVarDeclaration2.ts, 10, 43))
|
||||
|
||||
@ -0,0 +1,137 @@
|
||||
=== tests/cases/compiler/noImplicitAnyDestructuringVarDeclaration2.ts ===
|
||||
let [a, b, c] = [1, 2, 3]; // no error
|
||||
>a : number
|
||||
>b : number
|
||||
>c : number
|
||||
>[1, 2, 3] : [number, number, number]
|
||||
>1 : number
|
||||
>2 : number
|
||||
>3 : number
|
||||
|
||||
let [a1 = 10, b1 = 10, c1 = 10] = [1, 2, 3]; // no error
|
||||
>a1 : number
|
||||
>10 : number
|
||||
>b1 : number
|
||||
>10 : number
|
||||
>c1 : number
|
||||
>10 : number
|
||||
>[1, 2, 3] : [number, number, number]
|
||||
>1 : number
|
||||
>2 : number
|
||||
>3 : number
|
||||
|
||||
let [a2 = undefined, b2 = undefined, c2 = undefined] = [1, 2, 3]; // no error
|
||||
>a2 : number
|
||||
>undefined : undefined
|
||||
>b2 : number
|
||||
>undefined : undefined
|
||||
>c2 : number
|
||||
>undefined : undefined
|
||||
>[1, 2, 3] : [number, number, number]
|
||||
>1 : number
|
||||
>2 : number
|
||||
>3 : number
|
||||
|
||||
let [a3 = <any>undefined, b3 = <any>null, c3 = <any>undefined] = [1, 2, 3]; // no error
|
||||
>a3 : number
|
||||
><any>undefined : any
|
||||
>undefined : undefined
|
||||
>b3 : number
|
||||
><any>null : any
|
||||
>null : null
|
||||
>c3 : number
|
||||
><any>undefined : any
|
||||
>undefined : undefined
|
||||
>[1, 2, 3] : [number, number, number]
|
||||
>1 : number
|
||||
>2 : number
|
||||
>3 : number
|
||||
|
||||
let [a4] = [<any>undefined], [b4] = [<any>null], c4 = <any>undefined, d4 = <any>null; // no error
|
||||
>a4 : any
|
||||
>[<any>undefined] : [any]
|
||||
><any>undefined : any
|
||||
>undefined : undefined
|
||||
>b4 : any
|
||||
>[<any>null] : [any]
|
||||
><any>null : any
|
||||
>null : null
|
||||
>c4 : any
|
||||
><any>undefined : any
|
||||
>undefined : undefined
|
||||
>d4 : any
|
||||
><any>null : any
|
||||
>null : null
|
||||
|
||||
let {x, y, z} = { x: 1, y: 2, z: 3 }; // no error
|
||||
>x : number
|
||||
>y : number
|
||||
>z : number
|
||||
>{ x: 1, y: 2, z: 3 } : { x: number; y: number; z: number; }
|
||||
>x : number
|
||||
>1 : number
|
||||
>y : number
|
||||
>2 : number
|
||||
>z : number
|
||||
>3 : number
|
||||
|
||||
let {x1 = 10, y1 = 10, z1 = 10} = { x1: 1, y1: 2, z1: 3 }; // no error
|
||||
>x1 : number
|
||||
>10 : number
|
||||
>y1 : number
|
||||
>10 : number
|
||||
>z1 : number
|
||||
>10 : number
|
||||
>{ x1: 1, y1: 2, z1: 3 } : { x1?: number; y1?: number; z1?: number; }
|
||||
>x1 : number
|
||||
>1 : number
|
||||
>y1 : number
|
||||
>2 : number
|
||||
>z1 : number
|
||||
>3 : number
|
||||
|
||||
let {x2 = undefined, y2 = undefined, z2 = undefined} = { x2: 1, y2: 2, z2: 3 }; // no error
|
||||
>x2 : number
|
||||
>undefined : undefined
|
||||
>y2 : number
|
||||
>undefined : undefined
|
||||
>z2 : number
|
||||
>undefined : undefined
|
||||
>{ x2: 1, y2: 2, z2: 3 } : { x2?: number; y2?: number; z2?: number; }
|
||||
>x2 : number
|
||||
>1 : number
|
||||
>y2 : number
|
||||
>2 : number
|
||||
>z2 : number
|
||||
>3 : number
|
||||
|
||||
let {x3 = <any>undefined, y3 = <any>null, z3 = <any>undefined} = { x3: 1, y3: 2, z3: 3 }; // no error
|
||||
>x3 : number
|
||||
><any>undefined : any
|
||||
>undefined : undefined
|
||||
>y3 : number
|
||||
><any>null : any
|
||||
>null : null
|
||||
>z3 : number
|
||||
><any>undefined : any
|
||||
>undefined : undefined
|
||||
>{ x3: 1, y3: 2, z3: 3 } : { x3?: number; y3?: number; z3?: number; }
|
||||
>x3 : number
|
||||
>1 : number
|
||||
>y3 : number
|
||||
>2 : number
|
||||
>z3 : number
|
||||
>3 : number
|
||||
|
||||
let {x4} = { x4: <any>undefined }, {y4} = { y4: <any>null }; // no error
|
||||
>x4 : any
|
||||
>{ x4: <any>undefined } : { x4: any; }
|
||||
>x4 : any
|
||||
><any>undefined : any
|
||||
>undefined : undefined
|
||||
>y4 : any
|
||||
>{ y4: <any>null } : { y4: any; }
|
||||
>y4 : any
|
||||
><any>null : any
|
||||
>null : null
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false,
|
||||
"noUnusedLocals": true
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false,
|
||||
"jsx": "react"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false
|
||||
},
|
||||
"files": [
|
||||
"file0.st",
|
||||
"file1.ts",
|
||||
"file2.ts"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false,
|
||||
"lib": [
|
||||
"es5",
|
||||
"es2015.promise"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false,
|
||||
"lib": [
|
||||
"es5",
|
||||
"es2015.core"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false,
|
||||
"types": [
|
||||
"jquery",
|
||||
"mocha"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
tests/cases/conformance/jsx/file.tsx(14,28): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsx/file.tsx(16,28): error TS2322: Type 'boolean' is not assignable to type 'string | number'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsx/react.d.ts (0 errors) ====
|
||||
|
||||
declare module JSX {
|
||||
interface Element { }
|
||||
interface IntrinsicElements {
|
||||
div: any;
|
||||
}
|
||||
interface ElementAttributesProperty { prop: any }
|
||||
}
|
||||
|
||||
==== tests/cases/conformance/jsx/file.tsx (2 errors) ====
|
||||
|
||||
interface IProps {
|
||||
primaryText: string,
|
||||
[propName: string]: string | number
|
||||
}
|
||||
|
||||
function VerticalNavMenuItem(prop: IProps) {
|
||||
return <div>props.primaryText</div>
|
||||
}
|
||||
|
||||
function VerticalNav() {
|
||||
return (
|
||||
<div>
|
||||
<VerticalNavMenuItem primaryText={2} /> // error
|
||||
~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
<VerticalNavMenuItem justRandomProp={2} primaryText={"hello"} /> // ok
|
||||
<VerticalNavMenuItem justRandomProp1={true} primaryText={"hello"} /> // error
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'boolean' is not assignable to type 'string | number'.
|
||||
</div>
|
||||
)
|
||||
}
|
||||
47
tests/baselines/reference/tsxAttributeResolution14.js
Normal file
47
tests/baselines/reference/tsxAttributeResolution14.js
Normal file
@ -0,0 +1,47 @@
|
||||
//// [tests/cases/conformance/jsx/tsxAttributeResolution14.tsx] ////
|
||||
|
||||
//// [react.d.ts]
|
||||
|
||||
declare module JSX {
|
||||
interface Element { }
|
||||
interface IntrinsicElements {
|
||||
div: any;
|
||||
}
|
||||
interface ElementAttributesProperty { prop: any }
|
||||
}
|
||||
|
||||
//// [file.tsx]
|
||||
|
||||
interface IProps {
|
||||
primaryText: string,
|
||||
[propName: string]: string | number
|
||||
}
|
||||
|
||||
function VerticalNavMenuItem(prop: IProps) {
|
||||
return <div>props.primaryText</div>
|
||||
}
|
||||
|
||||
function VerticalNav() {
|
||||
return (
|
||||
<div>
|
||||
<VerticalNavMenuItem primaryText={2} /> // error
|
||||
<VerticalNavMenuItem justRandomProp={2} primaryText={"hello"} /> // ok
|
||||
<VerticalNavMenuItem justRandomProp1={true} primaryText={"hello"} /> // error
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
//// [file.jsx]
|
||||
function VerticalNavMenuItem(prop) {
|
||||
return <div>props.primaryText</div>;
|
||||
}
|
||||
function VerticalNav() {
|
||||
return (<div>
|
||||
<VerticalNavMenuItem primaryText={2}/> // error
|
||||
// error
|
||||
<VerticalNavMenuItem justRandomProp={2} primaryText={"hello"}/> // ok
|
||||
// ok
|
||||
<VerticalNavMenuItem justRandomProp1={true} primaryText={"hello"}/> // error
|
||||
// error
|
||||
</div>);
|
||||
}
|
||||
13
tests/baselines/reference/typingsLookup3.js
Normal file
13
tests/baselines/reference/typingsLookup3.js
Normal file
@ -0,0 +1,13 @@
|
||||
//// [tests/cases/conformance/typings/typingsLookup3.ts] ////
|
||||
|
||||
//// [index.d.ts]
|
||||
declare var $: { x: any };
|
||||
|
||||
//// [a.ts]
|
||||
/// <reference types="JqUeRy" />
|
||||
$.x;
|
||||
|
||||
|
||||
//// [a.js]
|
||||
/// <reference types="JqUeRy" />
|
||||
$.x;
|
||||
12
tests/baselines/reference/typingsLookup3.symbols
Normal file
12
tests/baselines/reference/typingsLookup3.symbols
Normal file
@ -0,0 +1,12 @@
|
||||
=== /a.ts ===
|
||||
/// <reference types="JqUeRy" />
|
||||
$.x;
|
||||
>$.x : Symbol(x, Decl(index.d.ts, 0, 16))
|
||||
>$ : Symbol($, Decl(index.d.ts, 0, 11))
|
||||
>x : Symbol(x, Decl(index.d.ts, 0, 16))
|
||||
|
||||
=== /node_modules/@types/jquery/index.d.ts ===
|
||||
declare var $: { x: any };
|
||||
>$ : Symbol($, Decl(index.d.ts, 0, 11))
|
||||
>x : Symbol(x, Decl(index.d.ts, 0, 16))
|
||||
|
||||
12
tests/baselines/reference/typingsLookup3.trace.json
Normal file
12
tests/baselines/reference/typingsLookup3.trace.json
Normal file
@ -0,0 +1,12 @@
|
||||
[
|
||||
"======== Resolving type reference directive 'jquery', containing file '/a.ts', root directory '/node_modules/@types'. ========",
|
||||
"Resolving with primary search path '/node_modules/@types'",
|
||||
"File '/node_modules/@types/jquery/package.json' does not exist.",
|
||||
"File '/node_modules/@types/jquery/index.d.ts' exist - use it as a name resolution result.",
|
||||
"======== Type reference directive 'jquery' was successfully resolved to '/node_modules/@types/jquery/index.d.ts', primary: true. ========",
|
||||
"======== Resolving type reference directive 'jquery', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========",
|
||||
"Resolving with primary search path '/node_modules/@types'",
|
||||
"File '/node_modules/@types/jquery/package.json' does not exist.",
|
||||
"File '/node_modules/@types/jquery/index.d.ts' exist - use it as a name resolution result.",
|
||||
"======== Type reference directive 'jquery' was successfully resolved to '/node_modules/@types/jquery/index.d.ts', primary: true. ========"
|
||||
]
|
||||
12
tests/baselines/reference/typingsLookup3.types
Normal file
12
tests/baselines/reference/typingsLookup3.types
Normal file
@ -0,0 +1,12 @@
|
||||
=== /a.ts ===
|
||||
/// <reference types="JqUeRy" />
|
||||
$.x;
|
||||
>$.x : any
|
||||
>$ : { x: any; }
|
||||
>x : any
|
||||
|
||||
=== /node_modules/@types/jquery/index.d.ts ===
|
||||
declare var $: { x: any };
|
||||
>$ : { x: any; }
|
||||
>x : any
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
tests/cases/compiler/unusedParameterProperty1.ts(3,25): error TS6138: Property 'used' is declared but never used.
|
||||
|
||||
|
||||
==== tests/cases/compiler/unusedParameterProperty1.ts (1 errors) ====
|
||||
|
||||
class A {
|
||||
constructor(private used: string) {
|
||||
~~~~
|
||||
!!! error TS6138: Property 'used' is declared but never used.
|
||||
let foge = used;
|
||||
foge += "";
|
||||
}
|
||||
}
|
||||
|
||||
19
tests/baselines/reference/unusedParameterProperty1.js
Normal file
19
tests/baselines/reference/unusedParameterProperty1.js
Normal file
@ -0,0 +1,19 @@
|
||||
//// [unusedParameterProperty1.ts]
|
||||
|
||||
class A {
|
||||
constructor(private used: string) {
|
||||
let foge = used;
|
||||
foge += "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [unusedParameterProperty1.js]
|
||||
var A = (function () {
|
||||
function A(used) {
|
||||
this.used = used;
|
||||
var foge = used;
|
||||
foge += "";
|
||||
}
|
||||
return A;
|
||||
}());
|
||||
@ -0,0 +1,14 @@
|
||||
tests/cases/compiler/unusedParameterProperty2.ts(3,25): error TS6138: Property 'used' is declared but never used.
|
||||
|
||||
|
||||
==== tests/cases/compiler/unusedParameterProperty2.ts (1 errors) ====
|
||||
|
||||
class A {
|
||||
constructor(private used) {
|
||||
~~~~
|
||||
!!! error TS6138: Property 'used' is declared but never used.
|
||||
let foge = used;
|
||||
foge += "";
|
||||
}
|
||||
}
|
||||
|
||||
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