Merge remote-tracking branch 'origin/master' into enforce-const-enum-access-for-isolatedmodules
This commit is contained in:
commit
942b020081
2
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
|
@ -16,7 +16,7 @@ Please fill in the *entire* template below.
|
|||
-->
|
||||
|
||||
<!-- Please try to reproduce the issue with `typescript@next`. It may have already been fixed. -->
|
||||
**TypeScript Version:** 3.3.0-dev.201xxxxx
|
||||
**TypeScript Version:** 3.4.0-dev.201xxxxx
|
||||
|
||||
<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
|
||||
**Search Terms:**
|
||||
|
|
1100
Gulpfile.js
1100
Gulpfile.js
File diff suppressed because it is too large
Load diff
|
@ -8,10 +8,8 @@ const path = require("path");
|
|||
const fold = require("travis-fold");
|
||||
const ts = require("./lib/typescript");
|
||||
const del = require("del");
|
||||
const getDirSize = require("./scripts/build/getDirSize");
|
||||
const { getDirSize, needsUpdate, flatten } = require("./scripts/build/utils");
|
||||
const { base64VLQFormatEncode } = require("./scripts/build/sourcemaps");
|
||||
const needsUpdate = require("./scripts/build/needsUpdate");
|
||||
const { flatten } = require("./scripts/build/project");
|
||||
|
||||
// add node_modules to path so we don't need global modules, prefer the modules by adding them first
|
||||
var nodeModulesPathPrefix = path.resolve("./node_modules/.bin/") + path.delimiter;
|
||||
|
@ -361,7 +359,7 @@ file(ConfigFileFor.tsserverLibrary, [], function () {
|
|||
compilerOptions: {
|
||||
"removeComments": false,
|
||||
"stripInternal": true,
|
||||
"declarationMap": false,
|
||||
"declaration": true,
|
||||
"outFile": "tsserverlibrary.out.js"
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[![Build Status](https://travis-ci.org/Microsoft/TypeScript.svg?branch=master)](https://travis-ci.org/Microsoft/TypeScript)
|
||||
[![VSTS Build Status](https://dev.azure.com/typescript/TypeScript/_apis/build/status/Typescript/node10)](https://https://dev.azure.com/typescript/TypeScript/_build/latest?definitionId=4&view=logs)
|
||||
[![VSTS Build Status](https://dev.azure.com/typescript/TypeScript/_apis/build/status/Typescript/node10)](https://dev.azure.com/typescript/TypeScript/_build/latest?definitionId=4&view=logs)
|
||||
[![npm version](https://badge.fury.io/js/typescript.svg)](https://www.npmjs.com/package/typescript)
|
||||
[![Downloads](https://img.shields.io/npm/dm/typescript.svg)](https://www.npmjs.com/package/typescript)
|
||||
|
||||
|
|
|
@ -3715,7 +3715,7 @@ the array literal initializer expression is contextually typed by the implied ty
|
|||
|
||||
## <a name="5.3"/>5.3 Let and Const Declarations
|
||||
|
||||
Let and const declarations are exended to include optional type annotations.
|
||||
Let and const declarations are extended to include optional type annotations.
|
||||
|
||||
  *LexicalBinding:* *( Modified )*
|
||||
   *SimpleLexicalBinding*
|
||||
|
|
14
package.json
14
package.json
|
@ -2,7 +2,7 @@
|
|||
"name": "typescript",
|
||||
"author": "Microsoft Corp.",
|
||||
"homepage": "https://www.typescriptlang.org/",
|
||||
"version": "3.3.0",
|
||||
"version": "3.4.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "TypeScript is a language for application scale JavaScript development",
|
||||
"keywords": [
|
||||
|
@ -35,10 +35,8 @@
|
|||
"@types/convert-source-map": "latest",
|
||||
"@types/del": "latest",
|
||||
"@types/glob": "latest",
|
||||
"@types/gulp": "3.X",
|
||||
"@types/gulp": "^4.0.5",
|
||||
"@types/gulp-concat": "latest",
|
||||
"@types/gulp-help": "latest",
|
||||
"@types/gulp-if": "0.0.33",
|
||||
"@types/gulp-newer": "latest",
|
||||
"@types/gulp-rename": "0.0.33",
|
||||
"@types/gulp-sourcemaps": "0.0.32",
|
||||
|
@ -50,7 +48,6 @@
|
|||
"@types/mocha": "latest",
|
||||
"@types/node": "8.5.5",
|
||||
"@types/q": "latest",
|
||||
"@types/run-sequence": "latest",
|
||||
"@types/source-map-support": "latest",
|
||||
"@types/through2": "latest",
|
||||
"@types/travis-fold": "latest",
|
||||
|
@ -63,16 +60,12 @@
|
|||
"del": "latest",
|
||||
"fancy-log": "latest",
|
||||
"fs-extra": "^6.0.1",
|
||||
"gulp": "3.X",
|
||||
"gulp-clone": "latest",
|
||||
"gulp": "^4.0.0",
|
||||
"gulp-concat": "latest",
|
||||
"gulp-help": "latest",
|
||||
"gulp-if": "latest",
|
||||
"gulp-insert": "latest",
|
||||
"gulp-newer": "latest",
|
||||
"gulp-rename": "latest",
|
||||
"gulp-sourcemaps": "latest",
|
||||
"gulp-typescript": "latest",
|
||||
"istanbul": "latest",
|
||||
"jake": "latest",
|
||||
"lodash": "4.17.10",
|
||||
|
@ -86,7 +79,6 @@
|
|||
"prex": "^0.4.3",
|
||||
"q": "latest",
|
||||
"remove-internal": "^2.9.2",
|
||||
"run-sequence": "latest",
|
||||
"source-map-support": "latest",
|
||||
"through2": "latest",
|
||||
"travis-fold": "latest",
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
// @ts-check
|
||||
const merge2 = require("merge2");
|
||||
const gulp = require("./gulp");
|
||||
const rename = require("gulp-rename");
|
||||
const rm = require("./rm");
|
||||
const { localBaseline, refBaseline } = require("./tests");
|
||||
|
||||
module.exports = baselineAccept;
|
||||
|
||||
function baselineAccept(subfolder = "") {
|
||||
return merge2(baselineCopy(subfolder), baselineDelete(subfolder));
|
||||
}
|
||||
|
||||
function baselineCopy(subfolder = "") {
|
||||
return gulp.src([`${localBaseline}${subfolder ? `${subfolder}/` : ``}**`, `!${localBaseline}${subfolder}/**/*.delete`], { base: localBaseline })
|
||||
.pipe(gulp.dest(refBaseline));
|
||||
}
|
||||
|
||||
function baselineDelete(subfolder = "") {
|
||||
return gulp.src([`${localBaseline}${subfolder ? `${subfolder}/` : ``}**/*.delete`], { base: localBaseline, read: false })
|
||||
.pipe(rm())
|
||||
.pipe(rename({ extname: "" }))
|
||||
.pipe(rm(refBaseline));
|
||||
}
|
|
@ -1,12 +1,10 @@
|
|||
// @ts-check
|
||||
const browserify = require("browserify");
|
||||
const Vinyl = require("./vinyl");
|
||||
const Vinyl = require("vinyl");
|
||||
const { Transform } = require("stream");
|
||||
const { streamFromFile } = require("./utils");
|
||||
const { replaceContents } = require("./sourcemaps");
|
||||
|
||||
module.exports = browserifyFile;
|
||||
|
||||
/**
|
||||
* @param {import("browserify").Options} [opts]
|
||||
*/
|
||||
|
@ -31,4 +29,5 @@ function browserifyFile(opts) {
|
|||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.browserify = browserifyFile;
|
|
@ -1,5 +0,0 @@
|
|||
// @ts-check
|
||||
|
||||
// this just fixes the incorrect types for chalk :/
|
||||
const chalk = /**@type {import("chalk").Chalk}*/(require("chalk").default || require("chalk"));
|
||||
module.exports = chalk;
|
|
@ -1,19 +0,0 @@
|
|||
// @ts-check
|
||||
const replace = require("./replace");
|
||||
|
||||
module.exports = exports = convertConstEnum;
|
||||
|
||||
/**
|
||||
* This regexp exists to capture our const enums and replace them with normal enums in our public API
|
||||
* - this is fine since we compile with preserveConstEnums, and ensures our consumers are not locked
|
||||
* to the TS version they compile with.
|
||||
*/
|
||||
const constEnumCaptureRegexp = /^(\s*)(export )?const enum (\S+) {(\s*)$/gm;
|
||||
const constEnumReplacement = "$1$2enum $3 {$4";
|
||||
|
||||
/**
|
||||
* Converts `const enum` declarations in a .d.ts file into non-const `enum` declarations.
|
||||
*/
|
||||
function convertConstEnum() {
|
||||
return replace(constEnumCaptureRegexp, constEnumReplacement);
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
// @ts-check
|
||||
module.exports = debounce;
|
||||
|
||||
/**
|
||||
* @param {() => void} cb
|
||||
* @param {number} timeout
|
||||
* @param {DebounceOptions} [opts]
|
||||
*
|
||||
* @typedef DebounceOptions
|
||||
* @property {number} [max]
|
||||
*/
|
||||
function debounce(cb, timeout, opts = {}) {
|
||||
if (timeout < 10) timeout = 10;
|
||||
let max = opts.max || 10;
|
||||
if (max < timeout) max = timeout;
|
||||
let minTimer;
|
||||
let maxTimer;
|
||||
return trigger;
|
||||
|
||||
function trigger() {
|
||||
if (max > timeout && !maxTimer) maxTimer = setTimeout(done, max);
|
||||
if (minTimer) clearTimeout(minTimer);
|
||||
minTimer = setTimeout(done, timeout);
|
||||
}
|
||||
|
||||
function done() {
|
||||
if (maxTimer) maxTimer = void clearTimeout(maxTimer);
|
||||
if (minTimer) minTimer = void clearTimeout(minTimer);
|
||||
cb();
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
// @ts-check
|
||||
const ts = require("../../lib/typescript");
|
||||
const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util)
|
||||
|
||||
/** @type {FormatDiagnosticsHost} */
|
||||
const formatDiagnosticsHost = exports.formatDiagnosticsHost = {
|
||||
getCanonicalFileName: fileName => fileName,
|
||||
getCurrentDirectory: () => process.cwd(),
|
||||
getNewLine: () => ts.sys.newLine
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Diagnostic[]} diagnostics
|
||||
* @param {{ cwd?: string, pretty?: boolean }} [options]
|
||||
*/
|
||||
function formatDiagnostics(diagnostics, options) {
|
||||
return options && options.pretty
|
||||
? ts.formatDiagnosticsWithColorAndContext(diagnostics, getFormatDiagnosticsHost(options && options.cwd))
|
||||
: ts.formatDiagnostics(diagnostics, getFormatDiagnosticsHost(options && options.cwd));
|
||||
}
|
||||
exports.formatDiagnostics = formatDiagnostics;
|
||||
|
||||
/**
|
||||
* @param {Diagnostic[]} diagnostics
|
||||
* @param {{ cwd?: string }} [options]
|
||||
*/
|
||||
function reportDiagnostics(diagnostics, options) {
|
||||
log(formatDiagnostics(diagnostics, { cwd: options && options.cwd, pretty: process.stdout.isTTY }));
|
||||
}
|
||||
exports.reportDiagnostics = reportDiagnostics;
|
||||
|
||||
/**
|
||||
* @param {string | undefined} cwd
|
||||
* @returns {FormatDiagnosticsHost}
|
||||
*/
|
||||
function getFormatDiagnosticsHost(cwd) {
|
||||
if (!cwd || cwd === process.cwd()) return formatDiagnosticsHost;
|
||||
return {
|
||||
getCanonicalFileName: formatDiagnosticsHost.getCanonicalFileName,
|
||||
getCurrentDirectory: () => cwd,
|
||||
getNewLine: formatDiagnosticsHost.getNewLine
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {import("../../lib/typescript").FormatDiagnosticsHost} FormatDiagnosticsHost
|
||||
* @typedef {import("../../lib/typescript").Diagnostic} Diagnostic
|
||||
*/
|
||||
void 0;
|
|
@ -1,58 +0,0 @@
|
|||
// @ts-check
|
||||
const cp = require("child_process");
|
||||
const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util)
|
||||
const isWin = /^win/.test(process.platform);
|
||||
const chalk = require("./chalk");
|
||||
const { CancellationToken, CancelError } = require("prex");
|
||||
|
||||
module.exports = exec;
|
||||
|
||||
/**
|
||||
* Executes the provided command once with the supplied arguments.
|
||||
* @param {string} cmd
|
||||
* @param {string[]} args
|
||||
* @param {ExecOptions} [options]
|
||||
*
|
||||
* @typedef ExecOptions
|
||||
* @property {boolean} [ignoreExitCode]
|
||||
* @property {import("prex").CancellationToken} [cancelToken]
|
||||
*/
|
||||
function exec(cmd, args, options = {}) {
|
||||
return /**@type {Promise<{exitCode: number}>}*/(new Promise((resolve, reject) => {
|
||||
const { ignoreExitCode, cancelToken = CancellationToken.none } = options;
|
||||
cancelToken.throwIfCancellationRequested();
|
||||
|
||||
// TODO (weswig): Update child_process types to add windowsVerbatimArguments to the type definition
|
||||
const subshellFlag = isWin ? "/c" : "-c";
|
||||
const command = isWin ? [possiblyQuote(cmd), ...args] : [`${cmd} ${args.join(" ")}`];
|
||||
|
||||
log(`> ${chalk.green(cmd)} ${args.join(" ")}`);
|
||||
const proc = cp.spawn(isWin ? "cmd" : "/bin/sh", [subshellFlag, ...command], { stdio: "inherit", windowsVerbatimArguments: true });
|
||||
const registration = cancelToken.register(() => {
|
||||
log(`${chalk.red("killing")} '${chalk.green(cmd)} ${args.join(" ")}'...`);
|
||||
proc.kill("SIGINT");
|
||||
proc.kill("SIGTERM");
|
||||
reject(new CancelError());
|
||||
});
|
||||
proc.on("exit", exitCode => {
|
||||
registration.unregister();
|
||||
if (exitCode === 0 || ignoreExitCode) {
|
||||
resolve({ exitCode });
|
||||
}
|
||||
else {
|
||||
reject(new Error(`Process exited with code: ${exitCode}`));
|
||||
}
|
||||
});
|
||||
proc.on("error", error => {
|
||||
registration.unregister();
|
||||
reject(error);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} cmd
|
||||
*/
|
||||
function possiblyQuote(cmd) {
|
||||
return cmd.indexOf(" ") >= 0 ? `"${cmd}"` : cmd;
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
// @ts-check
|
||||
module.exports = finished;
|
||||
|
||||
/**
|
||||
* @param {NodeJS.ReadableStream | NodeJS.WritableStream} stream
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
function finished(stream) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const readable = "readable" in stream && stream.readable;
|
||||
const writable = "writable" in stream && stream.writable;
|
||||
|
||||
let countdown = 0;
|
||||
const cleanup = () => {
|
||||
if (readable) stream.removeListener("end", signal);
|
||||
if (writable) stream.removeListener("finish", signal);
|
||||
stream.removeListener("error", onerror);
|
||||
};
|
||||
const signal = () => {
|
||||
if (countdown > 0) {
|
||||
countdown--;
|
||||
if (countdown === 0) {
|
||||
cleanup();
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
};
|
||||
const onerror = (error) => {
|
||||
if (countdown > 0) {
|
||||
countdown = 0;
|
||||
cleanup();
|
||||
reject(error);
|
||||
}
|
||||
};
|
||||
stream.once("error", onerror);
|
||||
if (readable) {
|
||||
countdown++;
|
||||
stream.once("end", signal);
|
||||
}
|
||||
if (writable) {
|
||||
countdown++;
|
||||
stream.once("finish", signal);
|
||||
}
|
||||
if (countdown === 0) signal();
|
||||
});
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// @ts-check
|
||||
const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util)
|
||||
module.exports = getDiffTool;
|
||||
|
||||
function getDiffTool() {
|
||||
const program = process.env.DIFF;
|
||||
if (!program) {
|
||||
log.warn("Add the 'DIFF' environment variable to the path of the program you want to use.");
|
||||
process.exit(1);
|
||||
}
|
||||
return program;
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
// @ts-check
|
||||
const { lstatSync, readdirSync } = require("fs");
|
||||
const { join } = require("path");
|
||||
|
||||
/**
|
||||
* Find the size of a directory recursively.
|
||||
* Symbolic links can cause a loop.
|
||||
* @param {string} root
|
||||
* @returns {number} bytes
|
||||
*/
|
||||
function getDirSize(root) {
|
||||
const stats = lstatSync(root);
|
||||
|
||||
if (!stats.isDirectory()) {
|
||||
return stats.size;
|
||||
}
|
||||
|
||||
return readdirSync(root)
|
||||
.map(file => getDirSize(join(root, file)))
|
||||
.reduce((acc, num) => acc + num, 0);
|
||||
}
|
||||
|
||||
module.exports = getDirSize;
|
|
@ -1,149 +0,0 @@
|
|||
// @ts-check
|
||||
const path = require("path");
|
||||
const child_process = require("child_process");
|
||||
const fs = require("fs");
|
||||
const tsc = require("gulp-typescript");
|
||||
const Vinyl = require("vinyl");
|
||||
const { Duplex, Readable } = require("stream");
|
||||
const protocol = require("./protocol");
|
||||
|
||||
/**
|
||||
* @param {string | undefined} tsConfigFileName
|
||||
* @param {tsc.Settings} settings
|
||||
* @param {CreateProjectOptions} options
|
||||
*
|
||||
* @typedef CreateProjectOptions
|
||||
* @property {string} [typescript]
|
||||
* @property {boolean} [parse]
|
||||
*/
|
||||
function createProject(tsConfigFileName, settings, options) {
|
||||
settings = Object.assign({}, settings);
|
||||
options = Object.assign({}, options);
|
||||
if (settings.typescript) throw new Error();
|
||||
|
||||
const localSettings = Object.assign({}, settings);
|
||||
if (options.typescript) {
|
||||
options.typescript = path.resolve(options.typescript);
|
||||
localSettings.typescript = require(options.typescript);
|
||||
}
|
||||
|
||||
const project = tsConfigFileName === undefined ? tsc.createProject(localSettings) : tsc.createProject(tsConfigFileName, localSettings);
|
||||
const wrappedProject = /** @type {tsc.Project} */((reporter = tsc.reporter.defaultReporter()) => {
|
||||
const ts = project.typescript;
|
||||
const proc = child_process.fork(require.resolve("./worker.js"), [], {
|
||||
// Prevent errors when debugging gulpfile due to the same debug port being passed to forked children.
|
||||
execArgv: []
|
||||
});
|
||||
/** @type {Map<string, import("vinyl")>} */
|
||||
const inputs = new Map();
|
||||
/** @type {Map<string, *>} */
|
||||
const sourceFiles = new Map();
|
||||
/** @type {protocol.SourceFileHost & protocol.VinylHost} */
|
||||
const host = {
|
||||
getVinyl(path) { return inputs.get(path); },
|
||||
getSourceFile(fileName) { return sourceFiles.get(fileName); },
|
||||
createSourceFile(fileName, text, languageVersion) {
|
||||
if (text === undefined) {
|
||||
text = fs.readFileSync(fileName, "utf8");
|
||||
}
|
||||
|
||||
/** @type {protocol.SourceFile} */
|
||||
let file;
|
||||
if (options.parse) {
|
||||
file = ts.createSourceFile(fileName, text, languageVersion, /*setParentNodes*/ true);
|
||||
}
|
||||
else {
|
||||
// NOTE: the built-in reporters in gulp-typescript don't actually need a full
|
||||
// source file, so save time by faking one unless requested.
|
||||
file = /**@type {protocol.SourceFile}*/({
|
||||
pos: 0,
|
||||
end: text.length,
|
||||
kind: ts.SyntaxKind.SourceFile,
|
||||
fileName,
|
||||
text,
|
||||
languageVersion,
|
||||
statements: /**@type {*} */([]),
|
||||
endOfFileToken: { pos: text.length, end: text.length, kind: ts.SyntaxKind.EndOfFileToken },
|
||||
amdDependencies: /**@type {*} */([]),
|
||||
referencedFiles: /**@type {*} */([]),
|
||||
typeReferenceDirectives: /**@type {*} */([]),
|
||||
libReferenceDirectives: /**@type {*} */([]),
|
||||
languageVariant: ts.LanguageVariant.Standard,
|
||||
isDeclarationFile: /\.d\.ts$/.test(fileName),
|
||||
hasNoDefaultLib: /[\\/]lib\.[^\\/]+\.d\.ts$/.test(fileName)
|
||||
});
|
||||
}
|
||||
sourceFiles.set(fileName, file);
|
||||
return file;
|
||||
}
|
||||
};
|
||||
/** @type {Duplex & { js?: Readable, dts?: Readable }} */
|
||||
const compileStream = new Duplex({
|
||||
objectMode: true,
|
||||
read() {},
|
||||
/** @param {*} file */
|
||||
write(file, _encoding, callback) {
|
||||
inputs.set(file.path, file);
|
||||
proc.send(protocol.message.write(file));
|
||||
callback();
|
||||
},
|
||||
final(callback) {
|
||||
proc.send(protocol.message.final());
|
||||
callback();
|
||||
}
|
||||
});
|
||||
const jsStream = compileStream.js = new Readable({
|
||||
objectMode: true,
|
||||
read() {}
|
||||
});
|
||||
const dtsStream = compileStream.dts = new Readable({
|
||||
objectMode: true,
|
||||
read() {}
|
||||
});
|
||||
proc.send(protocol.message.createProject(tsConfigFileName, settings, options));
|
||||
proc.on("message", (/**@type {protocol.WorkerMessage}*/ message) => {
|
||||
switch (message.method) {
|
||||
case "write": {
|
||||
const file = protocol.vinylFromJson(message.params);
|
||||
compileStream.push(file);
|
||||
if (file.path.endsWith(".d.ts")) {
|
||||
dtsStream.push(file);
|
||||
}
|
||||
else {
|
||||
jsStream.push(file);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "final": {
|
||||
compileStream.push(null);
|
||||
jsStream.push(null);
|
||||
dtsStream.push(null);
|
||||
proc.kill(); // TODO(rbuckton): pool workers? may not be feasible due to gulp-typescript holding onto memory
|
||||
break;
|
||||
}
|
||||
case "error": {
|
||||
const error = protocol.errorFromJson(message.params);
|
||||
compileStream.emit("error", error);
|
||||
proc.kill(); // TODO(rbuckton): pool workers? may not be feasible due to gulp-typescript holding onto memory
|
||||
break;
|
||||
}
|
||||
case "reporter.error": {
|
||||
if (reporter.error) {
|
||||
const error = protocol.typeScriptErrorFromJson(message.params, host);
|
||||
reporter.error(error, project.typescript);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "reporter.finish": {
|
||||
if (reporter.finish) {
|
||||
reporter.finish(message.params);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return /** @type {*} */(compileStream);
|
||||
});
|
||||
return Object.assign(wrappedProject, project);
|
||||
}
|
||||
|
||||
exports.createProject = createProject;
|
|
@ -1,281 +0,0 @@
|
|||
// @ts-check
|
||||
const Vinyl = require("vinyl");
|
||||
|
||||
/**
|
||||
* @param {File} file
|
||||
* @returns {*}
|
||||
*/
|
||||
function vinylToJson(file) {
|
||||
if (file.isStream()) throw new TypeError("Streams not supported.");
|
||||
return {
|
||||
path: file.path,
|
||||
cwd: file.cwd,
|
||||
base: file.base,
|
||||
contents: file.isBuffer() ? file.contents.toString("utf8") : undefined,
|
||||
sourceMap: file.sourceMap
|
||||
};
|
||||
}
|
||||
exports.vinylToJson = vinylToJson;
|
||||
|
||||
/**
|
||||
* @param {*} json
|
||||
* @returns {File}
|
||||
*/
|
||||
function vinylFromJson(json) {
|
||||
return new Vinyl({
|
||||
path: json.path,
|
||||
cwd: json.cwd,
|
||||
base: json.base,
|
||||
contents: typeof json.contents === "string" ? Buffer.from(json.contents, "utf8") : undefined,
|
||||
sourceMap: json.sourceMap
|
||||
});
|
||||
}
|
||||
exports.vinylFromJson = vinylFromJson;
|
||||
|
||||
/**
|
||||
* @param {Error} error
|
||||
* @returns {*}
|
||||
*/
|
||||
function errorToJson(error) {
|
||||
return {
|
||||
name: error.name,
|
||||
message: error.message,
|
||||
stack: error.stack
|
||||
};
|
||||
}
|
||||
exports.errorToJson = errorToJson;
|
||||
|
||||
/**
|
||||
* @param {*} json
|
||||
* @returns {Error}
|
||||
*/
|
||||
function errorFromJson(json) {
|
||||
const error = new Error();
|
||||
error.name = json.name;
|
||||
error.message = json.message;
|
||||
error.stack = json.stack;
|
||||
return error;
|
||||
}
|
||||
exports.errorFromJson = errorFromJson;
|
||||
|
||||
/**
|
||||
* @param {TypeScriptError} error
|
||||
* @returns {*}
|
||||
*/
|
||||
function typeScriptErrorToJson(error) {
|
||||
return Object.assign({}, errorToJson(error), {
|
||||
fullFilename: error.fullFilename,
|
||||
relativeFilename: error.relativeFilename,
|
||||
file: error.file && { path: error.file.path },
|
||||
tsFile: error.tsFile && sourceFileToJson(error.tsFile),
|
||||
diagnostic: diagnosticToJson(error.diagnostic),
|
||||
startPosition: error.startPosition,
|
||||
endPosition: error.endPosition
|
||||
});
|
||||
}
|
||||
exports.typeScriptErrorToJson = typeScriptErrorToJson;
|
||||
|
||||
/**
|
||||
* @param {*} json
|
||||
* @param {SourceFileHost & VinylHost} host
|
||||
* @returns {TypeScriptError}
|
||||
*/
|
||||
function typeScriptErrorFromJson(json, host) {
|
||||
const error = /**@type {TypeScriptError}*/(errorFromJson(json));
|
||||
error.fullFilename = json.fullFilename;
|
||||
error.relativeFilename = json.relativeFilename;
|
||||
error.file = json.file && host.getVinyl(json.file.path);
|
||||
error.tsFile = json.tsFile && sourceFileFromJson(json.tsFile, host);
|
||||
error.diagnostic = diagnosticFromJson(json.diagnostic, host);
|
||||
error.startPosition = json.startPosition;
|
||||
error.endPosition = json.endPosition;
|
||||
return error;
|
||||
}
|
||||
exports.typeScriptErrorFromJson = typeScriptErrorFromJson;
|
||||
|
||||
/**
|
||||
* @param {SourceFile} file
|
||||
* @returns {*}
|
||||
*/
|
||||
function sourceFileToJson(file) {
|
||||
return {
|
||||
fileName: file.fileName,
|
||||
text: file.text,
|
||||
languageVersion: file.languageVersion
|
||||
};
|
||||
}
|
||||
exports.sourceFileToJson = sourceFileToJson;
|
||||
|
||||
/**
|
||||
* @param {*} json
|
||||
* @param {SourceFileHost} host
|
||||
*/
|
||||
function sourceFileFromJson(json, host) {
|
||||
return host.getSourceFile(json.fileName)
|
||||
|| host.createSourceFile(json.fileName, json.text, json.languageVersion);
|
||||
}
|
||||
exports.sourceFileFromJson = sourceFileFromJson;
|
||||
|
||||
/**
|
||||
* @param {Diagnostic} diagnostic
|
||||
* @returns {*}
|
||||
*/
|
||||
function diagnosticToJson(diagnostic) {
|
||||
return Object.assign({}, diagnosticRelatedInformationToJson(diagnostic), {
|
||||
category: diagnostic.category,
|
||||
code: diagnostic.code,
|
||||
source: diagnostic.source,
|
||||
relatedInformation: diagnostic.relatedInformation && diagnostic.relatedInformation.map(diagnosticRelatedInformationToJson)
|
||||
});
|
||||
}
|
||||
exports.diagnosticToJson = diagnosticToJson;
|
||||
|
||||
/**
|
||||
* @param {*} json
|
||||
* @param {SourceFileHost} host
|
||||
* @returns {Diagnostic}
|
||||
*/
|
||||
function diagnosticFromJson(json, host) {
|
||||
return Object.assign({}, diagnosticRelatedInformationFromJson(json, host), {
|
||||
category: json.category,
|
||||
code: json.code,
|
||||
source: json.source,
|
||||
relatedInformation: json.relatedInformation && json.relatedInformation.map(json => diagnosticRelatedInformationFromJson(json, host))
|
||||
});
|
||||
}
|
||||
exports.diagnosticFromJson = diagnosticFromJson;
|
||||
|
||||
/**
|
||||
* @param {DiagnosticRelatedInformation} diagnostic
|
||||
* @returns {*}
|
||||
*/
|
||||
function diagnosticRelatedInformationToJson(diagnostic) {
|
||||
return {
|
||||
file: diagnostic.file && { fileName: diagnostic.file.fileName },
|
||||
start: diagnostic.start,
|
||||
length: diagnostic.length,
|
||||
messageText: diagnostic.messageText
|
||||
};
|
||||
}
|
||||
exports.diagnosticRelatedInformationToJson = diagnosticRelatedInformationToJson;
|
||||
|
||||
/**
|
||||
* @param {*} json
|
||||
* @param {SourceFileHost} host
|
||||
* @returns {DiagnosticRelatedInformation}
|
||||
*/
|
||||
function diagnosticRelatedInformationFromJson(json, host) {
|
||||
return {
|
||||
file: json.file && sourceFileFromJson(json.file, host),
|
||||
start: json.start,
|
||||
length: json.length,
|
||||
messageText: json.messageText,
|
||||
category: json.category,
|
||||
code: json.code
|
||||
};
|
||||
}
|
||||
exports.diagnosticRelatedInformationFromJson = diagnosticRelatedInformationFromJson;
|
||||
|
||||
exports.message = {};
|
||||
|
||||
/**
|
||||
* @param {string | undefined} tsConfigFileName
|
||||
* @param {import("gulp-typescript").Settings} settings
|
||||
* @param {Object} options
|
||||
* @param {string} [options.typescript]
|
||||
* @returns {CreateProjectMessage}
|
||||
*
|
||||
* @typedef CreateProjectMessage
|
||||
* @property {"createProject"} method
|
||||
* @property {CreateProjectParams} params
|
||||
*
|
||||
* @typedef CreateProjectParams
|
||||
* @property {string | undefined} tsConfigFileName
|
||||
* @property {import("gulp-typescript").Settings} settings
|
||||
* @property {CreateProjectOptions} options
|
||||
*
|
||||
* @typedef CreateProjectOptions
|
||||
* @property {string} [typescript]
|
||||
*/
|
||||
exports.message.createProject = function(tsConfigFileName, settings, options) {
|
||||
return { method: "createProject", params: { tsConfigFileName, settings, options } };
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {File} file
|
||||
* @returns {WriteMessage}
|
||||
*
|
||||
* @typedef WriteMessage
|
||||
* @property {"write"} method
|
||||
* @property {*} params
|
||||
*/
|
||||
exports.message.write = function(file) {
|
||||
return { method: "write", params: vinylToJson(file) };
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {FinalMessage}
|
||||
*
|
||||
* @typedef FinalMessage
|
||||
* @property {"final"} method
|
||||
*/
|
||||
exports.message.final = function() {
|
||||
return { method: "final" };
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Error} error
|
||||
* @returns {ErrorMessage}
|
||||
*
|
||||
* @typedef ErrorMessage
|
||||
* @property {"error"} method
|
||||
* @property {*} params
|
||||
*/
|
||||
exports.message.error = function(error) {
|
||||
return { method: "error", params: errorToJson(error) };
|
||||
};
|
||||
|
||||
exports.message.reporter = {};
|
||||
|
||||
/**
|
||||
* @param {TypeScriptError} error
|
||||
* @returns {reporter.ErrorMessage}
|
||||
*
|
||||
* @typedef reporter.ErrorMessage
|
||||
* @property {"reporter.error"} method
|
||||
* @property {*} params
|
||||
*/
|
||||
exports.message.reporter.error = function(error) {
|
||||
return { method: "reporter.error", params: typeScriptErrorToJson(error) };
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {*} results
|
||||
* @returns {reporter.FinishMessage}
|
||||
*
|
||||
* @typedef reporter.FinishMessage
|
||||
* @property {"reporter.finish"} method
|
||||
* @property {*} params
|
||||
*/
|
||||
exports.message.reporter.finish = function(results) {
|
||||
return { method: "reporter.finish", params: results };
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef {import("vinyl")} File
|
||||
* @typedef {typeof import("typescript")} TypeScriptModule
|
||||
* @typedef {import("typescript").SourceFile} SourceFile
|
||||
* @typedef {import("typescript").Diagnostic} Diagnostic
|
||||
* @typedef {import("typescript").DiagnosticRelatedInformation} DiagnosticRelatedInformation
|
||||
* @typedef {import("gulp-typescript").reporter.TypeScriptError} TypeScriptError
|
||||
* @typedef {WriteMessage | FinalMessage | CreateProjectMessage} HostMessage
|
||||
* @typedef {WriteMessage | FinalMessage | ErrorMessage | reporter.ErrorMessage | reporter.FinishMessage} WorkerMessage
|
||||
*
|
||||
* @typedef SourceFileHost
|
||||
* @property {(fileName: string) => SourceFile | undefined} getSourceFile
|
||||
* @property {(fileName: string, text: string, languageVersion: number) => SourceFile} createSourceFile
|
||||
*
|
||||
* @typedef VinylHost
|
||||
* @property {(path: string) => File | undefined} getVinyl
|
||||
*/
|
||||
void 0;
|
|
@ -1,79 +0,0 @@
|
|||
// @ts-check
|
||||
const fs = require("fs");
|
||||
const tsc = require("gulp-typescript");
|
||||
const { Readable, Writable } = require("stream");
|
||||
const protocol = require("./protocol");
|
||||
|
||||
/** @type {tsc.Project} */
|
||||
let project;
|
||||
|
||||
/** @type {Readable} */
|
||||
let inputStream;
|
||||
|
||||
/** @type {Writable} */
|
||||
let outputStream;
|
||||
|
||||
/** @type {tsc.CompileStream} */
|
||||
let compileStream;
|
||||
|
||||
process.on("message", (/**@type {protocol.HostMessage}*/ message) => {
|
||||
try {
|
||||
switch (message.method) {
|
||||
case "createProject": {
|
||||
const { tsConfigFileName, settings, options } = message.params;
|
||||
if (options.typescript) {
|
||||
settings.typescript = require(options.typescript);
|
||||
}
|
||||
|
||||
project = tsConfigFileName === undefined
|
||||
? tsc.createProject(settings)
|
||||
: tsc.createProject(tsConfigFileName, settings);
|
||||
|
||||
inputStream = new Readable({
|
||||
objectMode: true,
|
||||
read() {}
|
||||
});
|
||||
|
||||
outputStream = new Writable({
|
||||
objectMode: true,
|
||||
/**
|
||||
* @param {*} file
|
||||
*/
|
||||
write(file, _, callback) {
|
||||
process.send(protocol.message.write(file));
|
||||
callback();
|
||||
},
|
||||
final(callback) {
|
||||
process.send(protocol.message.final());
|
||||
callback();
|
||||
}
|
||||
});
|
||||
compileStream = project({
|
||||
error(error) { process.send(protocol.message.reporter.error(error)); },
|
||||
finish(results) { process.send(protocol.message.reporter.finish(results)); }
|
||||
});
|
||||
compileStream.on("error", error => {
|
||||
process.send(protocol.message.error(error));
|
||||
});
|
||||
outputStream.on("error", () => {
|
||||
/* do nothing */
|
||||
});
|
||||
inputStream.pipe(compileStream).pipe(outputStream);
|
||||
break;
|
||||
}
|
||||
case "write": {
|
||||
const file = protocol.vinylFromJson(message.params);
|
||||
if (!file.isBuffer()) file.contents = fs.readFileSync(file.path);
|
||||
inputStream.push(file);
|
||||
break;
|
||||
}
|
||||
case "final": {
|
||||
inputStream.push(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
process.send(protocol.message.error(e));
|
||||
}
|
||||
});
|
|
@ -1,8 +0,0 @@
|
|||
// @ts-check
|
||||
/**
|
||||
* @typedef {import("gulp").Gulp} Gulp
|
||||
* @typedef {import("gulp-help").GulpHelp} GulpHelp
|
||||
* @typedef {GulpHelp & { Gulp: new () => Gulp }} DotGulpModule
|
||||
* @type {DotGulpModule}
|
||||
*/
|
||||
module.exports = require("gulp-help")(require("gulp"));
|
|
@ -1,30 +0,0 @@
|
|||
// @ts-check
|
||||
const readJson = require("./readJson");
|
||||
const path = require("path");
|
||||
const gulp = require("./gulp");
|
||||
const newer = require("gulp-newer");
|
||||
const concat = require("gulp-concat");
|
||||
const merge2 = require("merge2");
|
||||
|
||||
/** @type {{ libs: string[], paths?: Record<string, string>, sources?: Record<string, string[]> }} */
|
||||
const libraries = readJson("./src/lib/libs.json");
|
||||
const libs = libraries.libs.map(lib => {
|
||||
const relativeSources = ["header.d.ts"].concat(libraries.sources && libraries.sources[lib] || [lib + ".d.ts"]);
|
||||
const relativeTarget = libraries.paths && libraries.paths[lib] || ("lib." + lib + ".d.ts");
|
||||
const sources = relativeSources.map(s => path.posix.join("src/lib", s));
|
||||
const target = `built/local/${relativeTarget}`;
|
||||
return { target, relativeTarget, sources };
|
||||
});
|
||||
exports.libraryTargets = libs.map(lib => lib.target);
|
||||
|
||||
/**
|
||||
* @param {string[]} prepends
|
||||
*/
|
||||
function generateLibs(prepends) {
|
||||
return merge2(libs.map(({ sources, target, relativeTarget }) =>
|
||||
gulp.src(prepends.concat(sources))
|
||||
.pipe(newer(target))
|
||||
.pipe(concat(relativeTarget, { newLine: "\n\n" }))
|
||||
.pipe(gulp.dest("built/local"))));
|
||||
}
|
||||
exports.generateLibs = generateLibs;
|
|
@ -1,14 +0,0 @@
|
|||
// @ts-check
|
||||
const mkdirp = require("mkdirp");
|
||||
|
||||
module.exports = exports = mkdirpAsync;
|
||||
|
||||
/**
|
||||
* @param {string} dir
|
||||
* @param {mkdirp.Mode | mkdirp.Options} [opts]
|
||||
*/
|
||||
function mkdirpAsync(dir, opts) {
|
||||
return new Promise((resolve, reject) => mkdirp(dir, opts, (err, made) => err ? reject(err) : resolve(made)));
|
||||
}
|
||||
|
||||
exports.sync = mkdirp.sync;
|
|
@ -1,72 +0,0 @@
|
|||
// @ts-check
|
||||
const fs = require("fs");
|
||||
|
||||
module.exports = needsUpdate;
|
||||
|
||||
/**
|
||||
* @param {string | string[]} source
|
||||
* @param {string | string[]} dest
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function needsUpdate(source, dest) {
|
||||
if (typeof source === "string" && typeof dest === "string") {
|
||||
if (fs.existsSync(dest)) {
|
||||
const {mtime: outTime} = fs.statSync(dest);
|
||||
const {mtime: inTime} = fs.statSync(source);
|
||||
if (+inTime <= +outTime) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (typeof source === "string" && typeof dest !== "string") {
|
||||
const {mtime: inTime} = fs.statSync(source);
|
||||
for (const filepath of dest) {
|
||||
if (fs.existsSync(filepath)) {
|
||||
const {mtime: outTime} = fs.statSync(filepath);
|
||||
if (+inTime > +outTime) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (typeof source !== "string" && typeof dest === "string") {
|
||||
if (fs.existsSync(dest)) {
|
||||
const {mtime: outTime} = fs.statSync(dest);
|
||||
for (const filepath of source) {
|
||||
if (fs.existsSync(filepath)) {
|
||||
const {mtime: inTime} = fs.statSync(filepath);
|
||||
if (+inTime > +outTime) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (typeof source !== "string" && typeof dest !== "string") {
|
||||
for (let i = 0; i < source.length; i++) {
|
||||
if (!dest[i]) {
|
||||
continue;
|
||||
}
|
||||
if (fs.existsSync(dest[i])) {
|
||||
const {mtime: outTime} = fs.statSync(dest[i]);
|
||||
const {mtime: inTime} = fs.statSync(source[i]);
|
||||
if (+inTime > +outTime) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
|
@ -4,7 +4,7 @@ const os = require("os");
|
|||
|
||||
/** @type {CommandLineOptions} */
|
||||
module.exports = minimist(process.argv.slice(2), {
|
||||
boolean: ["debug", "dirty", "inspect", "light", "colors", "lint", "lkg", "soft", "fix", "failed", "keepFailed"],
|
||||
boolean: ["debug", "dirty", "inspect", "light", "colors", "lint", "lkg", "soft", "fix", "failed", "keepFailed", "force", "built"],
|
||||
string: ["browser", "tests", "host", "reporter", "stackTraceLimit", "timeout"],
|
||||
alias: {
|
||||
"b": "browser",
|
||||
|
@ -15,7 +15,7 @@ module.exports = minimist(process.argv.slice(2), {
|
|||
"r": "reporter",
|
||||
"c": "colors", "color": "colors",
|
||||
"w": "workers",
|
||||
"f": "fix",
|
||||
"f": "fix"
|
||||
},
|
||||
default: {
|
||||
soft: false,
|
||||
|
@ -35,10 +35,15 @@ module.exports = minimist(process.argv.slice(2), {
|
|||
failed: false,
|
||||
keepFailed: false,
|
||||
lkg: true,
|
||||
dirty: false
|
||||
dirty: false,
|
||||
built: false
|
||||
}
|
||||
});
|
||||
|
||||
if (module.exports.built) {
|
||||
module.exports.lkg = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef TypedOptions
|
||||
* @property {boolean} debug
|
||||
|
@ -48,6 +53,7 @@ module.exports = minimist(process.argv.slice(2), {
|
|||
* @property {boolean} colors
|
||||
* @property {boolean} lint
|
||||
* @property {boolean} lkg
|
||||
* @property {boolean} built
|
||||
* @property {boolean} soft
|
||||
* @property {boolean} fix
|
||||
* @property {string} browser
|
||||
|
|
|
@ -1,20 +1,18 @@
|
|||
// @ts-check
|
||||
const stream = require("stream");
|
||||
const Vinyl = require("./vinyl");
|
||||
const Vinyl = require("vinyl");
|
||||
const ts = require("../../lib/typescript");
|
||||
const fs = require("fs");
|
||||
const { base64VLQFormatEncode } = require("./sourcemaps");
|
||||
|
||||
module.exports = exports = prepend;
|
||||
|
||||
/**
|
||||
* @param {string | ((file: Vinyl) => string)} data
|
||||
* @param {string | ((file: import("vinyl")) => string)} data
|
||||
*/
|
||||
function prepend(data) {
|
||||
return new stream.Transform({
|
||||
objectMode: true,
|
||||
/**
|
||||
* @param {string | Buffer | Vinyl} input
|
||||
* @param {string | Buffer | import("vinyl")} input
|
||||
* @param {(error: Error, data?: any) => void} cb
|
||||
*/
|
||||
transform(input, _, cb) {
|
||||
|
@ -56,11 +54,11 @@ function prepend(data) {
|
|||
exports.prepend = prepend;
|
||||
|
||||
/**
|
||||
* @param {string | ((file: Vinyl) => string)} file
|
||||
* @param {string | ((file: import("vinyl")) => string)} file
|
||||
*/
|
||||
function prependFile(file) {
|
||||
const data = typeof file === "string" ? fs.readFileSync(file, "utf8") :
|
||||
vinyl => fs.readFileSync(file(vinyl), "utf8");
|
||||
return prepend(data)
|
||||
}
|
||||
exports.file = prependFile;
|
||||
exports.prependFile = prependFile;
|
File diff suppressed because it is too large
Load diff
60
scripts/build/projects.js
Normal file
60
scripts/build/projects.js
Normal file
|
@ -0,0 +1,60 @@
|
|||
// @ts-check
|
||||
const { exec, Debouncer } = require("./utils");
|
||||
|
||||
class ProjectQueue {
|
||||
/**
|
||||
* @param {(projects: string[], lkg: boolean, force: boolean) => Promise<any>} action
|
||||
*/
|
||||
constructor(action) {
|
||||
/** @type {{ lkg: boolean, force: boolean, projects?: string[], debouncer: Debouncer }[]} */
|
||||
this._debouncers = [];
|
||||
this._action = action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} project
|
||||
* @param {object} options
|
||||
*/
|
||||
enqueue(project, { lkg = true, force = false } = {}) {
|
||||
let entry = this._debouncers.find(entry => entry.lkg === lkg && entry.force === force);
|
||||
if (!entry) {
|
||||
const debouncer = new Debouncer(100, async () => {
|
||||
const projects = entry.projects;
|
||||
if (projects) {
|
||||
entry.projects = undefined;
|
||||
await this._action(projects, lkg, force);
|
||||
}
|
||||
});
|
||||
this._debouncers.push(entry = { lkg, force, debouncer });
|
||||
}
|
||||
if (!entry.projects) entry.projects = [];
|
||||
entry.projects.push(project);
|
||||
return entry.debouncer.enqueue();
|
||||
}
|
||||
}
|
||||
|
||||
const projectBuilder = new ProjectQueue((projects, lkg, force) => exec(process.execPath, [lkg ? "./lib/tsc" : "./built/local/tsc", "-b", ...(force ? ["--force"] : []), ...projects], { hidePrompt: true }));
|
||||
|
||||
/**
|
||||
* @param {string} project
|
||||
* @param {object} [options]
|
||||
* @param {boolean} [options.lkg=true]
|
||||
* @param {boolean} [options.force=false]
|
||||
*/
|
||||
exports.buildProject = (project, { lkg, force } = {}) => projectBuilder.enqueue(project, { lkg, force });
|
||||
|
||||
const projectCleaner = new ProjectQueue((projects, lkg) => exec(process.execPath, [lkg ? "./lib/tsc" : "./built/local/tsc", "-b", "--clean", ...projects], { hidePrompt: true }));
|
||||
|
||||
/**
|
||||
* @param {string} project
|
||||
*/
|
||||
exports.cleanProject = (project) => projectCleaner.enqueue(project);
|
||||
|
||||
const projectWatcher = new ProjectQueue((projects) => exec(process.execPath, ["./lib/tsc", "-b", "--watch", ...projects], { hidePrompt: true }));
|
||||
|
||||
/**
|
||||
* @param {string} project
|
||||
* @param {object} [options]
|
||||
* @param {boolean} [options.lkg=true]
|
||||
*/
|
||||
exports.watchProject = (project, { lkg } = {}) => projectWatcher.enqueue(project, { lkg });
|
|
@ -1,17 +0,0 @@
|
|||
// @ts-check
|
||||
const ts = require("../../lib/typescript");
|
||||
const fs = require("fs");
|
||||
const { reportDiagnostics } = require("./diagnostics");
|
||||
|
||||
module.exports = exports = readJson;
|
||||
|
||||
/** @param {string} jsonPath */
|
||||
function readJson(jsonPath) {
|
||||
const jsonText = fs.readFileSync(jsonPath, "utf8");
|
||||
const result = ts.parseConfigFileTextToJson(jsonPath, jsonText);
|
||||
if (result.error) {
|
||||
reportDiagnostics([result.error]);
|
||||
throw new Error("An error occurred during parse.");
|
||||
}
|
||||
return result.config;
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// @ts-check
|
||||
const insert = require("gulp-insert");
|
||||
|
||||
/**
|
||||
* @param {string | RegExp} searchValue
|
||||
* @param {string | ((...args: string[]) => string)} replacer
|
||||
*/
|
||||
function replace(searchValue, replacer) {
|
||||
return insert.transform(content => content.replace(searchValue, /**@type {string}*/(replacer)));
|
||||
}
|
||||
|
||||
module.exports = replace;
|
|
@ -1,84 +0,0 @@
|
|||
// @ts-check
|
||||
const { Duplex } = require("stream");
|
||||
const path = require("path");
|
||||
const Vinyl = require("vinyl");
|
||||
const del = require("del");
|
||||
|
||||
module.exports = rm;
|
||||
|
||||
/**
|
||||
* @param {string | ((file: File) => string) | Options} [dest]
|
||||
* @param {Options} [opts]
|
||||
*/
|
||||
function rm(dest, opts) {
|
||||
if (dest && typeof dest === "object") opts = dest, dest = undefined;
|
||||
let failed = false;
|
||||
|
||||
const cwd = path.resolve(opts && opts.cwd || process.cwd());
|
||||
|
||||
/** @type {{ file: File, deleted: boolean, promise: Promise<any>, cb: Function }[]} */
|
||||
const pending = [];
|
||||
|
||||
const processDeleted = () => {
|
||||
if (failed) return;
|
||||
while (pending.length && pending[0].deleted) {
|
||||
const { file, cb } = pending.shift();
|
||||
duplex.push(file);
|
||||
cb();
|
||||
}
|
||||
};
|
||||
|
||||
const duplex = new Duplex({
|
||||
objectMode: true,
|
||||
/**
|
||||
* @param {string|Buffer|File} file
|
||||
*/
|
||||
write(file, _, cb) {
|
||||
if (failed) return;
|
||||
if (typeof file === "string" || Buffer.isBuffer(file)) return cb(new Error("Only Vinyl files are supported."));
|
||||
const basePath = typeof dest === "string" ? path.resolve(cwd, dest) :
|
||||
typeof dest === "function" ? path.resolve(cwd, dest(file)) :
|
||||
file.base;
|
||||
const filePath = path.resolve(basePath, file.relative);
|
||||
file.cwd = cwd;
|
||||
file.base = basePath;
|
||||
file.path = filePath;
|
||||
const entry = {
|
||||
file,
|
||||
deleted: false,
|
||||
cb,
|
||||
promise: del(file.path).then(() => {
|
||||
entry.deleted = true;
|
||||
processDeleted();
|
||||
}, err => {
|
||||
failed = true;
|
||||
pending.length = 0;
|
||||
cb(err);
|
||||
})
|
||||
};
|
||||
pending.push(entry);
|
||||
},
|
||||
final(cb) {
|
||||
processDeleted();
|
||||
if (pending.length) {
|
||||
Promise
|
||||
.all(pending.map(entry => entry.promise))
|
||||
.then(() => processDeleted())
|
||||
.then(() => cb(), cb);
|
||||
return;
|
||||
}
|
||||
cb();
|
||||
},
|
||||
read() {
|
||||
}
|
||||
});
|
||||
return duplex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {import("vinyl")} File
|
||||
*
|
||||
* @typedef Options
|
||||
* @property {string} [cwd]
|
||||
*/
|
||||
void 0;
|
|
@ -1,12 +1,13 @@
|
|||
// @ts-check
|
||||
/// <reference path="../types/ambient.d.ts" />
|
||||
|
||||
const path = require("path");
|
||||
const Vinyl = require("./vinyl");
|
||||
const convertMap = require("convert-source-map");
|
||||
const applySourceMap = require("vinyl-sourcemaps-apply");
|
||||
const through2 = require("through2");
|
||||
|
||||
/**
|
||||
* @param {Vinyl} input
|
||||
* @param {import("vinyl")} input
|
||||
* @param {string | Buffer} contents
|
||||
* @param {string | RawSourceMap} [sourceMap]
|
||||
*/
|
||||
|
@ -16,13 +17,13 @@ function replaceContents(input, contents, sourceMap) {
|
|||
if (input.sourceMap) {
|
||||
output.sourceMap = typeof input.sourceMap === "string" ? /**@type {RawSourceMap}*/(JSON.parse(input.sourceMap)) : input.sourceMap;
|
||||
if (typeof sourceMap === "string") {
|
||||
sourceMap = /**@type {RawSourceMap}*/(JSON.parse(sourceMap));
|
||||
sourceMap = /** @type {RawSourceMap} */(JSON.parse(sourceMap));
|
||||
}
|
||||
else if (sourceMap === undefined) {
|
||||
const stringContents = typeof contents === "string" ? contents : contents.toString("utf8");
|
||||
const newSourceMapConverter = convertMap.fromSource(stringContents);
|
||||
if (newSourceMapConverter) {
|
||||
sourceMap = /**@type {RawSourceMap}*/(newSourceMapConverter.toObject());
|
||||
sourceMap = /** @type {RawSourceMap} */(newSourceMapConverter.toObject());
|
||||
output.contents = new Buffer(convertMap.removeMapFileComments(stringContents), "utf8");
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +32,7 @@ function replaceContents(input, contents, sourceMap) {
|
|||
const base = input.base || cwd;
|
||||
const sourceRoot = output.sourceMap.sourceRoot;
|
||||
makeAbsoluteSourceMap(cwd, base, output.sourceMap);
|
||||
makeAbsoluteSourceMap(cwd, base, sourceMap);
|
||||
makeAbsoluteSourceMap(cwd, base, /** @type {RawSourceMap} */(sourceMap));
|
||||
applySourceMap(output, sourceMap);
|
||||
makeRelativeSourceMap(cwd, base, sourceRoot, output.sourceMap);
|
||||
}
|
||||
|
@ -44,10 +45,12 @@ function replaceContents(input, contents, sourceMap) {
|
|||
exports.replaceContents = replaceContents;
|
||||
|
||||
function removeSourceMaps() {
|
||||
return through2.obj((/**@type {Vinyl}*/file, _, cb) => {
|
||||
if (file.sourceMap && file.isBuffer()) {
|
||||
return through2.obj((/**@type {import("vinyl")}*/file, _, cb) => {
|
||||
if (file.isBuffer()) {
|
||||
file.contents = Buffer.from(convertMap.removeMapFileComments(file.contents.toString("utf8")), "utf8");
|
||||
file.sourceMap = undefined;
|
||||
if (file.sourceMap) {
|
||||
file.sourceMap = undefined;
|
||||
}
|
||||
}
|
||||
cb(null, file);
|
||||
});
|
||||
|
@ -59,7 +62,7 @@ exports.removeSourceMaps = removeSourceMaps;
|
|||
* @param {string | undefined} base
|
||||
* @param {RawSourceMap} sourceMap
|
||||
*
|
||||
* @typedef RawSourceMap
|
||||
* @typedef {object} RawSourceMap
|
||||
* @property {string} version
|
||||
* @property {string} file
|
||||
* @property {string} [sourceRoot]
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
// @ts-check
|
||||
const gulp = require("./gulp");
|
||||
const gulp = require("gulp");
|
||||
const del = require("del");
|
||||
const fs = require("fs");
|
||||
const os = require("os");
|
||||
const path = require("path");
|
||||
const mkdirP = require("./mkdirp");
|
||||
const mkdirP = require("mkdirp");
|
||||
const log = require("fancy-log");
|
||||
const cmdLineOptions = require("./options");
|
||||
const exec = require("./exec");
|
||||
const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util)
|
||||
const { CancellationToken } = require("prex");
|
||||
const mochaJs = require.resolve("mocha/bin/_mocha");
|
||||
const { exec } = require("./utils");
|
||||
|
||||
const mochaJs = require.resolve("mocha/bin/_mocha");
|
||||
exports.localBaseline = "tests/baselines/local/";
|
||||
exports.refBaseline = "tests/baselines/reference/";
|
||||
exports.localRwcBaseline = "internal/baselines/rwc/local";
|
||||
|
@ -27,7 +27,6 @@ exports.localTest262Baseline = "internal/baselines/test262/local";
|
|||
async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode, cancelToken = CancellationToken.none) {
|
||||
let testTimeout = cmdLineOptions.timeout;
|
||||
let tests = cmdLineOptions.tests;
|
||||
const lintFlag = cmdLineOptions.lint;
|
||||
const debug = cmdLineOptions.debug;
|
||||
const inspect = cmdLineOptions.inspect;
|
||||
const runners = cmdLineOptions.runners;
|
||||
|
@ -117,9 +116,6 @@ async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode,
|
|||
errorStatus = exitCode;
|
||||
error = new Error(`Process exited with status code ${errorStatus}.`);
|
||||
}
|
||||
else if (lintFlag) {
|
||||
await new Promise((resolve, reject) => gulp.start(["lint"], error => error ? reject(error) : resolve()));
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
errorStatus = undefined;
|
||||
|
@ -144,10 +140,10 @@ async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode,
|
|||
}
|
||||
exports.runConsoleTests = runConsoleTests;
|
||||
|
||||
function cleanTestDirs() {
|
||||
return del([exports.localBaseline, exports.localRwcBaseline])
|
||||
.then(() => mkdirP(exports.localRwcBaseline))
|
||||
.then(() => mkdirP(exports.localBaseline));
|
||||
async function cleanTestDirs() {
|
||||
await del([exports.localBaseline, exports.localRwcBaseline])
|
||||
mkdirP.sync(exports.localRwcBaseline);
|
||||
mkdirP.sync(exports.localBaseline);
|
||||
}
|
||||
exports.cleanTestDirs = cleanTestDirs;
|
||||
|
||||
|
|
|
@ -1,435 +0,0 @@
|
|||
// @ts-check
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util)
|
||||
const ts = require("../../lib/typescript");
|
||||
const { Duplex } = require("stream");
|
||||
const chalk = /**@type {*} */(require("chalk"));
|
||||
const Vinyl = require("vinyl");
|
||||
|
||||
/**
|
||||
* Creates a stream that passes through its inputs only if the project outputs are not up to date
|
||||
* with respect to the inputs.
|
||||
* @param {ParsedCommandLine} parsedProject
|
||||
* @param {UpToDateOptions} [options]
|
||||
*
|
||||
* @typedef UpToDateOptions
|
||||
* @property {boolean | "minimal"} [verbose]
|
||||
* @property {(configFilePath: string) => ParsedCommandLine | undefined} [parseProject]
|
||||
*/
|
||||
function upToDate(parsedProject, options) {
|
||||
/** @type {File[]} */
|
||||
const inputs = [];
|
||||
/** @type {Map<string, File>} */
|
||||
const inputMap = new Map();
|
||||
/** @type {Map<string, fs.Stats>} */
|
||||
const statCache = new Map();
|
||||
/** @type {UpToDateHost} */
|
||||
const upToDateHost = {
|
||||
fileExists(fileName) {
|
||||
const stats = getStat(fileName);
|
||||
return stats ? stats.isFile() : false;
|
||||
},
|
||||
getModifiedTime(fileName) {
|
||||
return getStat(fileName).mtime;
|
||||
},
|
||||
parseConfigFile: options && options.parseProject
|
||||
};
|
||||
const duplex = new Duplex({
|
||||
objectMode: true,
|
||||
/**
|
||||
* @param {string|Buffer|File} file
|
||||
*/
|
||||
write(file, _, cb) {
|
||||
if (typeof file === "string" || Buffer.isBuffer(file)) return cb(new Error("Only Vinyl files are supported."));
|
||||
inputs.push(file);
|
||||
inputMap.set(path.resolve(file.path), file);
|
||||
cb();
|
||||
},
|
||||
final(cb) {
|
||||
const status = getUpToDateStatus(upToDateHost, parsedProject);
|
||||
reportStatus(parsedProject, status, options);
|
||||
if (status.type !== UpToDateStatusType.UpToDate) {
|
||||
for (const input of inputs) duplex.push(input);
|
||||
}
|
||||
duplex.push(null);
|
||||
inputMap.clear();
|
||||
statCache.clear();
|
||||
cb();
|
||||
},
|
||||
read() {
|
||||
}
|
||||
});
|
||||
return duplex;
|
||||
|
||||
function getStat(fileName) {
|
||||
fileName = path.resolve(fileName);
|
||||
const inputFile = inputMap.get(fileName);
|
||||
if (inputFile && inputFile.stat) return inputFile.stat;
|
||||
|
||||
let stats = statCache.get(fileName);
|
||||
if (!stats && fs.existsSync(fileName)) {
|
||||
stats = fs.statSync(fileName);
|
||||
statCache.set(fileName, stats);
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
}
|
||||
module.exports = exports = upToDate;
|
||||
|
||||
/**
|
||||
* @param {DiagnosticMessage} message
|
||||
* @param {...string} args
|
||||
*/
|
||||
function formatMessage(message, ...args) {
|
||||
log.info(formatStringFromArgs(message.message, args));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ParsedCommandLine} project
|
||||
* @param {UpToDateStatus} status
|
||||
* @param {{verbose?: boolean | "minimal"}} options
|
||||
*/
|
||||
function reportStatus(project, status, options) {
|
||||
switch (options.verbose) {
|
||||
case "minimal":
|
||||
switch (status.type) {
|
||||
case UpToDateStatusType.UpToDate:
|
||||
log.info(`Project '${fileName(project.options.configFilePath)}' is up to date.`);
|
||||
break;
|
||||
default:
|
||||
log.info(`Project '${fileName(project.options.configFilePath)}' is out of date, rebuilding...`);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case true:
|
||||
/**@type {*}*/(ts).formatUpToDateStatus(project.options.configFilePath, status, fileName, formatMessage);
|
||||
break;
|
||||
}
|
||||
if (!options.verbose) return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} file
|
||||
* @private
|
||||
*/
|
||||
function normalizeSlashes(file) {
|
||||
return file.replace(/\\/g, "/");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} file
|
||||
* @private
|
||||
*/
|
||||
function fileName(file) {
|
||||
return chalk.cyan(normalizeSlashes(path.relative(process.cwd(), path.resolve(file))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @param {string[]} args
|
||||
* @param {number} [baseIndex]
|
||||
*/
|
||||
function formatStringFromArgs(text, args, baseIndex = 0) {
|
||||
return text.replace(/{(\d+)}/g, (_match, index) => args[+index + baseIndex]);
|
||||
}
|
||||
|
||||
const minimumDate = new Date(-8640000000000000);
|
||||
const maximumDate = new Date(8640000000000000);
|
||||
const missingFileModifiedTime = new Date(0);
|
||||
|
||||
/**
|
||||
* @typedef {0} UpToDateStatusType.Unbuildable
|
||||
* @typedef {1} UpToDateStatusType.UpToDate
|
||||
* @typedef {2} UpToDateStatusType.UpToDateWithUpstreamTypes
|
||||
* @typedef {3} UpToDateStatusType.OutputMissing
|
||||
* @typedef {4} UpToDateStatusType.OutOfDateWithSelf
|
||||
* @typedef {5} UpToDateStatusType.OutOfDateWithUpstream
|
||||
* @typedef {6} UpToDateStatusType.UpstreamOutOfDate
|
||||
* @typedef {7} UpToDateStatusType.UpstreamBlocked
|
||||
* @typedef {8} UpToDateStatusType.ComputingUpstream
|
||||
* @typedef {9} UpToDateStatusType.ContainerOnly
|
||||
* @enum {UpToDateStatusType.Unbuildable | UpToDateStatusType.UpToDate | UpToDateStatusType.UpToDateWithUpstreamTypes | UpToDateStatusType.OutputMissing | UpToDateStatusType.OutOfDateWithSelf | UpToDateStatusType.OutOfDateWithUpstream | UpToDateStatusType.UpstreamOutOfDate | UpToDateStatusType.UpstreamBlocked | UpToDateStatusType.ComputingUpstream | UpToDateStatusType.ContainerOnly}
|
||||
*/
|
||||
const UpToDateStatusType = {
|
||||
Unbuildable: /** @type {0} */(0),
|
||||
UpToDate: /** @type {1} */(1),
|
||||
UpToDateWithUpstreamTypes: /** @type {2} */(2),
|
||||
OutputMissing: /** @type {3} */(3),
|
||||
OutOfDateWithSelf: /** @type {4} */(4),
|
||||
OutOfDateWithUpstream: /** @type {5} */(5),
|
||||
UpstreamOutOfDate: /** @type {6} */(6),
|
||||
UpstreamBlocked: /** @type {7} */(7),
|
||||
ComputingUpstream: /** @type {8} */(8),
|
||||
ContainerOnly: /** @type {9} */(9),
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Date} date1
|
||||
* @param {Date} date2
|
||||
* @returns {Date}
|
||||
*/
|
||||
function newer(date1, date2) {
|
||||
return date2 > date1 ? date2 : date1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {UpToDateHost} host
|
||||
* @param {ParsedCommandLine | undefined} project
|
||||
* @returns {UpToDateStatus}
|
||||
*/
|
||||
function getUpToDateStatus(host, project) {
|
||||
if (project === undefined) return { type: UpToDateStatusType.Unbuildable, reason: "File deleted mid-build" };
|
||||
const prior = host.getLastStatus ? host.getLastStatus(project.options.configFilePath) : undefined;
|
||||
if (prior !== undefined) {
|
||||
return prior;
|
||||
}
|
||||
const actual = getUpToDateStatusWorker(host, project);
|
||||
if (host.setLastStatus) {
|
||||
host.setLastStatus(project.options.configFilePath, actual);
|
||||
}
|
||||
return actual;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {UpToDateHost} host
|
||||
* @param {ParsedCommandLine | undefined} project
|
||||
* @returns {UpToDateStatus}
|
||||
*/
|
||||
function getUpToDateStatusWorker(host, project) {
|
||||
/** @type {string} */
|
||||
let newestInputFileName = undefined;
|
||||
let newestInputFileTime = minimumDate;
|
||||
// Get timestamps of input files
|
||||
for (const inputFile of project.fileNames) {
|
||||
if (!host.fileExists(inputFile)) {
|
||||
return {
|
||||
type: UpToDateStatusType.Unbuildable,
|
||||
reason: `${inputFile} does not exist`
|
||||
};
|
||||
}
|
||||
|
||||
const inputTime = host.getModifiedTime(inputFile) || missingFileModifiedTime;
|
||||
if (inputTime > newestInputFileTime) {
|
||||
newestInputFileName = inputFile;
|
||||
newestInputFileTime = inputTime;
|
||||
}
|
||||
}
|
||||
|
||||
// Collect the expected outputs of this project
|
||||
const outputs = /**@type {string[]}*/(/**@type {*}*/(ts).getAllProjectOutputs(project));
|
||||
|
||||
if (outputs.length === 0) {
|
||||
return {
|
||||
type: UpToDateStatusType.ContainerOnly
|
||||
};
|
||||
}
|
||||
|
||||
// Now see if all outputs are newer than the newest input
|
||||
let oldestOutputFileName = "(none)";
|
||||
let oldestOutputFileTime = maximumDate;
|
||||
let newestOutputFileName = "(none)";
|
||||
let newestOutputFileTime = minimumDate;
|
||||
/** @type {string | undefined} */
|
||||
let missingOutputFileName;
|
||||
let newestDeclarationFileContentChangedTime = minimumDate;
|
||||
let isOutOfDateWithInputs = false;
|
||||
for (const output of outputs) {
|
||||
// Output is missing; can stop checking
|
||||
// Don't immediately return because we can still be upstream-blocked, which is a higher-priority status
|
||||
if (!host.fileExists(output)) {
|
||||
missingOutputFileName = output;
|
||||
break;
|
||||
}
|
||||
|
||||
const outputTime = host.getModifiedTime(output) || missingFileModifiedTime;
|
||||
if (outputTime < oldestOutputFileTime) {
|
||||
oldestOutputFileTime = outputTime;
|
||||
oldestOutputFileName = output;
|
||||
}
|
||||
|
||||
// If an output is older than the newest input, we can stop checking
|
||||
// Don't immediately return because we can still be upstream-blocked, which is a higher-priority status
|
||||
if (outputTime < newestInputFileTime) {
|
||||
isOutOfDateWithInputs = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (outputTime > newestOutputFileTime) {
|
||||
newestOutputFileTime = outputTime;
|
||||
newestOutputFileName = output;
|
||||
}
|
||||
|
||||
// Keep track of when the most recent time a .d.ts file was changed.
|
||||
// In addition to file timestamps, we also keep track of when a .d.ts file
|
||||
// had its file touched but not had its contents changed - this allows us
|
||||
// to skip a downstream typecheck
|
||||
if (path.extname(output) === ".d.ts") {
|
||||
const unchangedTime = host.getUnchangedTime ? host.getUnchangedTime(output) : undefined;
|
||||
if (unchangedTime !== undefined) {
|
||||
newestDeclarationFileContentChangedTime = newer(unchangedTime, newestDeclarationFileContentChangedTime);
|
||||
}
|
||||
else {
|
||||
const outputModifiedTime = host.getModifiedTime(output) || missingFileModifiedTime;
|
||||
newestDeclarationFileContentChangedTime = newer(newestDeclarationFileContentChangedTime, outputModifiedTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let pseudoUpToDate = false;
|
||||
let usesPrepend = false;
|
||||
/** @type {string | undefined} */
|
||||
let upstreamChangedProject;
|
||||
if (project.projectReferences) {
|
||||
if (host.setLastStatus) host.setLastStatus(project.options.configFilePath, { type: UpToDateStatusType.ComputingUpstream });
|
||||
for (const ref of project.projectReferences) {
|
||||
usesPrepend = usesPrepend || !!(ref.prepend);
|
||||
const resolvedRef = ts.resolveProjectReferencePath(host, ref);
|
||||
const parsedRef = host.parseConfigFile ? host.parseConfigFile(resolvedRef) : ts.getParsedCommandLineOfConfigFile(resolvedRef, {}, parseConfigHost);
|
||||
const refStatus = getUpToDateStatus(host, parsedRef);
|
||||
|
||||
// Its a circular reference ignore the status of this project
|
||||
if (refStatus.type === UpToDateStatusType.ComputingUpstream) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// An upstream project is blocked
|
||||
if (refStatus.type === UpToDateStatusType.Unbuildable) {
|
||||
return {
|
||||
type: UpToDateStatusType.UpstreamBlocked,
|
||||
upstreamProjectName: ref.path
|
||||
};
|
||||
}
|
||||
|
||||
// If the upstream project is out of date, then so are we (someone shouldn't have asked, though?)
|
||||
if (refStatus.type !== UpToDateStatusType.UpToDate) {
|
||||
return {
|
||||
type: UpToDateStatusType.UpstreamOutOfDate,
|
||||
upstreamProjectName: ref.path
|
||||
};
|
||||
}
|
||||
|
||||
// If the upstream project's newest file is older than our oldest output, we
|
||||
// can't be out of date because of it
|
||||
if (refStatus.newestInputFileTime && refStatus.newestInputFileTime <= oldestOutputFileTime) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the upstream project has only change .d.ts files, and we've built
|
||||
// *after* those files, then we're "psuedo up to date" and eligible for a fast rebuild
|
||||
if (refStatus.newestDeclarationFileContentChangedTime && refStatus.newestDeclarationFileContentChangedTime <= oldestOutputFileTime) {
|
||||
pseudoUpToDate = true;
|
||||
upstreamChangedProject = ref.path;
|
||||
continue;
|
||||
}
|
||||
|
||||
// We have an output older than an upstream output - we are out of date
|
||||
return {
|
||||
type: UpToDateStatusType.OutOfDateWithUpstream,
|
||||
outOfDateOutputFileName: oldestOutputFileName,
|
||||
newerProjectName: ref.path
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (missingOutputFileName !== undefined) {
|
||||
return {
|
||||
type: UpToDateStatusType.OutputMissing,
|
||||
missingOutputFileName
|
||||
};
|
||||
}
|
||||
|
||||
if (isOutOfDateWithInputs) {
|
||||
return {
|
||||
type: UpToDateStatusType.OutOfDateWithSelf,
|
||||
outOfDateOutputFileName: oldestOutputFileName,
|
||||
newerInputFileName: newestInputFileName
|
||||
};
|
||||
}
|
||||
|
||||
if (usesPrepend && pseudoUpToDate) {
|
||||
return {
|
||||
type: UpToDateStatusType.OutOfDateWithUpstream,
|
||||
outOfDateOutputFileName: oldestOutputFileName,
|
||||
newerProjectName: upstreamChangedProject
|
||||
};
|
||||
}
|
||||
|
||||
// Up to date
|
||||
return {
|
||||
type: pseudoUpToDate ? UpToDateStatusType.UpToDateWithUpstreamTypes : UpToDateStatusType.UpToDate,
|
||||
newestDeclarationFileContentChangedTime,
|
||||
newestInputFileTime,
|
||||
newestOutputFileTime,
|
||||
newestInputFileName,
|
||||
newestOutputFileName,
|
||||
oldestOutputFileName
|
||||
};
|
||||
}
|
||||
|
||||
const parseConfigHost = {
|
||||
useCaseSensitiveFileNames: true,
|
||||
getCurrentDirectory: () => process.cwd(),
|
||||
readDirectory: (file) => fs.readdirSync(file),
|
||||
fileExists: file => fs.existsSync(file) && fs.statSync(file).isFile(),
|
||||
readFile: file => fs.readFileSync(file, "utf8"),
|
||||
onUnRecoverableConfigFileDiagnostic: () => undefined
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef {import("vinyl")} File
|
||||
* @typedef {import("../../lib/typescript").ParsedCommandLine & { options: CompilerOptions }} ParsedCommandLine
|
||||
* @typedef {import("../../lib/typescript").CompilerOptions & { configFilePath?: string }} CompilerOptions
|
||||
* @typedef {import("../../lib/typescript").DiagnosticMessage} DiagnosticMessage
|
||||
* @typedef UpToDateHost
|
||||
* @property {(fileName: string) => boolean} fileExists
|
||||
* @property {(fileName: string) => Date} getModifiedTime
|
||||
* @property {(fileName: string) => Date} [getUnchangedTime]
|
||||
* @property {(configFilePath: string) => ParsedCommandLine | undefined} parseConfigFile
|
||||
* @property {(configFilePath: string) => UpToDateStatus} [getLastStatus]
|
||||
* @property {(configFilePath: string, status: UpToDateStatus) => void} [setLastStatus]
|
||||
*
|
||||
* @typedef Status.Unbuildable
|
||||
* @property {UpToDateStatusType.Unbuildable} type
|
||||
* @property {string} reason
|
||||
*
|
||||
* @typedef Status.ContainerOnly
|
||||
* @property {UpToDateStatusType.ContainerOnly} type
|
||||
*
|
||||
* @typedef Status.UpToDate
|
||||
* @property {UpToDateStatusType.UpToDate | UpToDateStatusType.UpToDateWithUpstreamTypes} type
|
||||
* @property {Date} [newestInputFileTime]
|
||||
* @property {string} [newestInputFileName]
|
||||
* @property {Date} [newestDeclarationFileContentChangedTime]
|
||||
* @property {Date} [newestOutputFileTime]
|
||||
* @property {string} [newestOutputFileName]
|
||||
* @property {string} [oldestOutputFileName]
|
||||
*
|
||||
* @typedef Status.OutputMissing
|
||||
* @property {UpToDateStatusType.OutputMissing} type
|
||||
* @property {string} missingOutputFileName
|
||||
*
|
||||
* @typedef Status.OutOfDateWithSelf
|
||||
* @property {UpToDateStatusType.OutOfDateWithSelf} type
|
||||
* @property {string} outOfDateOutputFileName
|
||||
* @property {string} newerInputFileName
|
||||
*
|
||||
* @typedef Status.UpstreamOutOfDate
|
||||
* @property {UpToDateStatusType.UpstreamOutOfDate} type
|
||||
* @property {string} upstreamProjectName
|
||||
*
|
||||
* @typedef Status.UpstreamBlocked
|
||||
* @property {UpToDateStatusType.UpstreamBlocked} type
|
||||
* @property {string} upstreamProjectName
|
||||
*
|
||||
* @typedef Status.ComputingUpstream
|
||||
* @property {UpToDateStatusType.ComputingUpstream} type
|
||||
*
|
||||
* @typedef Status.OutOfDateWithUpstream
|
||||
* @property {UpToDateStatusType.OutOfDateWithUpstream} type
|
||||
* @property {string} outOfDateOutputFileName
|
||||
* @property {string} newerProjectName
|
||||
|
||||
* @typedef {Status.Unbuildable | Status.ContainerOnly | Status.UpToDate | Status.OutputMissing | Status.OutOfDateWithSelf | Status.UpstreamOutOfDate | Status.UpstreamBlocked | Status.ComputingUpstream | Status.OutOfDateWithUpstream} UpToDateStatus
|
||||
*/
|
||||
void 0;
|
|
@ -1,7 +1,119 @@
|
|||
// @ts-check
|
||||
/// <reference path="../types/ambient.d.ts" />
|
||||
|
||||
const fs = require("fs");
|
||||
const File = require("./vinyl");
|
||||
const { Readable } = require("stream");
|
||||
const path = require("path");
|
||||
const log = require("fancy-log");
|
||||
const mkdirp = require("mkdirp");
|
||||
const del = require("del");
|
||||
const File = require("vinyl");
|
||||
const ts = require("../../lib/typescript");
|
||||
const { default: chalk } = require("chalk");
|
||||
const { spawn } = require("child_process");
|
||||
const { CancellationToken, CancelError, Deferred } = require("prex");
|
||||
const { Readable, Duplex } = require("stream");
|
||||
|
||||
const isWindows = /^win/.test(process.platform);
|
||||
|
||||
/**
|
||||
* Executes the provided command once with the supplied arguments.
|
||||
* @param {string} cmd
|
||||
* @param {string[]} args
|
||||
* @param {ExecOptions} [options]
|
||||
*
|
||||
* @typedef ExecOptions
|
||||
* @property {boolean} [ignoreExitCode]
|
||||
* @property {import("prex").CancellationToken} [cancelToken]
|
||||
* @property {boolean} [hidePrompt]
|
||||
*/
|
||||
function exec(cmd, args, options = {}) {
|
||||
return /**@type {Promise<{exitCode: number}>}*/(new Promise((resolve, reject) => {
|
||||
const { ignoreExitCode, cancelToken = CancellationToken.none } = options;
|
||||
cancelToken.throwIfCancellationRequested();
|
||||
|
||||
// TODO (weswig): Update child_process types to add windowsVerbatimArguments to the type definition
|
||||
const subshellFlag = isWindows ? "/c" : "-c";
|
||||
const command = isWindows ? [possiblyQuote(cmd), ...args] : [`${cmd} ${args.join(" ")}`];
|
||||
|
||||
if (!options.hidePrompt) log(`> ${chalk.green(cmd)} ${args.join(" ")}`);
|
||||
const proc = spawn(isWindows ? "cmd" : "/bin/sh", [subshellFlag, ...command], { stdio: "inherit", windowsVerbatimArguments: true });
|
||||
const registration = cancelToken.register(() => {
|
||||
log(`${chalk.red("killing")} '${chalk.green(cmd)} ${args.join(" ")}'...`);
|
||||
proc.kill("SIGINT");
|
||||
proc.kill("SIGTERM");
|
||||
reject(new CancelError());
|
||||
});
|
||||
proc.on("exit", exitCode => {
|
||||
registration.unregister();
|
||||
if (exitCode === 0 || ignoreExitCode) {
|
||||
resolve({ exitCode });
|
||||
}
|
||||
else {
|
||||
reject(new Error(`Process exited with code: ${exitCode}`));
|
||||
}
|
||||
});
|
||||
proc.on("error", error => {
|
||||
registration.unregister();
|
||||
reject(error);
|
||||
});
|
||||
}));
|
||||
}
|
||||
exports.exec = exec;
|
||||
|
||||
/**
|
||||
* @param {string} cmd
|
||||
*/
|
||||
function possiblyQuote(cmd) {
|
||||
return cmd.indexOf(" ") >= 0 ? `"${cmd}"` : cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ts.Diagnostic[]} diagnostics
|
||||
* @param {{ cwd?: string, pretty?: boolean }} [options]
|
||||
*/
|
||||
function formatDiagnostics(diagnostics, options) {
|
||||
return options && options.pretty
|
||||
? ts.formatDiagnosticsWithColorAndContext(diagnostics, getFormatDiagnosticsHost(options && options.cwd))
|
||||
: ts.formatDiagnostics(diagnostics, getFormatDiagnosticsHost(options && options.cwd));
|
||||
}
|
||||
exports.formatDiagnostics = formatDiagnostics;
|
||||
|
||||
/**
|
||||
* @param {ts.Diagnostic[]} diagnostics
|
||||
* @param {{ cwd?: string }} [options]
|
||||
*/
|
||||
function reportDiagnostics(diagnostics, options) {
|
||||
log(formatDiagnostics(diagnostics, { cwd: options && options.cwd, pretty: process.stdout.isTTY }));
|
||||
}
|
||||
exports.reportDiagnostics = reportDiagnostics;
|
||||
|
||||
/**
|
||||
* @param {string | undefined} cwd
|
||||
* @returns {ts.FormatDiagnosticsHost}
|
||||
*/
|
||||
function getFormatDiagnosticsHost(cwd) {
|
||||
return {
|
||||
getCanonicalFileName: fileName => fileName,
|
||||
getCurrentDirectory: () => cwd,
|
||||
getNewLine: () => ts.sys.newLine,
|
||||
};
|
||||
}
|
||||
exports.getFormatDiagnosticsHost = getFormatDiagnosticsHost;
|
||||
|
||||
/**
|
||||
* Reads JSON data with optional comments using the LKG TypeScript compiler
|
||||
* @param {string} jsonPath
|
||||
*/
|
||||
function readJson(jsonPath) {
|
||||
const jsonText = fs.readFileSync(jsonPath, "utf8");
|
||||
const result = ts.parseConfigFileTextToJson(jsonPath, jsonText);
|
||||
if (result.error) {
|
||||
reportDiagnostics([result.error]);
|
||||
throw new Error("An error occurred during parse.");
|
||||
}
|
||||
return result.config;
|
||||
}
|
||||
exports.readJson = readJson;
|
||||
|
||||
/**
|
||||
* @param {File} file
|
||||
|
@ -24,4 +136,299 @@ function streamFromBuffer(buffer) {
|
|||
}
|
||||
});
|
||||
}
|
||||
exports.streamFromBuffer = streamFromBuffer;
|
||||
exports.streamFromBuffer = streamFromBuffer;
|
||||
|
||||
/**
|
||||
* @param {string | string[]} source
|
||||
* @param {string | string[]} dest
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function needsUpdate(source, dest) {
|
||||
if (typeof source === "string" && typeof dest === "string") {
|
||||
if (fs.existsSync(dest)) {
|
||||
const {mtime: outTime} = fs.statSync(dest);
|
||||
const {mtime: inTime} = fs.statSync(source);
|
||||
if (+inTime <= +outTime) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (typeof source === "string" && typeof dest !== "string") {
|
||||
const {mtime: inTime} = fs.statSync(source);
|
||||
for (const filepath of dest) {
|
||||
if (fs.existsSync(filepath)) {
|
||||
const {mtime: outTime} = fs.statSync(filepath);
|
||||
if (+inTime > +outTime) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (typeof source !== "string" && typeof dest === "string") {
|
||||
if (fs.existsSync(dest)) {
|
||||
const {mtime: outTime} = fs.statSync(dest);
|
||||
for (const filepath of source) {
|
||||
if (fs.existsSync(filepath)) {
|
||||
const {mtime: inTime} = fs.statSync(filepath);
|
||||
if (+inTime > +outTime) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (typeof source !== "string" && typeof dest !== "string") {
|
||||
for (let i = 0; i < source.length; i++) {
|
||||
if (!dest[i]) {
|
||||
continue;
|
||||
}
|
||||
if (fs.existsSync(dest[i])) {
|
||||
const {mtime: outTime} = fs.statSync(dest[i]);
|
||||
const {mtime: inTime} = fs.statSync(source[i]);
|
||||
if (+inTime > +outTime) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
exports.needsUpdate = needsUpdate;
|
||||
|
||||
function getDiffTool() {
|
||||
const program = process.env.DIFF;
|
||||
if (!program) {
|
||||
log.warn("Add the 'DIFF' environment variable to the path of the program you want to use.");
|
||||
process.exit(1);
|
||||
}
|
||||
return program;
|
||||
}
|
||||
exports.getDiffTool = getDiffTool;
|
||||
|
||||
/**
|
||||
* Find the size of a directory recursively.
|
||||
* Symbolic links can cause a loop.
|
||||
* @param {string} root
|
||||
* @returns {number} bytes
|
||||
*/
|
||||
function getDirSize(root) {
|
||||
const stats = fs.lstatSync(root);
|
||||
|
||||
if (!stats.isDirectory()) {
|
||||
return stats.size;
|
||||
}
|
||||
|
||||
return fs.readdirSync(root)
|
||||
.map(file => getDirSize(path.join(root, file)))
|
||||
.reduce((acc, num) => acc + num, 0);
|
||||
}
|
||||
exports.getDirSize = getDirSize;
|
||||
|
||||
/**
|
||||
* Flattens a project with project references into a single project.
|
||||
* @param {string} projectSpec The path to a tsconfig.json file or its containing directory.
|
||||
* @param {string} flattenedProjectSpec The output path for the flattened tsconfig.json file.
|
||||
* @param {FlattenOptions} [options] Options used to flatten a project hierarchy.
|
||||
*
|
||||
* @typedef FlattenOptions
|
||||
* @property {string} [cwd] The path to use for the current working directory. Defaults to `process.cwd()`.
|
||||
* @property {import("../../lib/typescript").CompilerOptions} [compilerOptions] Compiler option overrides.
|
||||
* @property {boolean} [force] Forces creation of the output project.
|
||||
* @property {string[]} [exclude] Files to exclude (relative to `cwd`)
|
||||
*/
|
||||
function flatten(projectSpec, flattenedProjectSpec, options = {}) {
|
||||
const cwd = normalizeSlashes(options.cwd ? path.resolve(options.cwd) : process.cwd());
|
||||
const files = [];
|
||||
const resolvedOutputSpec = path.resolve(cwd, flattenedProjectSpec);
|
||||
const resolvedOutputDirectory = path.dirname(resolvedOutputSpec);
|
||||
const resolvedProjectSpec = resolveProjectSpec(projectSpec, cwd, undefined);
|
||||
const project = readJson(resolvedProjectSpec);
|
||||
const skipProjects = /**@type {Set<string>}*/(new Set());
|
||||
const skipFiles = new Set(options && options.exclude && options.exclude.map(file => normalizeSlashes(path.resolve(cwd, file))));
|
||||
recur(resolvedProjectSpec, project);
|
||||
|
||||
if (options.force || needsUpdate(files, resolvedOutputSpec)) {
|
||||
const config = {
|
||||
extends: normalizeSlashes(path.relative(resolvedOutputDirectory, resolvedProjectSpec)),
|
||||
compilerOptions: options.compilerOptions || {},
|
||||
files: files.map(file => normalizeSlashes(path.relative(resolvedOutputDirectory, file)))
|
||||
};
|
||||
mkdirp.sync(resolvedOutputDirectory);
|
||||
fs.writeFileSync(resolvedOutputSpec, JSON.stringify(config, undefined, 2), "utf8");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} projectSpec
|
||||
* @param {object} project
|
||||
*/
|
||||
function recur(projectSpec, project) {
|
||||
if (skipProjects.has(projectSpec)) return;
|
||||
skipProjects.add(project);
|
||||
if (project.references) {
|
||||
for (const ref of project.references) {
|
||||
const referencedSpec = resolveProjectSpec(ref.path, cwd, projectSpec);
|
||||
const referencedProject = readJson(referencedSpec);
|
||||
recur(referencedSpec, referencedProject);
|
||||
}
|
||||
}
|
||||
if (project.include) {
|
||||
throw new Error("Flattened project may not have an 'include' list.");
|
||||
}
|
||||
if (!project.files) {
|
||||
throw new Error("Flattened project must have an explicit 'files' list.");
|
||||
}
|
||||
const projectDirectory = path.dirname(projectSpec);
|
||||
for (let file of project.files) {
|
||||
file = normalizeSlashes(path.resolve(projectDirectory, file));
|
||||
if (skipFiles.has(file)) continue;
|
||||
skipFiles.add(file);
|
||||
files.push(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.flatten = flatten;
|
||||
|
||||
/**
|
||||
* @param {string} file
|
||||
*/
|
||||
function normalizeSlashes(file) {
|
||||
return file.replace(/\\/g, "/");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} projectSpec
|
||||
* @param {string} cwd
|
||||
* @param {string | undefined} referrer
|
||||
* @returns {string}
|
||||
*/
|
||||
function resolveProjectSpec(projectSpec, cwd, referrer) {
|
||||
let projectPath = normalizeSlashes(path.resolve(cwd, referrer ? path.dirname(referrer) : "", projectSpec));
|
||||
const stats = fs.statSync(projectPath);
|
||||
if (stats.isFile()) return normalizeSlashes(projectPath);
|
||||
return normalizeSlashes(path.resolve(cwd, projectPath, "tsconfig.json"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | ((file: File) => string) | { cwd?: string }} [dest]
|
||||
* @param {{ cwd?: string }} [opts]
|
||||
*/
|
||||
function rm(dest, opts) {
|
||||
if (dest && typeof dest === "object") opts = dest, dest = undefined;
|
||||
let failed = false;
|
||||
|
||||
const cwd = path.resolve(opts && opts.cwd || process.cwd());
|
||||
|
||||
/** @type {{ file: File, deleted: boolean, promise: Promise<any>, cb: Function }[]} */
|
||||
const pending = [];
|
||||
|
||||
const processDeleted = () => {
|
||||
if (failed) return;
|
||||
while (pending.length && pending[0].deleted) {
|
||||
const { file, cb } = pending.shift();
|
||||
duplex.push(file);
|
||||
cb();
|
||||
}
|
||||
};
|
||||
|
||||
const duplex = new Duplex({
|
||||
objectMode: true,
|
||||
/**
|
||||
* @param {string|Buffer|File} file
|
||||
*/
|
||||
write(file, _, cb) {
|
||||
if (failed) return;
|
||||
if (typeof file === "string" || Buffer.isBuffer(file)) return cb(new Error("Only Vinyl files are supported."));
|
||||
const basePath = typeof dest === "string" ? path.resolve(cwd, dest) :
|
||||
typeof dest === "function" ? path.resolve(cwd, dest(file)) :
|
||||
file.base;
|
||||
const filePath = path.resolve(basePath, file.relative);
|
||||
file.cwd = cwd;
|
||||
file.base = basePath;
|
||||
file.path = filePath;
|
||||
const entry = {
|
||||
file,
|
||||
deleted: false,
|
||||
cb,
|
||||
promise: del(file.path).then(() => {
|
||||
entry.deleted = true;
|
||||
processDeleted();
|
||||
}, err => {
|
||||
failed = true;
|
||||
pending.length = 0;
|
||||
cb(err);
|
||||
})
|
||||
};
|
||||
pending.push(entry);
|
||||
},
|
||||
final(cb) {
|
||||
processDeleted();
|
||||
if (pending.length) {
|
||||
Promise
|
||||
.all(pending.map(entry => entry.promise))
|
||||
.then(() => processDeleted())
|
||||
.then(() => cb(), cb);
|
||||
return;
|
||||
}
|
||||
cb();
|
||||
},
|
||||
read() {
|
||||
}
|
||||
});
|
||||
return duplex;
|
||||
}
|
||||
exports.rm = rm;
|
||||
|
||||
class Debouncer {
|
||||
/**
|
||||
* @param {number} timeout
|
||||
* @param {() => Promise<any>} action
|
||||
*/
|
||||
constructor(timeout, action) {
|
||||
this._timeout = timeout;
|
||||
this._action = action;
|
||||
}
|
||||
|
||||
enqueue() {
|
||||
if (this._timer) {
|
||||
clearTimeout(this._timer);
|
||||
this._timer = undefined;
|
||||
}
|
||||
|
||||
if (!this._deferred) {
|
||||
this._deferred = new Deferred();
|
||||
}
|
||||
|
||||
this._timer = setTimeout(() => this.run(), 100);
|
||||
return this._deferred.promise;
|
||||
}
|
||||
|
||||
run() {
|
||||
if (this._timer) {
|
||||
clearTimeout(this._timer);
|
||||
this._timer = undefined;
|
||||
}
|
||||
|
||||
const deferred = this._deferred;
|
||||
this._deferred = undefined;
|
||||
this._projects = undefined;
|
||||
try {
|
||||
deferred.resolve(this._action());
|
||||
}
|
||||
catch (e) {
|
||||
deferred.reject(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.Debouncer = Debouncer;
|
60
scripts/build/vinyl.d.ts
vendored
60
scripts/build/vinyl.d.ts
vendored
|
@ -1,60 +0,0 @@
|
|||
// NOTE: This makes it possible to correctly type vinyl Files under @ts-check.
|
||||
export = File;
|
||||
|
||||
declare class File<T extends File.Contents = File.Contents> {
|
||||
constructor(options?: File.VinylOptions<T>);
|
||||
|
||||
cwd: string;
|
||||
base: string;
|
||||
path: string;
|
||||
readonly history: ReadonlyArray<string>;
|
||||
contents: T;
|
||||
relative: string;
|
||||
dirname: string;
|
||||
basename: string;
|
||||
stem: string;
|
||||
extname: string;
|
||||
symlink: string | null;
|
||||
stat: import("fs").Stats | null;
|
||||
sourceMap?: import("./sourcemaps").RawSourceMap | string;
|
||||
|
||||
[custom: string]: any;
|
||||
|
||||
isBuffer(): this is T extends Buffer ? File<Buffer> : never;
|
||||
isStream(): this is T extends NodeJS.ReadableStream ? File<NodeJS.ReadableStream> : never;
|
||||
isNull(): this is T extends null ? File<null> : never;
|
||||
isDirectory(): this is T extends null ? File.Directory : never;
|
||||
isSymbolic(): this is T extends null ? File.Symbolic : never;
|
||||
clone(opts?: { contents?: boolean, deep?: boolean }): this;
|
||||
}
|
||||
|
||||
namespace File {
|
||||
export interface VinylOptions<T extends Contents = Contents> {
|
||||
cwd?: string;
|
||||
base?: string;
|
||||
path?: string;
|
||||
history?: ReadonlyArray<string>;
|
||||
stat?: import("fs").Stats;
|
||||
contents?: T;
|
||||
sourceMap?: import("./sourcemaps").RawSourceMap | string;
|
||||
[custom: string]: any;
|
||||
}
|
||||
|
||||
export type Contents = Buffer | NodeJS.ReadableStream | null;
|
||||
export type File = import("./vinyl");
|
||||
export type NullFile = File<null>;
|
||||
export type BufferFile = File<Buffer>;
|
||||
export type StreamFile = File<NodeJS.ReadableStream>;
|
||||
|
||||
export interface Directory extends NullFile {
|
||||
isNull(): true;
|
||||
isDirectory(): true;
|
||||
isSymbolic(): this is never;
|
||||
}
|
||||
|
||||
export interface Symbolic extends NullFile {
|
||||
isNull(): true;
|
||||
isDirectory(): this is never;
|
||||
isSymbolic(): true;
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
module.exports = require("vinyl");
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference lib="esnext.asynciterable" />
|
||||
// Must reference esnext.asynciterable lib, since octokit uses AsyncIterable internally
|
||||
import cp = require("child_process");
|
||||
import Octokit = require("@octokit/rest");
|
||||
|
||||
|
@ -35,7 +37,7 @@ gh.authenticate({
|
|||
type: "token",
|
||||
token: process.argv[2]
|
||||
});
|
||||
gh.pullRequests.create({
|
||||
gh.pulls.create({
|
||||
owner: process.env.TARGET_FORK,
|
||||
repo: "TypeScript",
|
||||
maintainer_can_modify: true,
|
||||
|
@ -50,7 +52,7 @@ cc ${reviewers.map(r => "@" + r).join(" ")}`,
|
|||
}).then(r => {
|
||||
const num = r.data.number;
|
||||
console.log(`Pull request ${num} created.`);
|
||||
return gh.pullRequests.createReviewRequest({
|
||||
return gh.pulls.createReviewRequest({
|
||||
owner: process.env.TARGET_FORK,
|
||||
repo: "TypeScript",
|
||||
number: num,
|
||||
|
|
77
scripts/types/ambient.d.ts
vendored
77
scripts/types/ambient.d.ts
vendored
|
@ -1,3 +1,5 @@
|
|||
import { TaskFunction } from "gulp";
|
||||
|
||||
declare module "gulp-clone" {
|
||||
function Clone(): NodeJS.ReadWriteStream;
|
||||
namespace Clone {
|
||||
|
@ -14,3 +16,78 @@ declare module "gulp-insert" {
|
|||
}
|
||||
|
||||
declare module "sorcery";
|
||||
|
||||
declare module "vinyl" {
|
||||
// NOTE: This makes it possible to correctly type vinyl Files under @ts-check.
|
||||
export = File;
|
||||
|
||||
declare class File<T extends File.Contents = File.Contents> {
|
||||
constructor(options?: File.VinylOptions<T>);
|
||||
|
||||
cwd: string;
|
||||
base: string;
|
||||
path: string;
|
||||
readonly history: ReadonlyArray<string>;
|
||||
contents: T;
|
||||
relative: string;
|
||||
dirname: string;
|
||||
basename: string;
|
||||
stem: string;
|
||||
extname: string;
|
||||
symlink: string | null;
|
||||
stat: import("fs").Stats | null;
|
||||
sourceMap?: import("./sourcemaps").RawSourceMap | string;
|
||||
|
||||
[custom: string]: any;
|
||||
|
||||
isBuffer(): this is T extends Buffer ? File<Buffer> : never;
|
||||
isStream(): this is T extends NodeJS.ReadableStream ? File<NodeJS.ReadableStream> : never;
|
||||
isNull(): this is T extends null ? File<null> : never;
|
||||
isDirectory(): this is T extends null ? File.Directory : never;
|
||||
isSymbolic(): this is T extends null ? File.Symbolic : never;
|
||||
clone(opts?: { contents?: boolean, deep?: boolean }): this;
|
||||
}
|
||||
|
||||
namespace File {
|
||||
export interface VinylOptions<T extends Contents = Contents> {
|
||||
cwd?: string;
|
||||
base?: string;
|
||||
path?: string;
|
||||
history?: ReadonlyArray<string>;
|
||||
stat?: import("fs").Stats;
|
||||
contents?: T;
|
||||
sourceMap?: import("./sourcemaps").RawSourceMap | string;
|
||||
[custom: string]: any;
|
||||
}
|
||||
|
||||
export type Contents = Buffer | NodeJS.ReadableStream | null;
|
||||
export type File = import("./vinyl");
|
||||
export type NullFile = File<null>;
|
||||
export type BufferFile = File<Buffer>;
|
||||
export type StreamFile = File<NodeJS.ReadableStream>;
|
||||
|
||||
export interface Directory extends NullFile {
|
||||
isNull(): true;
|
||||
isDirectory(): true;
|
||||
isSymbolic(): this is never;
|
||||
}
|
||||
|
||||
export interface Symbolic extends NullFile {
|
||||
isNull(): true;
|
||||
isDirectory(): this is never;
|
||||
isSymbolic(): true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare module "undertaker" {
|
||||
interface TaskFunctionParams {
|
||||
flags?: Record<string, string>;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "gulp-sourcemaps" {
|
||||
interface WriteOptions {
|
||||
destPath?: string;
|
||||
}
|
||||
}
|
|
@ -35,8 +35,8 @@ function createCancellationToken(args: string[]): ServerCancellationToken {
|
|||
}
|
||||
// cancellationPipeName is a string without '*' inside that can optionally end with '*'
|
||||
// when client wants to signal cancellation it should create a named pipe with name=<cancellationPipeName>
|
||||
// server will synchronously check the presence of the pipe and treat its existance as indicator that current request should be canceled.
|
||||
// in case if client prefers to use more fine-grained schema than one name for all request it can add '*' to the end of cancelellationPipeName.
|
||||
// server will synchronously check the presence of the pipe and treat its existence as indicator that current request should be canceled.
|
||||
// in case if client prefers to use more fine-grained schema than one name for all request it can add '*' to the end of cancellationPipeName.
|
||||
// in this case pipe name will be build dynamically as <cancellationPipeName><request_seq>.
|
||||
if (cancellationPipeName.charAt(cancellationPipeName.length - 1) === "*") {
|
||||
const namePrefix = cancellationPipeName.slice(0, -1);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../tsconfig-base",
|
||||
"extends": "../tsconfig-noncomposite-base",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../built/local/",
|
||||
"rootDir": ".",
|
||||
|
|
|
@ -550,7 +550,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
// We create a return control flow graph for IIFEs and constructors. For constructors
|
||||
// we use the return control flow graph in strict property intialization checks.
|
||||
// we use the return control flow graph in strict property initialization checks.
|
||||
currentReturnTarget = isIIFE || node.kind === SyntaxKind.Constructor ? createBranchLabel() : undefined;
|
||||
currentBreakTarget = undefined;
|
||||
currentContinueTarget = undefined;
|
||||
|
@ -3445,7 +3445,7 @@ namespace ts {
|
|||
// If a FunctionDeclaration is generator function and is the body of a
|
||||
// transformed async function, then this node can be transformed to a
|
||||
// down-level generator.
|
||||
// Currently we do not support transforming any other generator fucntions
|
||||
// Currently we do not support transforming any other generator functions
|
||||
// down level.
|
||||
if (node.asteriskToken) {
|
||||
transformFlags |= TransformFlags.AssertGenerator;
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace ts {
|
|||
currentChangedFilePath: Path | undefined;
|
||||
/**
|
||||
* Map of file signatures, with key being file path, calculated while getting current changed file's affected files
|
||||
* These will be commited whenever the iteration through affected files of current changed file is complete
|
||||
* These will be committed whenever the iteration through affected files of current changed file is complete
|
||||
*/
|
||||
currentAffectedFilesSignatures: Map<string> | undefined;
|
||||
/**
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace ts {
|
|||
*/
|
||||
readonly referencedMap: ReadonlyMap<BuilderState.ReferencedSet> | undefined;
|
||||
/**
|
||||
* Contains the map of exported modules ReferencedSet=exorted module files from the file if module emit is enabled
|
||||
* Contains the map of exported modules ReferencedSet=exported module files from the file if module emit is enabled
|
||||
* Otherwise undefined
|
||||
*/
|
||||
readonly exportedModulesMap: Map<BuilderState.ReferencedSet> | undefined;
|
||||
|
@ -268,9 +268,9 @@ namespace ts.BuilderState {
|
|||
*/
|
||||
export function getFilesAffectedBy(state: BuilderState, programOfThisState: Program, path: Path, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, cacheToUpdateSignature?: Map<string>, exportedModulesMapCache?: ComputingExportedModulesMap): ReadonlyArray<SourceFile> {
|
||||
// Since the operation could be cancelled, the signatures are always stored in the cache
|
||||
// They will be commited once it is safe to use them
|
||||
// They will be committed once it is safe to use them
|
||||
// eg when calling this api from tsserver, if there is no cancellation of the operation
|
||||
// In the other cases the affected files signatures are commited only after the iteration through the result is complete
|
||||
// In the other cases the affected files signatures are committed only after the iteration through the result is complete
|
||||
const signatureCache = cacheToUpdateSignature || createMap();
|
||||
const sourceFile = programOfThisState.getSourceFileByPath(path);
|
||||
if (!sourceFile) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1935,7 +1935,7 @@ namespace ts {
|
|||
|
||||
function directoryOfCombinedPath(fileName: string, basePath: string) {
|
||||
// Use the `getNormalizedAbsolutePath` function to avoid canonicalizing the path, as it must remain noncanonical
|
||||
// until consistient casing errors are reported
|
||||
// until consistent casing errors are reported
|
||||
return getDirectoryPath(getNormalizedAbsolutePath(fileName, basePath));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
namespace ts {
|
||||
// WARNING: The script `configureNightly.ts` uses a regexp to parse out these values.
|
||||
// If changing the text in this section, be sure to test `configureNightly` too.
|
||||
export const versionMajorMinor = "3.3";
|
||||
export const versionMajorMinor = "3.4";
|
||||
/** The version of the TypeScript compiler release */
|
||||
export const version = `${versionMajorMinor}.0-dev`;
|
||||
}
|
||||
|
@ -884,8 +884,11 @@ namespace ts {
|
|||
/**
|
||||
* Compacts an array, removing any falsey elements.
|
||||
*/
|
||||
export function compact<T>(array: T[]): T[];
|
||||
export function compact<T>(array: ReadonlyArray<T>): ReadonlyArray<T>;
|
||||
export function compact<T>(array: (T | undefined | null | false | 0 | "")[]): T[];
|
||||
export function compact<T>(array: ReadonlyArray<T | undefined | null | false | 0 | "">): ReadonlyArray<T>;
|
||||
// TSLint thinks these can be combined with the above - they cannot; they'd produce higher-priority inferences and prevent the falsey types from being stripped
|
||||
export function compact<T>(array: T[]): T[]; // tslint:disable-line unified-signatures
|
||||
export function compact<T>(array: ReadonlyArray<T>): ReadonlyArray<T>; // tslint:disable-line unified-signatures
|
||||
export function compact<T>(array: T[]): T[] {
|
||||
let result: T[] | undefined;
|
||||
if (array) {
|
||||
|
|
|
@ -1019,6 +1019,14 @@
|
|||
"category": "Error",
|
||||
"code": 1353
|
||||
},
|
||||
"'readonly' type modifier is only permitted on array and tuple literal types.": {
|
||||
"category": "Error",
|
||||
"code": 1354
|
||||
},
|
||||
"A 'const' assertion can only be applied to a string, number, boolean, array, or object literal.": {
|
||||
"category": "Error",
|
||||
"code": 1355
|
||||
},
|
||||
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
|
@ -2088,15 +2096,15 @@
|
|||
"category": "Error",
|
||||
"code": 2577
|
||||
},
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.": {
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i @types/node`.": {
|
||||
"category": "Error",
|
||||
"code": 2580
|
||||
},
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i @types/jquery` and then add `jquery` to the types field in your tsconfig.": {
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i @types/jquery`.": {
|
||||
"category": "Error",
|
||||
"code": 2581
|
||||
},
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig.": {
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha`.": {
|
||||
"category": "Error",
|
||||
"code": 2582
|
||||
},
|
||||
|
@ -2124,6 +2132,26 @@
|
|||
"category": "Error",
|
||||
"code": 2588
|
||||
},
|
||||
"Type instantiation is excessively deep and possibly infinite.": {
|
||||
"category": "Error",
|
||||
"code": 2589
|
||||
},
|
||||
"Expression produces a union type that is too complex to represent.": {
|
||||
"category": "Error",
|
||||
"code": 2590
|
||||
},
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.": {
|
||||
"category": "Error",
|
||||
"code": 2591
|
||||
},
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i @types/jquery` and then add `jquery` to the types field in your tsconfig.": {
|
||||
"category": "Error",
|
||||
"code": 2592
|
||||
},
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig.": {
|
||||
"category": "Error",
|
||||
"code": 2593
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
|
|
|
@ -876,8 +876,8 @@ namespace ts {
|
|||
}
|
||||
|
||||
export function createTypeOperatorNode(type: TypeNode): TypeOperatorNode;
|
||||
export function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword, type: TypeNode): TypeOperatorNode;
|
||||
export function createTypeOperatorNode(operatorOrType: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | TypeNode, type?: TypeNode) {
|
||||
export function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode;
|
||||
export function createTypeOperatorNode(operatorOrType: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword | TypeNode, type?: TypeNode) {
|
||||
const node = createSynthesizedNode(SyntaxKind.TypeOperator) as TypeOperatorNode;
|
||||
node.operator = typeof operatorOrType === "number" ? operatorOrType : SyntaxKind.KeyOfKeyword;
|
||||
node.type = parenthesizeElementTypeMember(typeof operatorOrType === "number" ? type! : operatorOrType);
|
||||
|
@ -2874,7 +2874,7 @@ namespace ts {
|
|||
return node.emitNode = { annotatedNodes: [node] } as EmitNode;
|
||||
}
|
||||
|
||||
const sourceFile = getSourceFileOfNode(node);
|
||||
const sourceFile = getSourceFileOfNode(getParseTreeNode(getSourceFileOfNode(node)));
|
||||
getOrCreateEmitNode(sourceFile).annotatedNodes!.push(node);
|
||||
}
|
||||
|
||||
|
|
|
@ -2966,6 +2966,7 @@ namespace ts {
|
|||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.ReadonlyKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.UniqueKeyword:
|
||||
case SyntaxKind.VoidKeyword:
|
||||
|
@ -3055,7 +3056,7 @@ namespace ts {
|
|||
return finishNode(postfix);
|
||||
}
|
||||
|
||||
function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword) {
|
||||
function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword) {
|
||||
const node = <TypeOperatorNode>createNode(SyntaxKind.TypeOperator);
|
||||
parseExpected(operator);
|
||||
node.operator = operator;
|
||||
|
@ -3077,6 +3078,7 @@ namespace ts {
|
|||
switch (operator) {
|
||||
case SyntaxKind.KeyOfKeyword:
|
||||
case SyntaxKind.UniqueKeyword:
|
||||
case SyntaxKind.ReadonlyKeyword:
|
||||
return parseTypeOperator(operator);
|
||||
case SyntaxKind.InferKeyword:
|
||||
return parseInferType();
|
||||
|
|
|
@ -230,18 +230,18 @@ namespace ts {
|
|||
const readFileWithCache = (fileName: string): string | undefined => {
|
||||
const key = toPath(fileName);
|
||||
const value = readFileCache.get(key);
|
||||
if (value !== undefined) return value || undefined;
|
||||
if (value !== undefined) return value !== false ? value : undefined;
|
||||
return setReadFileCache(key, fileName);
|
||||
};
|
||||
const setReadFileCache = (key: Path, fileName: string) => {
|
||||
const newValue = originalReadFile.call(host, fileName);
|
||||
readFileCache.set(key, newValue || false);
|
||||
readFileCache.set(key, newValue !== undefined ? newValue : false);
|
||||
return newValue;
|
||||
};
|
||||
host.readFile = fileName => {
|
||||
const key = toPath(fileName);
|
||||
const value = readFileCache.get(key);
|
||||
if (value !== undefined) return value; // could be .d.ts from output
|
||||
if (value !== undefined) return value !== false ? value : undefined; // could be .d.ts from output
|
||||
if (!fileExtensionIs(fileName, Extension.Json)) {
|
||||
return originalReadFile.call(host, fileName);
|
||||
}
|
||||
|
|
|
@ -661,8 +661,15 @@ namespace ts {
|
|||
let pendingKind!: CommentKind;
|
||||
let pendingHasTrailingNewLine!: boolean;
|
||||
let hasPendingCommentRange = false;
|
||||
let collecting = trailing || pos === 0;
|
||||
let collecting = trailing;
|
||||
let accumulator = initial;
|
||||
if (pos === 0) {
|
||||
collecting = true;
|
||||
const shebang = getShebang(text);
|
||||
if (shebang) {
|
||||
pos = shebang.length;
|
||||
}
|
||||
}
|
||||
scan: while (pos >= 0 && pos < text.length) {
|
||||
const ch = text.charCodeAt(pos);
|
||||
switch (ch) {
|
||||
|
|
|
@ -1934,8 +1934,13 @@ namespace ts {
|
|||
case SyntaxKind.ConditionalType:
|
||||
return serializeTypeList([(<ConditionalTypeNode>node).trueType, (<ConditionalTypeNode>node).falseType]);
|
||||
|
||||
case SyntaxKind.TypeQuery:
|
||||
case SyntaxKind.TypeOperator:
|
||||
if ((<TypeOperatorNode>node).operator === SyntaxKind.ReadonlyKeyword) {
|
||||
return serializeTypeNode((<TypeOperatorNode>node).type);
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.TypeQuery:
|
||||
case SyntaxKind.IndexedAccessType:
|
||||
case SyntaxKind.MappedType:
|
||||
case SyntaxKind.TypeLiteral:
|
||||
|
|
|
@ -1233,7 +1233,7 @@ namespace ts {
|
|||
|
||||
export interface TypeOperatorNode extends TypeNode {
|
||||
kind: SyntaxKind.TypeOperator;
|
||||
operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword;
|
||||
operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword;
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
|
@ -3955,6 +3955,7 @@ namespace ts {
|
|||
// Unique symbol types (TypeFlags.UniqueESSymbol)
|
||||
export interface UniqueESSymbolType extends Type {
|
||||
symbol: Symbol;
|
||||
escapedName: __String;
|
||||
}
|
||||
|
||||
export interface StringLiteralType extends LiteralType {
|
||||
|
@ -4062,6 +4063,7 @@ namespace ts {
|
|||
export interface TupleType extends GenericType {
|
||||
minLength: number;
|
||||
hasRestElement: boolean;
|
||||
readonly: boolean;
|
||||
associatedNames?: __String[];
|
||||
}
|
||||
|
||||
|
@ -4339,6 +4341,7 @@ namespace ts {
|
|||
None = 0, // No special inference behaviors
|
||||
NoDefault = 1 << 0, // Infer unknownType for no inferences (otherwise anyType or emptyObjectType)
|
||||
AnyDefault = 1 << 1, // Infer anyType for no inferences (otherwise emptyObjectType)
|
||||
NoFixing = 1 << 2, // Disable type parameter fixing
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4367,6 +4370,7 @@ namespace ts {
|
|||
inferences: InferenceInfo[]; // Inferences made for each type parameter
|
||||
flags: InferenceFlags; // Inference flags
|
||||
compareTypes: TypeComparer; // Type comparer function
|
||||
returnMapper?: TypeMapper; // Type mapper for inferences from return types (if any)
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
|
|
@ -778,7 +778,8 @@ namespace ts {
|
|||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
return escapeLeadingUnderscores(name.text);
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
return isStringOrNumericLiteralLike(name.expression) ? escapeLeadingUnderscores(name.expression.text) : undefined!; // TODO: GH#18217 Almost all uses of this assume the result to be defined!
|
||||
if (isStringOrNumericLiteralLike(name.expression)) return escapeLeadingUnderscores(name.expression.text);
|
||||
return Debug.fail("Text of property name cannot be read from non-literal-valued ComputedPropertyNames");
|
||||
default:
|
||||
return Debug.assertNever(name);
|
||||
}
|
||||
|
@ -5606,6 +5607,11 @@ namespace ts {
|
|||
return node.kind === SyntaxKind.TypeAssertionExpression;
|
||||
}
|
||||
|
||||
export function isConstTypeReference(node: Node) {
|
||||
return isTypeReferenceNode(node) && isIdentifier(node.typeName) &&
|
||||
node.typeName.escapedText === "const" && !node.typeArguments;
|
||||
}
|
||||
|
||||
export function isParenthesizedExpression(node: Node): node is ParenthesizedExpression {
|
||||
return node.kind === SyntaxKind.ParenthesizedExpression;
|
||||
}
|
||||
|
|
|
@ -375,6 +375,15 @@ namespace fakes {
|
|||
}
|
||||
}
|
||||
|
||||
export type ExpectedDiagnostic = [ts.DiagnosticMessage, ...(string | number)[]];
|
||||
function expectedDiagnosticToText([message, ...args]: ExpectedDiagnostic) {
|
||||
let text = ts.getLocaleSpecificMessage(message);
|
||||
if (args.length) {
|
||||
text = ts.formatStringFromArgs(text, args);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
export class SolutionBuilderHost extends CompilerHost implements ts.SolutionBuilderHost<ts.BuilderProgram> {
|
||||
createProgram = ts.createAbstractBuilder;
|
||||
now() {
|
||||
|
@ -395,16 +404,10 @@ namespace fakes {
|
|||
this.diagnostics.length = 0;
|
||||
}
|
||||
|
||||
assertDiagnosticMessages(...expected: ts.DiagnosticMessage[]) {
|
||||
const actual = this.diagnostics.slice();
|
||||
if (actual.length !== expected.length) {
|
||||
assert.fail<any>(actual, expected, `Diagnostic arrays did not match - got\r\n${actual.map(a => " " + a.messageText).join("\r\n")}\r\nexpected\r\n${expected.map(e => " " + e.message).join("\r\n")}`);
|
||||
}
|
||||
for (let i = 0; i < actual.length; i++) {
|
||||
if (actual[i].code !== expected[i].code) {
|
||||
assert.fail(actual[i].messageText, expected[i].message, `Mismatched error code - expected diagnostic ${i} "${actual[i].messageText}" to match ${expected[i].message}`);
|
||||
}
|
||||
}
|
||||
assertDiagnosticMessages(...expectedDiagnostics: ExpectedDiagnostic[]) {
|
||||
const actual = this.diagnostics.slice().map(d => d.messageText as string);
|
||||
const expected = expectedDiagnostics.map(expectedDiagnosticToText);
|
||||
assert.deepEqual(actual, expected, "Diagnostic arrays did not match");
|
||||
}
|
||||
|
||||
printDiagnostics(header = "== Diagnostics ==") {
|
||||
|
|
4
src/lib/es2017.sharedmemory.d.ts
vendored
4
src/lib/es2017.sharedmemory.d.ts
vendored
|
@ -103,7 +103,7 @@ interface Atomics {
|
|||
* Wakes up sleeping agents that are waiting on the given index of the array, returning the
|
||||
* number of agents that were awoken.
|
||||
*/
|
||||
wake(typedArray: Int32Array, index: number, count: number): number;
|
||||
notify(typedArray: Int32Array, index: number, count: number): number;
|
||||
|
||||
/**
|
||||
* Stores the bitwise XOR of a value with the value at the given position in the array,
|
||||
|
@ -115,4 +115,4 @@ interface Atomics {
|
|||
readonly [Symbol.toStringTag]: "Atomics";
|
||||
}
|
||||
|
||||
declare var Atomics: Atomics;
|
||||
declare var Atomics: Atomics;
|
||||
|
|
|
@ -904,7 +904,7 @@ namespace ts.server {
|
|||
|
||||
getPreferences(file: NormalizedPath): protocol.UserPreferences {
|
||||
const info = this.getScriptInfoForNormalizedPath(file);
|
||||
return info && info.getPreferences() || this.hostConfiguration.preferences;
|
||||
return { ...this.hostConfiguration.preferences, ...info && info.getPreferences() };
|
||||
}
|
||||
|
||||
getHostFormatCodeOptions(): FormatCodeSettings {
|
||||
|
|
|
@ -1178,8 +1178,7 @@ namespace ts.server {
|
|||
private getRenameInfo(args: protocol.FileLocationRequestArgs): RenameInfo {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const position = this.getPositionInFile(args, file);
|
||||
const preferences = this.getHostPreferences();
|
||||
return project.getLanguageService().getRenameInfo(file, position, { allowRenameOfImportPath: preferences.allowRenameOfImportPath });
|
||||
return project.getLanguageService().getRenameInfo(file, position, { allowRenameOfImportPath: this.getPreferences(file).allowRenameOfImportPath });
|
||||
}
|
||||
|
||||
private getProjects(args: protocol.FileRequestArgs, getScriptInfoEnsuringProjectsUptoDate?: boolean, ignoreNoProjectError?: boolean): Projects {
|
||||
|
@ -1234,12 +1233,12 @@ namespace ts.server {
|
|||
{ fileName: args.file, pos: position },
|
||||
!!args.findInStrings,
|
||||
!!args.findInComments,
|
||||
this.getHostPreferences()
|
||||
this.getPreferences(file)
|
||||
);
|
||||
if (!simplifiedResult) return locations;
|
||||
|
||||
const defaultProject = this.getDefaultProject(args);
|
||||
const renameInfo: protocol.RenameInfo = this.mapRenameInfo(defaultProject.getLanguageService().getRenameInfo(file, position, { allowRenameOfImportPath: this.getHostPreferences().allowRenameOfImportPath }), Debug.assertDefined(this.projectService.getScriptInfo(file)));
|
||||
const renameInfo: protocol.RenameInfo = this.mapRenameInfo(defaultProject.getLanguageService().getRenameInfo(file, position, { allowRenameOfImportPath: this.getPreferences(file).allowRenameOfImportPath }), Debug.assertDefined(this.projectService.getScriptInfo(file)));
|
||||
return { info: renameInfo, locs: this.toSpanGroups(locations) };
|
||||
}
|
||||
|
||||
|
|
|
@ -274,7 +274,17 @@ namespace ts.codefix {
|
|||
return !!merged;
|
||||
}));
|
||||
const tag = createJSDocComment(comments.join("\n"), createNodeArray([...(oldTags || emptyArray), ...unmergedNewTags]));
|
||||
changes.insertJsdocCommentBefore(sourceFile, parent, tag);
|
||||
const jsDocNode = parent.kind === SyntaxKind.ArrowFunction ? getJsDocNodeForArrowFunction(parent) : parent;
|
||||
jsDocNode.jsDoc = parent.jsDoc;
|
||||
jsDocNode.jsDocCache = parent.jsDocCache;
|
||||
changes.insertJsdocCommentBefore(sourceFile, jsDocNode, tag);
|
||||
}
|
||||
|
||||
function getJsDocNodeForArrowFunction(signature: ArrowFunction): HasJSDoc {
|
||||
if (signature.parent.kind === SyntaxKind.PropertyDeclaration) {
|
||||
return <HasJSDoc>signature.parent;
|
||||
}
|
||||
return <HasJSDoc>signature.parent.parent;
|
||||
}
|
||||
|
||||
function tryMergeJsdocTags(oldTag: JSDocTag, newTag: JSDocTag): JSDocTag | undefined {
|
||||
|
|
|
@ -41,6 +41,7 @@ namespace ts.FindAllReferences {
|
|||
readonly implementations?: boolean;
|
||||
/**
|
||||
* True to opt in for enhanced renaming of shorthand properties and import/export specifiers.
|
||||
* The options controls the behavior for the whole rename operation; it cannot be changed on a per-file basis.
|
||||
* Default is false for backwards compatibility.
|
||||
*/
|
||||
readonly providePrefixAndSuffixTextForRename?: boolean;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../tsconfig-base",
|
||||
"extends": "../tsconfig-noncomposite-base",
|
||||
"compilerOptions": {
|
||||
"outFile": "../../built/local/run.js",
|
||||
"composite": false,
|
||||
|
@ -43,6 +43,7 @@
|
|||
"unittests/asserts.ts",
|
||||
"unittests/base64.ts",
|
||||
"unittests/builder.ts",
|
||||
"unittests/comments.ts",
|
||||
"unittests/compilerCore.ts",
|
||||
"unittests/convertToBase64.ts",
|
||||
"unittests/customTransforms.ts",
|
||||
|
|
32
src/testRunner/unittests/comments.ts
Normal file
32
src/testRunner/unittests/comments.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
namespace ts {
|
||||
describe("comment parsing", () => {
|
||||
const withShebang = `#! node
|
||||
/** comment */
|
||||
// another one
|
||||
;`;
|
||||
const noShebang = `/** comment */
|
||||
// another one
|
||||
;`;
|
||||
const withTrailing = `;/* comment */
|
||||
// another one
|
||||
`;
|
||||
it("skips shebang", () => {
|
||||
const result = getLeadingCommentRanges(withShebang, 0);
|
||||
assert.isDefined(result);
|
||||
assert.strictEqual(result!.length, 2);
|
||||
});
|
||||
|
||||
it("treats all comments at start of file as leading comments", () => {
|
||||
const result = getLeadingCommentRanges(noShebang, 0);
|
||||
assert.isDefined(result);
|
||||
assert.strictEqual(result!.length, 2);
|
||||
});
|
||||
|
||||
it("returns leading comments if position is not 0", () => {
|
||||
const result = getLeadingCommentRanges(withTrailing, 1);
|
||||
assert.isDefined(result);
|
||||
assert.strictEqual(result!.length, 1);
|
||||
assert.strictEqual(result![0].kind, SyntaxKind.SingleLineCommentTrivia);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -400,6 +400,46 @@ namespace Foo {
|
|||
}
|
||||
}).outputText;
|
||||
});
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/24709
|
||||
testBaseline("issue24709", () => {
|
||||
const fs = vfs.createFromFileSystem(Harness.IO, /*caseSensitive*/ true);
|
||||
const transformed = transform(createSourceFile("source.ts", "class X { echo(x: string) { return x; } }", ScriptTarget.ES3), [transformSourceFile]);
|
||||
const transformedSourceFile = transformed.transformed[0];
|
||||
transformed.dispose();
|
||||
const host = new fakes.CompilerHost(fs);
|
||||
host.getSourceFile = () => transformedSourceFile;
|
||||
const program = createProgram(["source.ts"], {
|
||||
target: ScriptTarget.ES3,
|
||||
module: ModuleKind.None,
|
||||
noLib: true
|
||||
}, host);
|
||||
program.emit(transformedSourceFile, (_p, s, b) => host.writeFile("source.js", s, b));
|
||||
return host.readFile("source.js")!.toString();
|
||||
|
||||
function transformSourceFile(context: TransformationContext) {
|
||||
const visitor: Visitor = (node) => {
|
||||
if (isMethodDeclaration(node)) {
|
||||
return updateMethod(
|
||||
node,
|
||||
node.decorators,
|
||||
node.modifiers,
|
||||
node.asteriskToken,
|
||||
createIdentifier("foobar"),
|
||||
node.questionToken,
|
||||
node.typeParameters,
|
||||
node.parameters,
|
||||
node.type,
|
||||
node.body,
|
||||
);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
};
|
||||
return (node: SourceFile) => visitNode(node, visitor);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
namespace ts {
|
||||
let currentTime = 100;
|
||||
|
||||
function getExpectedDiagnosticForProjectsInBuild(...projects: string[]): fakes.ExpectedDiagnostic {
|
||||
return [Diagnostics.Projects_in_this_build_Colon_0, projects.map(p => "\r\n * " + p).join("")];
|
||||
}
|
||||
|
||||
export namespace Sample1 {
|
||||
tick();
|
||||
const projFs = loadProjectFromDisk("tests/projects/sample1");
|
||||
|
@ -67,7 +72,11 @@ namespace ts {
|
|||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], { dry: true, force: false, verbose: false });
|
||||
builder.buildAllProjects();
|
||||
host.assertDiagnosticMessages(Diagnostics.A_non_dry_build_would_build_project_0, Diagnostics.A_non_dry_build_would_build_project_0, Diagnostics.A_non_dry_build_would_build_project_0);
|
||||
host.assertDiagnosticMessages(
|
||||
[Diagnostics.A_non_dry_build_would_build_project_0, "/src/core/tsconfig.json"],
|
||||
[Diagnostics.A_non_dry_build_would_build_project_0, "/src/logic/tsconfig.json"],
|
||||
[Diagnostics.A_non_dry_build_would_build_project_0, "/src/tests/tsconfig.json"]
|
||||
);
|
||||
|
||||
// Check for outputs to not be written. Not an exhaustive list
|
||||
for (const output of allExpectedOutputs) {
|
||||
|
@ -86,7 +95,11 @@ namespace ts {
|
|||
host.clearDiagnostics();
|
||||
builder = createSolutionBuilder(host, ["/src/tests"], { dry: true, force: false, verbose: false });
|
||||
builder.buildAllProjects();
|
||||
host.assertDiagnosticMessages(Diagnostics.Project_0_is_up_to_date, Diagnostics.Project_0_is_up_to_date, Diagnostics.Project_0_is_up_to_date);
|
||||
host.assertDiagnosticMessages(
|
||||
[Diagnostics.Project_0_is_up_to_date, "/src/core/tsconfig.json"],
|
||||
[Diagnostics.Project_0_is_up_to_date, "/src/logic/tsconfig.json"],
|
||||
[Diagnostics.Project_0_is_up_to_date, "/src/tests/tsconfig.json"]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -146,13 +159,15 @@ namespace ts {
|
|||
host.clearDiagnostics();
|
||||
builder.resetBuildContext();
|
||||
builder.buildAllProjects();
|
||||
host.assertDiagnosticMessages(Diagnostics.Projects_in_this_build_Colon_0,
|
||||
Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist,
|
||||
Diagnostics.Building_project_0,
|
||||
Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist,
|
||||
Diagnostics.Building_project_0,
|
||||
Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist,
|
||||
Diagnostics.Building_project_0);
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"],
|
||||
[Diagnostics.Building_project_0, "/src/core/tsconfig.json"],
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/logic/tsconfig.json", "src/logic/index.js"],
|
||||
[Diagnostics.Building_project_0, "/src/logic/tsconfig.json"],
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/tests/tsconfig.json", "src/tests/index.js"],
|
||||
[Diagnostics.Building_project_0, "/src/tests/tsconfig.json"]
|
||||
);
|
||||
tick();
|
||||
});
|
||||
|
||||
|
@ -161,10 +176,12 @@ namespace ts {
|
|||
host.clearDiagnostics();
|
||||
builder.resetBuildContext();
|
||||
builder.buildAllProjects();
|
||||
host.assertDiagnosticMessages(Diagnostics.Projects_in_this_build_Colon_0,
|
||||
Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2,
|
||||
Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2,
|
||||
Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2);
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"),
|
||||
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/core/tsconfig.json", "src/core/anotherModule.ts", "src/core/anotherModule.js"],
|
||||
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/logic/tsconfig.json", "src/logic/index.ts", "src/logic/index.js"],
|
||||
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/tests/tsconfig.json", "src/tests/index.ts", "src/tests/index.js"]
|
||||
);
|
||||
tick();
|
||||
});
|
||||
|
||||
|
@ -175,11 +192,13 @@ namespace ts {
|
|||
builder.resetBuildContext();
|
||||
builder.buildAllProjects();
|
||||
|
||||
host.assertDiagnosticMessages(Diagnostics.Projects_in_this_build_Colon_0,
|
||||
Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2,
|
||||
Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2,
|
||||
Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2,
|
||||
Diagnostics.Building_project_0);
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"),
|
||||
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/core/tsconfig.json", "src/core/anotherModule.ts", "src/core/anotherModule.js"],
|
||||
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/logic/tsconfig.json", "src/logic/index.ts", "src/logic/index.js"],
|
||||
[Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/tests/tsconfig.json", "src/tests/index.js", "src/tests/index.ts"],
|
||||
[Diagnostics.Building_project_0, "/src/tests/tsconfig.json"]
|
||||
);
|
||||
tick();
|
||||
});
|
||||
|
||||
|
@ -190,13 +209,15 @@ namespace ts {
|
|||
builder.resetBuildContext();
|
||||
builder.buildAllProjects();
|
||||
|
||||
host.assertDiagnosticMessages(Diagnostics.Projects_in_this_build_Colon_0,
|
||||
Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2,
|
||||
Diagnostics.Building_project_0,
|
||||
Diagnostics.Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies,
|
||||
Diagnostics.Updating_output_timestamps_of_project_0,
|
||||
Diagnostics.Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies,
|
||||
Diagnostics.Updating_output_timestamps_of_project_0);
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/core/tsconfig.json", "src/core/anotherModule.js", "src/core/index.ts"],
|
||||
[Diagnostics.Building_project_0, "/src/core/tsconfig.json"],
|
||||
[Diagnostics.Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies, "src/logic/tsconfig.json"],
|
||||
[Diagnostics.Updating_output_timestamps_of_project_0, "/src/logic/tsconfig.json"],
|
||||
[Diagnostics.Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies, "src/tests/tsconfig.json"],
|
||||
[Diagnostics.Updating_output_timestamps_of_project_0, "/src/tests/tsconfig.json"]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -210,14 +231,14 @@ namespace ts {
|
|||
replaceText(fs, "/src/logic/index.ts", "c.multiply(10, 15)", `c.muitply()`);
|
||||
builder.buildAllProjects();
|
||||
host.assertDiagnosticMessages(
|
||||
Diagnostics.Projects_in_this_build_Colon_0,
|
||||
Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist,
|
||||
Diagnostics.Building_project_0,
|
||||
Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist,
|
||||
Diagnostics.Building_project_0,
|
||||
Diagnostics.Property_0_does_not_exist_on_type_1,
|
||||
Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors,
|
||||
Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors
|
||||
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"],
|
||||
[Diagnostics.Building_project_0, "/src/core/tsconfig.json"],
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/logic/tsconfig.json", "src/logic/index.js"],
|
||||
[Diagnostics.Building_project_0, "/src/logic/tsconfig.json"],
|
||||
[Diagnostics.Property_0_does_not_exist_on_type_1, "muitply", `typeof import("/src/core/index")`],
|
||||
[Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors, "src/tests/tsconfig.json", "src/logic"],
|
||||
[Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, "/src/tests/tsconfig.json", "/src/logic"]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -281,12 +302,12 @@ export class cNew {}`);
|
|||
const projFs = loadProjectFromDisk("tests/projects/resolveJsonModuleAndComposite");
|
||||
const allExpectedOutputs = ["/src/tests/dist/src/index.js", "/src/tests/dist/src/index.d.ts", "/src/tests/dist/src/hello.json"];
|
||||
|
||||
function verifyProjectWithResolveJsonModule(configFile: string, ...expectedDiagnosticMessages: DiagnosticMessage[]) {
|
||||
function verifyProjectWithResolveJsonModule(configFile: string, ...expectedDiagnosticMessages: fakes.ExpectedDiagnostic[]) {
|
||||
const fs = projFs.shadow();
|
||||
verifyProjectWithResolveJsonModuleWithFs(fs, configFile, allExpectedOutputs, ...expectedDiagnosticMessages);
|
||||
}
|
||||
|
||||
function verifyProjectWithResolveJsonModuleWithFs(fs: vfs.FileSystem, configFile: string, allExpectedOutputs: ReadonlyArray<string>, ...expectedDiagnosticMessages: DiagnosticMessage[]) {
|
||||
function verifyProjectWithResolveJsonModuleWithFs(fs: vfs.FileSystem, configFile: string, allExpectedOutputs: ReadonlyArray<string>, ...expectedDiagnosticMessages: fakes.ExpectedDiagnostic[]) {
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, [configFile], { dry: false, force: false, verbose: false });
|
||||
builder.buildAllProjects();
|
||||
|
@ -300,7 +321,10 @@ export class cNew {}`);
|
|||
}
|
||||
|
||||
it("with resolveJsonModule and include only", () => {
|
||||
verifyProjectWithResolveJsonModule("/src/tests/tsconfig_withInclude.json", Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern);
|
||||
verifyProjectWithResolveJsonModule("/src/tests/tsconfig_withInclude.json", [
|
||||
Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern,
|
||||
"/src/tests/src/hello.json"
|
||||
]);
|
||||
});
|
||||
|
||||
it("with resolveJsonModule and include of *.json along with other include", () => {
|
||||
|
@ -415,7 +439,7 @@ export default hello.hello`);
|
|||
"/src/c.ts"
|
||||
];
|
||||
|
||||
function verifyBuild(modifyDiskLayout: (fs: vfs.FileSystem) => void, allExpectedOutputs: ReadonlyArray<string>, expectedDiagnostics: DiagnosticMessage[], expectedFileTraces: ReadonlyArray<string>) {
|
||||
function verifyBuild(modifyDiskLayout: (fs: vfs.FileSystem) => void, allExpectedOutputs: ReadonlyArray<string>, expectedFileTraces: ReadonlyArray<string>, ...expectedDiagnostics: fakes.ExpectedDiagnostic[]) {
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
modifyDiskLayout(fs);
|
||||
|
@ -442,11 +466,11 @@ export const b = new A();`);
|
|||
}
|
||||
|
||||
it("verify that it builds correctly", () => {
|
||||
verifyBuild(noop, allExpectedOutputs, emptyArray, expectedFileTraces);
|
||||
verifyBuild(noop, allExpectedOutputs, expectedFileTraces);
|
||||
});
|
||||
|
||||
it("verify that it builds correctly when the referenced project uses different module resolution", () => {
|
||||
verifyBuild(fs => modifyFsBTsToNonRelativeImport(fs, "classic"), allExpectedOutputs, emptyArray, expectedFileTraces);
|
||||
verifyBuild(fs => modifyFsBTsToNonRelativeImport(fs, "classic"), allExpectedOutputs, expectedFileTraces);
|
||||
});
|
||||
|
||||
it("verify that it build reports error about module not found with node resolution with external module name", () => {
|
||||
|
@ -458,10 +482,25 @@ export const b = new A();`);
|
|||
];
|
||||
verifyBuild(fs => modifyFsBTsToNonRelativeImport(fs, "node"),
|
||||
allExpectedOutputs,
|
||||
[Diagnostics.Cannot_find_module_0],
|
||||
expectedFileTraces);
|
||||
expectedFileTraces,
|
||||
[Diagnostics.Cannot_find_module_0, "a"],
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("unittests:: tsbuild - when tsconfig extends the missing file", () => {
|
||||
const projFs = loadProjectFromDisk("tests/projects/missingExtendedConfig");
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tsconfig.json"], {});
|
||||
builder.buildAllProjects();
|
||||
host.assertDiagnosticMessages(
|
||||
[Diagnostics.The_specified_path_does_not_exist_Colon_0, "/src/foobar.json"],
|
||||
[Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, "/src/tsconfig.first.json", "[\"**/*\"]", "[]"],
|
||||
[Diagnostics.The_specified_path_does_not_exist_Colon_0, "/src/foobar.json"],
|
||||
[Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, "/src/tsconfig.second.json", "[\"**/*\"]", "[]"]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export namespace OutFile {
|
||||
|
@ -564,7 +603,7 @@ export const b = new A();`);
|
|||
|
||||
host.clearDiagnostics();
|
||||
builder.buildAllProjects();
|
||||
host.assertDiagnosticMessages(Diagnostics.The_files_list_in_config_file_0_is_empty);
|
||||
host.assertDiagnosticMessages([Diagnostics.The_files_list_in_config_file_0_is_empty, "/src/no-references/tsconfig.json"]);
|
||||
|
||||
// Check for outputs to not be written.
|
||||
for (const output of allExpectedOutputs) {
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace ts.projectSystem {
|
|||
const session = createSession(createServerHost([aTs, bTs]));
|
||||
openFilesForSession([bTs], session);
|
||||
|
||||
// rename fails with allowRenameOfImportPath disabled
|
||||
const response1 = executeSessionRequest<protocol.RenameRequest, protocol.RenameResponse>(session, protocol.CommandTypes.Rename, protocolFileLocationFromSubstring(bTs, 'a";'));
|
||||
assert.deepEqual<protocol.RenameResponseBody | undefined>(response1, {
|
||||
info: {
|
||||
|
@ -16,6 +17,7 @@ namespace ts.projectSystem {
|
|||
locs: [{ file: bTs.path, locs: [protocolRenameSpanFromSubstring(bTs.content, "./a")] }],
|
||||
});
|
||||
|
||||
// rename succeeds with allowRenameOfImportPath enabled in host
|
||||
session.getProjectService().setHostConfiguration({ preferences: { allowRenameOfImportPath: true } });
|
||||
const response2 = executeSessionRequest<protocol.RenameRequest, protocol.RenameResponse>(session, protocol.CommandTypes.Rename, protocolFileLocationFromSubstring(bTs, 'a";'));
|
||||
assert.deepEqual<protocol.RenameResponseBody | undefined>(response2, {
|
||||
|
@ -30,6 +32,23 @@ namespace ts.projectSystem {
|
|||
},
|
||||
locs: [{ file: bTs.path, locs: [protocolRenameSpanFromSubstring(bTs.content, "./a")] }],
|
||||
});
|
||||
|
||||
// rename succeeds with allowRenameOfImportPath enabled in file
|
||||
session.getProjectService().setHostConfiguration({ preferences: { allowRenameOfImportPath: false } });
|
||||
session.getProjectService().setHostConfiguration({ file: "/b.ts", formatOptions: {}, preferences: { allowRenameOfImportPath: true } });
|
||||
const response3 = executeSessionRequest<protocol.RenameRequest, protocol.RenameResponse>(session, protocol.CommandTypes.Rename, protocolFileLocationFromSubstring(bTs, 'a";'));
|
||||
assert.deepEqual<protocol.RenameResponseBody | undefined>(response3, {
|
||||
info: {
|
||||
canRename: true,
|
||||
fileToRename: aTs.path,
|
||||
displayName: aTs.path,
|
||||
fullDisplayName: aTs.path,
|
||||
kind: ScriptElementKind.moduleElement,
|
||||
kindModifiers: "",
|
||||
triggerSpan: protocolTextSpanFromSubstring(bTs.content, "a", { index: 1 }),
|
||||
},
|
||||
locs: [{ file: bTs.path, locs: [protocolRenameSpanFromSubstring(bTs.content, "./a")] }],
|
||||
});
|
||||
});
|
||||
|
||||
it("works with prefixText and suffixText when enabled", () => {
|
||||
|
@ -61,7 +80,7 @@ namespace ts.projectSystem {
|
|||
],
|
||||
});
|
||||
|
||||
// rename with prefixText and suffixText enabled
|
||||
// rename with prefixText and suffixText enabled in host
|
||||
session.getProjectService().setHostConfiguration({ preferences: { providePrefixAndSuffixTextForRename: true } });
|
||||
const response2 = executeSessionRequest<protocol.RenameRequest, protocol.RenameResponse>(session, protocol.CommandTypes.Rename, protocolFileLocationFromSubstring(aTs, "x"));
|
||||
assert.deepEqual<protocol.RenameResponseBody | undefined>(response2, {
|
||||
|
@ -84,6 +103,93 @@ namespace ts.projectSystem {
|
|||
},
|
||||
],
|
||||
});
|
||||
|
||||
// rename with prefixText and suffixText enabled for file
|
||||
session.getProjectService().setHostConfiguration({ preferences: { providePrefixAndSuffixTextForRename: false } });
|
||||
session.getProjectService().setHostConfiguration({ file: "/a.ts", formatOptions: {}, preferences: { providePrefixAndSuffixTextForRename: true } });
|
||||
const response3 = executeSessionRequest<protocol.RenameRequest, protocol.RenameResponse>(session, protocol.CommandTypes.Rename, protocolFileLocationFromSubstring(aTs, "x"));
|
||||
assert.deepEqual<protocol.RenameResponseBody | undefined>(response3, {
|
||||
info: {
|
||||
canRename: true,
|
||||
fileToRename: undefined,
|
||||
displayName: "x",
|
||||
fullDisplayName: "x",
|
||||
kind: ScriptElementKind.constElement,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
triggerSpan: protocolTextSpanFromSubstring(aTs.content, "x"),
|
||||
},
|
||||
locs: [
|
||||
{
|
||||
file: aTs.path,
|
||||
locs: [
|
||||
protocolRenameSpanFromSubstring(aTs.content, "x"),
|
||||
protocolRenameSpanFromSubstring(aTs.content, "x", { index: 1 }, { prefixText: "x: " }),
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it("rename behavior is based on file of rename initiation", () => {
|
||||
const aTs: File = { path: "/a.ts", content: "const x = 1; export { x };" };
|
||||
const bTs: File = { path: "/b.ts", content: `import { x } from "./a"; const y = x + 1;` };
|
||||
const host = createServerHost([aTs, bTs]);
|
||||
const session = createSession(host);
|
||||
openFilesForSession([aTs, bTs], session);
|
||||
|
||||
// rename from file with prefixText and suffixText enabled
|
||||
session.getProjectService().setHostConfiguration({ file: "/a.ts", formatOptions: {}, preferences: { providePrefixAndSuffixTextForRename: true } });
|
||||
const response1 = executeSessionRequest<protocol.RenameRequest, protocol.RenameResponse>(session, protocol.CommandTypes.Rename, protocolFileLocationFromSubstring(aTs, "x"));
|
||||
assert.deepEqual<protocol.RenameResponseBody | undefined>(response1, {
|
||||
info: {
|
||||
canRename: true,
|
||||
fileToRename: undefined,
|
||||
displayName: "x",
|
||||
fullDisplayName: "x",
|
||||
kind: ScriptElementKind.constElement,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
triggerSpan: protocolTextSpanFromSubstring(aTs.content, "x"),
|
||||
},
|
||||
locs: [
|
||||
{
|
||||
file: aTs.path,
|
||||
locs: [
|
||||
protocolRenameSpanFromSubstring(aTs.content, "x"),
|
||||
protocolRenameSpanFromSubstring(aTs.content, "x", { index: 2 }, { suffixText: " as x" }),
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// rename from file with prefixText and suffixText disabled
|
||||
const response2 = executeSessionRequest<protocol.RenameRequest, protocol.RenameResponse>(session, protocol.CommandTypes.Rename, protocolFileLocationFromSubstring(bTs, "x"));
|
||||
assert.deepEqual<protocol.RenameResponseBody | undefined>(response2, {
|
||||
info: {
|
||||
canRename: true,
|
||||
fileToRename: undefined,
|
||||
displayName: "x",
|
||||
fullDisplayName: "x",
|
||||
kind: ScriptElementKind.alias,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
triggerSpan: protocolTextSpanFromSubstring(bTs.content, "x"),
|
||||
},
|
||||
locs: [
|
||||
{
|
||||
file: bTs.path,
|
||||
locs: [
|
||||
protocolRenameSpanFromSubstring(bTs.content, "x"),
|
||||
protocolRenameSpanFromSubstring(bTs.content, "x", { index: 1 })
|
||||
]
|
||||
},
|
||||
{
|
||||
file: aTs.path,
|
||||
locs: [
|
||||
protocolRenameSpanFromSubstring(aTs.content, "x"),
|
||||
protocolRenameSpanFromSubstring(aTs.content, "x", { index: 2 }),
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../tsconfig-base",
|
||||
"extends": "../tsconfig-noncomposite-base",
|
||||
"compilerOptions": {
|
||||
"outFile": "../../built/local/tsc.js"
|
||||
},
|
||||
|
|
8
src/tsconfig-noncomposite-base.json
Normal file
8
src/tsconfig-noncomposite-base.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"extends": "./tsconfig-base",
|
||||
"compilerOptions": {
|
||||
"declaration": false,
|
||||
"declarationMap": false,
|
||||
"composite": false
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../tsconfig-base",
|
||||
"extends": "../tsconfig-noncomposite-base",
|
||||
|
||||
"compilerOptions": {
|
||||
"outFile": "../../built/local/tsserver.js",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../tsconfig-base",
|
||||
"extends": "../tsconfig-noncomposite-base",
|
||||
"compilerOptions": {
|
||||
"removeComments": true,
|
||||
"outFile": "../../built/local/typingsInstaller.js",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../tsconfig-base",
|
||||
"extends": "../tsconfig-noncomposite-base",
|
||||
"compilerOptions": {
|
||||
"removeComments": true,
|
||||
"outFile": "../../built/local/watchGuard.js",
|
||||
|
@ -13,4 +13,4 @@
|
|||
"files": [
|
||||
"watchGuard.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
tests/cases/compiler/anonymousModules.ts(1,1): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.
|
||||
tests/cases/compiler/anonymousModules.ts(1,1): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`.
|
||||
tests/cases/compiler/anonymousModules.ts(1,8): error TS1005: ';' expected.
|
||||
tests/cases/compiler/anonymousModules.ts(4,2): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.
|
||||
tests/cases/compiler/anonymousModules.ts(4,2): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`.
|
||||
tests/cases/compiler/anonymousModules.ts(4,9): error TS1005: ';' expected.
|
||||
tests/cases/compiler/anonymousModules.ts(10,2): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.
|
||||
tests/cases/compiler/anonymousModules.ts(10,2): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`.
|
||||
tests/cases/compiler/anonymousModules.ts(10,9): error TS1005: ';' expected.
|
||||
|
||||
|
||||
==== tests/cases/compiler/anonymousModules.ts (6 errors) ====
|
||||
module {
|
||||
~~~~~~
|
||||
!!! error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.
|
||||
!!! error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`.
|
||||
~
|
||||
!!! error TS1005: ';' expected.
|
||||
export var foo = 1;
|
||||
|
||||
module {
|
||||
~~~~~~
|
||||
!!! error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.
|
||||
!!! error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`.
|
||||
~
|
||||
!!! error TS1005: ';' expected.
|
||||
export var bar = 1;
|
||||
|
@ -26,7 +26,7 @@ tests/cases/compiler/anonymousModules.ts(10,9): error TS1005: ';' expected.
|
|||
|
||||
module {
|
||||
~~~~~~
|
||||
!!! error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.
|
||||
!!! error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`.
|
||||
~
|
||||
!!! error TS1005: ';' expected.
|
||||
var x = bar;
|
||||
|
|
|
@ -14,7 +14,7 @@ and limitations under the License.
|
|||
***************************************************************************** */
|
||||
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "3.3";
|
||||
const versionMajorMinor = "3.4";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
|
@ -814,7 +814,7 @@ declare namespace ts {
|
|||
}
|
||||
interface TypeOperatorNode extends TypeNode {
|
||||
kind: SyntaxKind.TypeOperator;
|
||||
operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword;
|
||||
operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword;
|
||||
type: TypeNode;
|
||||
}
|
||||
interface IndexedAccessTypeNode extends TypeNode {
|
||||
|
@ -2217,6 +2217,7 @@ declare namespace ts {
|
|||
}
|
||||
interface UniqueESSymbolType extends Type {
|
||||
symbol: Symbol;
|
||||
escapedName: __String;
|
||||
}
|
||||
interface StringLiteralType extends LiteralType {
|
||||
value: string;
|
||||
|
@ -2285,6 +2286,7 @@ declare namespace ts {
|
|||
interface TupleType extends GenericType {
|
||||
minLength: number;
|
||||
hasRestElement: boolean;
|
||||
readonly: boolean;
|
||||
associatedNames?: __String[];
|
||||
}
|
||||
interface TupleTypeReference extends TypeReference {
|
||||
|
@ -3358,6 +3360,7 @@ declare namespace ts {
|
|||
function isNewExpression(node: Node): node is NewExpression;
|
||||
function isTaggedTemplateExpression(node: Node): node is TaggedTemplateExpression;
|
||||
function isTypeAssertion(node: Node): node is TypeAssertion;
|
||||
function isConstTypeReference(node: Node): boolean;
|
||||
function isParenthesizedExpression(node: Node): node is ParenthesizedExpression;
|
||||
function skipPartiallyEmittedExpressions(node: Expression): Expression;
|
||||
function skipPartiallyEmittedExpressions(node: Node): Node;
|
||||
|
@ -3758,7 +3761,7 @@ declare namespace ts {
|
|||
function updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode;
|
||||
function createThisTypeNode(): ThisTypeNode;
|
||||
function createTypeOperatorNode(type: TypeNode): TypeOperatorNode;
|
||||
function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword, type: TypeNode): TypeOperatorNode;
|
||||
function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode;
|
||||
function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode;
|
||||
function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
|
||||
function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
|
||||
|
@ -8343,7 +8346,7 @@ declare namespace ts.server {
|
|||
excludedFiles: ReadonlyArray<NormalizedPath>;
|
||||
private typeAcquisition;
|
||||
updateGraph(): boolean;
|
||||
getExcludedFiles(): ReadonlyArray<NormalizedPath>;
|
||||
getExcludedFiles(): readonly NormalizedPath[];
|
||||
getTypeAcquisition(): TypeAcquisition;
|
||||
setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ and limitations under the License.
|
|||
***************************************************************************** */
|
||||
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "3.3";
|
||||
const versionMajorMinor = "3.4";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
|
@ -814,7 +814,7 @@ declare namespace ts {
|
|||
}
|
||||
interface TypeOperatorNode extends TypeNode {
|
||||
kind: SyntaxKind.TypeOperator;
|
||||
operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword;
|
||||
operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword;
|
||||
type: TypeNode;
|
||||
}
|
||||
interface IndexedAccessTypeNode extends TypeNode {
|
||||
|
@ -2217,6 +2217,7 @@ declare namespace ts {
|
|||
}
|
||||
interface UniqueESSymbolType extends Type {
|
||||
symbol: Symbol;
|
||||
escapedName: __String;
|
||||
}
|
||||
interface StringLiteralType extends LiteralType {
|
||||
value: string;
|
||||
|
@ -2285,6 +2286,7 @@ declare namespace ts {
|
|||
interface TupleType extends GenericType {
|
||||
minLength: number;
|
||||
hasRestElement: boolean;
|
||||
readonly: boolean;
|
||||
associatedNames?: __String[];
|
||||
}
|
||||
interface TupleTypeReference extends TypeReference {
|
||||
|
@ -3358,6 +3360,7 @@ declare namespace ts {
|
|||
function isNewExpression(node: Node): node is NewExpression;
|
||||
function isTaggedTemplateExpression(node: Node): node is TaggedTemplateExpression;
|
||||
function isTypeAssertion(node: Node): node is TypeAssertion;
|
||||
function isConstTypeReference(node: Node): boolean;
|
||||
function isParenthesizedExpression(node: Node): node is ParenthesizedExpression;
|
||||
function skipPartiallyEmittedExpressions(node: Expression): Expression;
|
||||
function skipPartiallyEmittedExpressions(node: Node): Node;
|
||||
|
@ -3758,7 +3761,7 @@ declare namespace ts {
|
|||
function updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode;
|
||||
function createThisTypeNode(): ThisTypeNode;
|
||||
function createTypeOperatorNode(type: TypeNode): TypeOperatorNode;
|
||||
function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword, type: TypeNode): TypeOperatorNode;
|
||||
function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode;
|
||||
function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode;
|
||||
function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
|
||||
function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
|
||||
|
|
|
@ -30,15 +30,15 @@ const foundNumber: number | undefined = arrayOfStringsNumbersAndBooleans.find(is
|
|||
>isNumber : (x: any) => x is number
|
||||
|
||||
const readonlyArrayOfStringsNumbersAndBooleans = arrayOfStringsNumbersAndBooleans as ReadonlyArray<string | number | boolean>;
|
||||
>readonlyArrayOfStringsNumbersAndBooleans : ReadonlyArray<string | number | boolean>
|
||||
>arrayOfStringsNumbersAndBooleans as ReadonlyArray<string | number | boolean> : ReadonlyArray<string | number | boolean>
|
||||
>readonlyArrayOfStringsNumbersAndBooleans : readonly (string | number | boolean)[]
|
||||
>arrayOfStringsNumbersAndBooleans as ReadonlyArray<string | number | boolean> : readonly (string | number | boolean)[]
|
||||
>arrayOfStringsNumbersAndBooleans : (string | number | boolean)[]
|
||||
|
||||
const readonlyFoundNumber: number | undefined = readonlyArrayOfStringsNumbersAndBooleans.find(isNumber);
|
||||
>readonlyFoundNumber : number
|
||||
>readonlyArrayOfStringsNumbersAndBooleans.find(isNumber) : number
|
||||
>readonlyArrayOfStringsNumbersAndBooleans.find : { <S extends string | number | boolean>(predicate: (this: void, value: string | number | boolean, index: number, obj: ReadonlyArray<string | number | boolean>) => value is S, thisArg?: any): S; (predicate: (value: string | number | boolean, index: number, obj: ReadonlyArray<string | number | boolean>) => boolean, thisArg?: any): string | number | boolean; }
|
||||
>readonlyArrayOfStringsNumbersAndBooleans : ReadonlyArray<string | number | boolean>
|
||||
>find : { <S extends string | number | boolean>(predicate: (this: void, value: string | number | boolean, index: number, obj: ReadonlyArray<string | number | boolean>) => value is S, thisArg?: any): S; (predicate: (value: string | number | boolean, index: number, obj: ReadonlyArray<string | number | boolean>) => boolean, thisArg?: any): string | number | boolean; }
|
||||
>readonlyArrayOfStringsNumbersAndBooleans.find : { <S extends string | number | boolean>(predicate: (this: void, value: string | number | boolean, index: number, obj: readonly (string | number | boolean)[]) => value is S, thisArg?: any): S; (predicate: (value: string | number | boolean, index: number, obj: readonly (string | number | boolean)[]) => boolean, thisArg?: any): string | number | boolean; }
|
||||
>readonlyArrayOfStringsNumbersAndBooleans : readonly (string | number | boolean)[]
|
||||
>find : { <S extends string | number | boolean>(predicate: (this: void, value: string | number | boolean, index: number, obj: readonly (string | number | boolean)[]) => value is S, thisArg?: any): S; (predicate: (value: string | number | boolean, index: number, obj: readonly (string | number | boolean)[]) => boolean, thisArg?: any): string | number | boolean; }
|
||||
>isNumber : (x: any) => x is number
|
||||
|
||||
|
|
|
@ -4,22 +4,22 @@ const array: number[] = [];
|
|||
>[] : undefined[]
|
||||
|
||||
const readonlyArray: ReadonlyArray<number> = [];
|
||||
>readonlyArray : ReadonlyArray<number>
|
||||
>readonlyArray : readonly number[]
|
||||
>[] : undefined[]
|
||||
|
||||
array.flatMap((): ReadonlyArray<number> => []); // ok
|
||||
>array.flatMap((): ReadonlyArray<number> => []) : number[]
|
||||
>array.flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | ReadonlyArray<U>, thisArg?: This) => U[]
|
||||
>array.flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | readonly U[], thisArg?: This) => U[]
|
||||
>array : number[]
|
||||
>flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | ReadonlyArray<U>, thisArg?: This) => U[]
|
||||
>(): ReadonlyArray<number> => [] : () => ReadonlyArray<number>
|
||||
>flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | readonly U[], thisArg?: This) => U[]
|
||||
>(): ReadonlyArray<number> => [] : () => readonly number[]
|
||||
>[] : undefined[]
|
||||
|
||||
readonlyArray.flatMap((): ReadonlyArray<number> => []); // ok
|
||||
>readonlyArray.flatMap((): ReadonlyArray<number> => []) : number[]
|
||||
>readonlyArray.flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | ReadonlyArray<U>, thisArg?: This) => U[]
|
||||
>readonlyArray : ReadonlyArray<number>
|
||||
>flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | ReadonlyArray<U>, thisArg?: This) => U[]
|
||||
>(): ReadonlyArray<number> => [] : () => ReadonlyArray<number>
|
||||
>readonlyArray.flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | readonly U[], thisArg?: This) => U[]
|
||||
>readonlyArray : readonly number[]
|
||||
>flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | readonly U[], thisArg?: This) => U[]
|
||||
>(): ReadonlyArray<number> => [] : () => readonly number[]
|
||||
>[] : undefined[]
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(13,1): error TS2322: Type 'A[]' is not assignable to type 'ReadonlyArray<B>'.
|
||||
tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(13,1): error TS2322: Type 'A[]' is not assignable to type 'readonly B[]'.
|
||||
Property 'b' is missing in type 'A' but required in type 'B'.
|
||||
tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error TS2322: Type 'C<A>' is not assignable to type 'ReadonlyArray<B>'.
|
||||
tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error TS2322: Type 'C<A>' is not assignable to type 'readonly B[]'.
|
||||
Types of property 'concat' are incompatible.
|
||||
Type '{ (...items: ConcatArray<A>[]): A[]; (...items: (A | ConcatArray<A>)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray<B>[]): B[]; (...items: (B | ConcatArray<B>)[]): B[]; }'.
|
||||
Type 'A[]' is not assignable to type 'B[]'.
|
||||
|
@ -22,7 +22,7 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error T
|
|||
rra = arb;
|
||||
rrb = ara; // error: 'A' is not assignable to 'B'
|
||||
~~~
|
||||
!!! error TS2322: Type 'A[]' is not assignable to type 'ReadonlyArray<B>'.
|
||||
!!! error TS2322: Type 'A[]' is not assignable to type 'readonly B[]'.
|
||||
!!! error TS2322: Property 'b' is missing in type 'A' but required in type 'B'.
|
||||
!!! related TS2728 tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts:2:21: 'b' is declared here.
|
||||
|
||||
|
@ -31,7 +31,7 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error T
|
|||
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: Type 'C<A>' is not assignable to type 'readonly B[]'.
|
||||
!!! error TS2322: Types of property 'concat' are incompatible.
|
||||
!!! error TS2322: Type '{ (...items: ConcatArray<A>[]): A[]; (...items: (A | ConcatArray<A>)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray<B>[]): B[]; (...items: (B | ConcatArray<B>)[]): B[]; }'.
|
||||
!!! error TS2322: Type 'A[]' is not assignable to type 'B[]'.
|
||||
|
|
|
@ -26,48 +26,48 @@ declare var crb: C<B>;
|
|||
>crb : C<B>
|
||||
|
||||
declare var rra: ReadonlyArray<A>;
|
||||
>rra : ReadonlyArray<A>
|
||||
>rra : readonly A[]
|
||||
|
||||
declare var rrb: ReadonlyArray<B>;
|
||||
>rrb : ReadonlyArray<B>
|
||||
>rrb : readonly B[]
|
||||
|
||||
rra = ara;
|
||||
>rra = ara : A[]
|
||||
>rra : ReadonlyArray<A>
|
||||
>rra : readonly A[]
|
||||
>ara : A[]
|
||||
|
||||
rrb = arb; // OK, Array<B> is assignable to ReadonlyArray<A>
|
||||
>rrb = arb : B[]
|
||||
>rrb : ReadonlyArray<B>
|
||||
>rrb : readonly B[]
|
||||
>arb : B[]
|
||||
|
||||
rra = arb;
|
||||
>rra = arb : B[]
|
||||
>rra : ReadonlyArray<A>
|
||||
>rra : readonly A[]
|
||||
>arb : B[]
|
||||
|
||||
rrb = ara; // error: 'A' is not assignable to 'B'
|
||||
>rrb = ara : A[]
|
||||
>rrb : ReadonlyArray<B>
|
||||
>rrb : readonly B[]
|
||||
>ara : A[]
|
||||
|
||||
rra = cra;
|
||||
>rra = cra : C<A>
|
||||
>rra : ReadonlyArray<A>
|
||||
>rra : readonly A[]
|
||||
>cra : C<A>
|
||||
|
||||
rra = crb; // OK, C<B> is assignable to ReadonlyArray<A>
|
||||
>rra = crb : C<B>
|
||||
>rra : ReadonlyArray<A>
|
||||
>rra : readonly A[]
|
||||
>crb : C<B>
|
||||
|
||||
rrb = crb;
|
||||
>rrb = crb : C<B>
|
||||
>rrb : ReadonlyArray<B>
|
||||
>rrb : readonly B[]
|
||||
>crb : C<B>
|
||||
|
||||
rrb = cra; // error: 'A' is not assignable to 'B'
|
||||
>rrb = cra : C<A>
|
||||
>rrb : ReadonlyArray<B>
|
||||
>rrb : readonly B[]
|
||||
>cra : C<A>
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
interface Array<T> {
|
||||
equalsShallow<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>): boolean;
|
||||
>equalsShallow : <T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean
|
||||
>this : ReadonlyArray<T>
|
||||
>other : ReadonlyArray<T>
|
||||
>equalsShallow : <T>(this: readonly T[], other: readonly T[]) => boolean
|
||||
>this : readonly T[]
|
||||
>other : readonly T[]
|
||||
}
|
||||
|
||||
declare const a: (string | number)[] | null[] | undefined[] | {}[];
|
||||
|
@ -19,8 +19,8 @@ declare const b: (string | number)[] | null[] | undefined[] | {}[];
|
|||
let x = a.equalsShallow(b);
|
||||
>x : boolean
|
||||
>a.equalsShallow(b) : boolean
|
||||
>a.equalsShallow : (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean)
|
||||
>a.equalsShallow : (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean)
|
||||
>a : (string | number)[] | null[] | undefined[] | {}[]
|
||||
>equalsShallow : (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean)
|
||||
>equalsShallow : (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean)
|
||||
>b : (string | number)[] | null[] | undefined[] | {}[]
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
Object.freeze({
|
||||
>Object.freeze({ foo() { return Object.freeze('a'); },}) : Readonly<{ foo(): string; }>
|
||||
>Object.freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
|
||||
>Object.freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
|
||||
>Object : ObjectConstructor
|
||||
>freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
|
||||
>freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
|
||||
>{ foo() { return Object.freeze('a'); },} : { foo(): string; }
|
||||
|
||||
foo() {
|
||||
|
@ -13,9 +13,9 @@ Object.freeze({
|
|||
|
||||
return Object.freeze('a');
|
||||
>Object.freeze('a') : string
|
||||
>Object.freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
|
||||
>Object.freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
|
||||
>Object : ObjectConstructor
|
||||
>freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
|
||||
>freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
|
||||
>'a' : "a"
|
||||
|
||||
},
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
tests/cases/conformance/salsa/bug24934.js(2,1): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.
|
||||
tests/cases/conformance/salsa/bug24934.js(2,1): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`.
|
||||
|
||||
|
||||
==== tests/cases/conformance/salsa/bug24934.js (1 errors) ====
|
||||
export function abc(a, b, c) { return 5; }
|
||||
module.exports = { abc };
|
||||
~~~~~~
|
||||
!!! error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.
|
||||
!!! error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`.
|
||||
==== tests/cases/conformance/salsa/use.js (0 errors) ====
|
||||
import { abc } from './bug24934';
|
||||
abc(1, 2, 3);
|
||||
|
|
79
tests/baselines/reference/constAssertions.errors.txt
Normal file
79
tests/baselines/reference/constAssertions.errors.txt
Normal file
|
@ -0,0 +1,79 @@
|
|||
tests/cases/conformance/expressions/typeAssertions/constAssertions.ts(44,32): error TS2540: Cannot assign to 'x' because it is a read-only property.
|
||||
tests/cases/conformance/expressions/typeAssertions/constAssertions.ts(61,10): error TS1355: A 'const' assertion can only be applied to a string, number, boolean, array, or object literal.
|
||||
tests/cases/conformance/expressions/typeAssertions/constAssertions.ts(62,10): error TS1355: A 'const' assertion can only be applied to a string, number, boolean, array, or object literal.
|
||||
tests/cases/conformance/expressions/typeAssertions/constAssertions.ts(63,10): error TS1355: A 'const' assertion can only be applied to a string, number, boolean, array, or object literal.
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/typeAssertions/constAssertions.ts (4 errors) ====
|
||||
let v1 = 'abc' as const;
|
||||
let v2 = `abc` as const;
|
||||
let v3 = 10 as const;
|
||||
let v4 = -10 as const;
|
||||
let v5 = +10 as const;
|
||||
let v6 = 10n as const;
|
||||
let v7 = -10n as const;
|
||||
let v8 = true as const;
|
||||
let v9 = false as const;
|
||||
|
||||
let c1 = 'abc' as const;
|
||||
let c2 = `abc` as const;
|
||||
let c3 = 10 as const;
|
||||
let c4 = -10 as const;
|
||||
let c5 = +10 as const;
|
||||
let c6 = 10n as const;
|
||||
let c7 = -10n as const;
|
||||
let c8 = true as const;
|
||||
let c9 = false as const;
|
||||
|
||||
let vv1 = v1;
|
||||
let vc1 = c1;
|
||||
|
||||
let a1 = [] as const;
|
||||
let a2 = [1, 2, 3] as const;
|
||||
let a3 = [10, 'hello', true] as const;
|
||||
let a4 = [...[1, 2, 3]] as const;
|
||||
let a5 = [1, 2, 3];
|
||||
let a6 = [...a5] as const;
|
||||
let a7 = [...a6];
|
||||
let a8 = ['abc', ...a7] as const;
|
||||
let a9 = [...a8];
|
||||
|
||||
declare let d: { [x: string]: string };
|
||||
|
||||
let o1 = { x: 10, y: 20 } as const;
|
||||
let o2 = { a: 1, 'b': 2, ['c']: 3, d() {}, ['e' + '']: 4 } as const;
|
||||
let o3 = { ...o1, ...o2 } as const;
|
||||
let o4 = { a: 1, b: 2 };
|
||||
let o5 = { ...o4 } as const;
|
||||
let o6 = { ...o5 };
|
||||
let o7 = { ...d } as const;
|
||||
let o8 = { ...o7 };
|
||||
let o9 = { x: 10, foo() { this.x = 20 } } as const; // Error
|
||||
~
|
||||
!!! error TS2540: Cannot assign to 'x' because it is a read-only property.
|
||||
|
||||
let p1 = (10) as const;
|
||||
let p2 = ((-10)) as const;
|
||||
let p3 = ([(10)]) as const;
|
||||
let p4 = [[[[10]]]] as const;
|
||||
|
||||
let x1 = { x: 10, y: [20, 30], z: { a: { b: 42 } } } as const;
|
||||
|
||||
let q1 = <const> 10;
|
||||
let q2 = <const> 'abc';
|
||||
let q3 = <const> true;
|
||||
let q4 = <const> [1, 2, 3];
|
||||
let q5 = <const> { x: 10, y: 20 };
|
||||
|
||||
declare function id<T>(x: T): T;
|
||||
|
||||
let e1 = v1 as const; // Error
|
||||
~~
|
||||
!!! error TS1355: A 'const' assertion can only be applied to a string, number, boolean, array, or object literal.
|
||||
let e2 = (true ? 1 : 0) as const; // Error
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS1355: A 'const' assertion can only be applied to a string, number, boolean, array, or object literal.
|
||||
let e3 = id(1) as const; // Error
|
||||
~~~~~
|
||||
!!! error TS1355: A 'const' assertion can only be applied to a string, number, boolean, array, or object literal.
|
||||
|
220
tests/baselines/reference/constAssertions.js
Normal file
220
tests/baselines/reference/constAssertions.js
Normal file
|
@ -0,0 +1,220 @@
|
|||
//// [constAssertions.ts]
|
||||
let v1 = 'abc' as const;
|
||||
let v2 = `abc` as const;
|
||||
let v3 = 10 as const;
|
||||
let v4 = -10 as const;
|
||||
let v5 = +10 as const;
|
||||
let v6 = 10n as const;
|
||||
let v7 = -10n as const;
|
||||
let v8 = true as const;
|
||||
let v9 = false as const;
|
||||
|
||||
let c1 = 'abc' as const;
|
||||
let c2 = `abc` as const;
|
||||
let c3 = 10 as const;
|
||||
let c4 = -10 as const;
|
||||
let c5 = +10 as const;
|
||||
let c6 = 10n as const;
|
||||
let c7 = -10n as const;
|
||||
let c8 = true as const;
|
||||
let c9 = false as const;
|
||||
|
||||
let vv1 = v1;
|
||||
let vc1 = c1;
|
||||
|
||||
let a1 = [] as const;
|
||||
let a2 = [1, 2, 3] as const;
|
||||
let a3 = [10, 'hello', true] as const;
|
||||
let a4 = [...[1, 2, 3]] as const;
|
||||
let a5 = [1, 2, 3];
|
||||
let a6 = [...a5] as const;
|
||||
let a7 = [...a6];
|
||||
let a8 = ['abc', ...a7] as const;
|
||||
let a9 = [...a8];
|
||||
|
||||
declare let d: { [x: string]: string };
|
||||
|
||||
let o1 = { x: 10, y: 20 } as const;
|
||||
let o2 = { a: 1, 'b': 2, ['c']: 3, d() {}, ['e' + '']: 4 } as const;
|
||||
let o3 = { ...o1, ...o2 } as const;
|
||||
let o4 = { a: 1, b: 2 };
|
||||
let o5 = { ...o4 } as const;
|
||||
let o6 = { ...o5 };
|
||||
let o7 = { ...d } as const;
|
||||
let o8 = { ...o7 };
|
||||
let o9 = { x: 10, foo() { this.x = 20 } } as const; // Error
|
||||
|
||||
let p1 = (10) as const;
|
||||
let p2 = ((-10)) as const;
|
||||
let p3 = ([(10)]) as const;
|
||||
let p4 = [[[[10]]]] as const;
|
||||
|
||||
let x1 = { x: 10, y: [20, 30], z: { a: { b: 42 } } } as const;
|
||||
|
||||
let q1 = <const> 10;
|
||||
let q2 = <const> 'abc';
|
||||
let q3 = <const> true;
|
||||
let q4 = <const> [1, 2, 3];
|
||||
let q5 = <const> { x: 10, y: 20 };
|
||||
|
||||
declare function id<T>(x: T): T;
|
||||
|
||||
let e1 = v1 as const; // Error
|
||||
let e2 = (true ? 1 : 0) as const; // Error
|
||||
let e3 = id(1) as const; // Error
|
||||
|
||||
|
||||
//// [constAssertions.js]
|
||||
"use strict";
|
||||
let v1 = 'abc';
|
||||
let v2 = `abc`;
|
||||
let v3 = 10;
|
||||
let v4 = -10;
|
||||
let v5 = +10;
|
||||
let v6 = 10n;
|
||||
let v7 = -10n;
|
||||
let v8 = true;
|
||||
let v9 = false;
|
||||
let c1 = 'abc';
|
||||
let c2 = `abc`;
|
||||
let c3 = 10;
|
||||
let c4 = -10;
|
||||
let c5 = +10;
|
||||
let c6 = 10n;
|
||||
let c7 = -10n;
|
||||
let c8 = true;
|
||||
let c9 = false;
|
||||
let vv1 = v1;
|
||||
let vc1 = c1;
|
||||
let a1 = [];
|
||||
let a2 = [1, 2, 3];
|
||||
let a3 = [10, 'hello', true];
|
||||
let a4 = [...[1, 2, 3]];
|
||||
let a5 = [1, 2, 3];
|
||||
let a6 = [...a5];
|
||||
let a7 = [...a6];
|
||||
let a8 = ['abc', ...a7];
|
||||
let a9 = [...a8];
|
||||
let o1 = { x: 10, y: 20 };
|
||||
let o2 = { a: 1, 'b': 2, ['c']: 3, d() { }, ['e' + '']: 4 };
|
||||
let o3 = { ...o1, ...o2 };
|
||||
let o4 = { a: 1, b: 2 };
|
||||
let o5 = { ...o4 };
|
||||
let o6 = { ...o5 };
|
||||
let o7 = { ...d };
|
||||
let o8 = { ...o7 };
|
||||
let o9 = { x: 10, foo() { this.x = 20; } }; // Error
|
||||
let p1 = (10);
|
||||
let p2 = ((-10));
|
||||
let p3 = ([(10)]);
|
||||
let p4 = [[[[10]]]];
|
||||
let x1 = { x: 10, y: [20, 30], z: { a: { b: 42 } } };
|
||||
let q1 = 10;
|
||||
let q2 = 'abc';
|
||||
let q3 = true;
|
||||
let q4 = [1, 2, 3];
|
||||
let q5 = { x: 10, y: 20 };
|
||||
let e1 = v1; // Error
|
||||
let e2 = (true ? 1 : 0); // Error
|
||||
let e3 = id(1); // Error
|
||||
|
||||
|
||||
//// [constAssertions.d.ts]
|
||||
declare let v1: "abc";
|
||||
declare let v2: "abc";
|
||||
declare let v3: 10;
|
||||
declare let v4: -10;
|
||||
declare let v5: 10;
|
||||
declare let v6: 10n;
|
||||
declare let v7: -10n;
|
||||
declare let v8: true;
|
||||
declare let v9: false;
|
||||
declare let c1: "abc";
|
||||
declare let c2: "abc";
|
||||
declare let c3: 10;
|
||||
declare let c4: -10;
|
||||
declare let c5: 10;
|
||||
declare let c6: 10n;
|
||||
declare let c7: -10n;
|
||||
declare let c8: true;
|
||||
declare let c9: false;
|
||||
declare let vv1: "abc";
|
||||
declare let vc1: "abc";
|
||||
declare let a1: readonly [];
|
||||
declare let a2: readonly [1, 2, 3];
|
||||
declare let a3: readonly [10, "hello", true];
|
||||
declare let a4: readonly (1 | 2 | 3)[];
|
||||
declare let a5: number[];
|
||||
declare let a6: readonly number[];
|
||||
declare let a7: number[];
|
||||
declare let a8: readonly ["abc", ...number[]];
|
||||
declare let a9: (number | "abc")[];
|
||||
declare let d: {
|
||||
[x: string]: string;
|
||||
};
|
||||
declare let o1: {
|
||||
readonly x: 10;
|
||||
readonly y: 20;
|
||||
};
|
||||
declare let o2: {
|
||||
readonly [x: string]: 1 | 2 | 3 | (() => void) | 4;
|
||||
readonly a: 1;
|
||||
readonly 'b': 2;
|
||||
readonly ['c']: 3;
|
||||
readonly d: () => void;
|
||||
};
|
||||
declare let o3: {
|
||||
readonly a: 1;
|
||||
readonly 'b': 2;
|
||||
readonly ['c']: 3;
|
||||
readonly d: () => void;
|
||||
readonly x: 10;
|
||||
readonly y: 20;
|
||||
};
|
||||
declare let o4: {
|
||||
a: number;
|
||||
b: number;
|
||||
};
|
||||
declare let o5: {
|
||||
readonly a: number;
|
||||
readonly b: number;
|
||||
};
|
||||
declare let o6: {
|
||||
a: number;
|
||||
b: number;
|
||||
};
|
||||
declare let o7: {
|
||||
readonly [x: string]: string;
|
||||
};
|
||||
declare let o8: {
|
||||
[x: string]: string;
|
||||
};
|
||||
declare let o9: {
|
||||
readonly x: 10;
|
||||
readonly foo: () => void;
|
||||
};
|
||||
declare let p1: 10;
|
||||
declare let p2: -10;
|
||||
declare let p3: readonly [10];
|
||||
declare let p4: readonly [readonly [readonly [readonly [10]]]];
|
||||
declare let x1: {
|
||||
readonly x: 10;
|
||||
readonly y: readonly [20, 30];
|
||||
z: {
|
||||
a: {
|
||||
readonly b: 42;
|
||||
};
|
||||
};
|
||||
};
|
||||
declare let q1: 10;
|
||||
declare let q2: "abc";
|
||||
declare let q3: true;
|
||||
declare let q4: readonly [1, 2, 3];
|
||||
declare let q5: {
|
||||
readonly x: 10;
|
||||
readonly y: 20;
|
||||
};
|
||||
declare function id<T>(x: T): T;
|
||||
declare let e1: "abc";
|
||||
declare let e2: 0 | 1;
|
||||
declare let e3: 1;
|
201
tests/baselines/reference/constAssertions.symbols
Normal file
201
tests/baselines/reference/constAssertions.symbols
Normal file
|
@ -0,0 +1,201 @@
|
|||
=== tests/cases/conformance/expressions/typeAssertions/constAssertions.ts ===
|
||||
let v1 = 'abc' as const;
|
||||
>v1 : Symbol(v1, Decl(constAssertions.ts, 0, 3))
|
||||
|
||||
let v2 = `abc` as const;
|
||||
>v2 : Symbol(v2, Decl(constAssertions.ts, 1, 3))
|
||||
|
||||
let v3 = 10 as const;
|
||||
>v3 : Symbol(v3, Decl(constAssertions.ts, 2, 3))
|
||||
|
||||
let v4 = -10 as const;
|
||||
>v4 : Symbol(v4, Decl(constAssertions.ts, 3, 3))
|
||||
|
||||
let v5 = +10 as const;
|
||||
>v5 : Symbol(v5, Decl(constAssertions.ts, 4, 3))
|
||||
|
||||
let v6 = 10n as const;
|
||||
>v6 : Symbol(v6, Decl(constAssertions.ts, 5, 3))
|
||||
|
||||
let v7 = -10n as const;
|
||||
>v7 : Symbol(v7, Decl(constAssertions.ts, 6, 3))
|
||||
|
||||
let v8 = true as const;
|
||||
>v8 : Symbol(v8, Decl(constAssertions.ts, 7, 3))
|
||||
|
||||
let v9 = false as const;
|
||||
>v9 : Symbol(v9, Decl(constAssertions.ts, 8, 3))
|
||||
|
||||
let c1 = 'abc' as const;
|
||||
>c1 : Symbol(c1, Decl(constAssertions.ts, 10, 3))
|
||||
|
||||
let c2 = `abc` as const;
|
||||
>c2 : Symbol(c2, Decl(constAssertions.ts, 11, 3))
|
||||
|
||||
let c3 = 10 as const;
|
||||
>c3 : Symbol(c3, Decl(constAssertions.ts, 12, 3))
|
||||
|
||||
let c4 = -10 as const;
|
||||
>c4 : Symbol(c4, Decl(constAssertions.ts, 13, 3))
|
||||
|
||||
let c5 = +10 as const;
|
||||
>c5 : Symbol(c5, Decl(constAssertions.ts, 14, 3))
|
||||
|
||||
let c6 = 10n as const;
|
||||
>c6 : Symbol(c6, Decl(constAssertions.ts, 15, 3))
|
||||
|
||||
let c7 = -10n as const;
|
||||
>c7 : Symbol(c7, Decl(constAssertions.ts, 16, 3))
|
||||
|
||||
let c8 = true as const;
|
||||
>c8 : Symbol(c8, Decl(constAssertions.ts, 17, 3))
|
||||
|
||||
let c9 = false as const;
|
||||
>c9 : Symbol(c9, Decl(constAssertions.ts, 18, 3))
|
||||
|
||||
let vv1 = v1;
|
||||
>vv1 : Symbol(vv1, Decl(constAssertions.ts, 20, 3))
|
||||
>v1 : Symbol(v1, Decl(constAssertions.ts, 0, 3))
|
||||
|
||||
let vc1 = c1;
|
||||
>vc1 : Symbol(vc1, Decl(constAssertions.ts, 21, 3))
|
||||
>c1 : Symbol(c1, Decl(constAssertions.ts, 10, 3))
|
||||
|
||||
let a1 = [] as const;
|
||||
>a1 : Symbol(a1, Decl(constAssertions.ts, 23, 3))
|
||||
|
||||
let a2 = [1, 2, 3] as const;
|
||||
>a2 : Symbol(a2, Decl(constAssertions.ts, 24, 3))
|
||||
|
||||
let a3 = [10, 'hello', true] as const;
|
||||
>a3 : Symbol(a3, Decl(constAssertions.ts, 25, 3))
|
||||
|
||||
let a4 = [...[1, 2, 3]] as const;
|
||||
>a4 : Symbol(a4, Decl(constAssertions.ts, 26, 3))
|
||||
|
||||
let a5 = [1, 2, 3];
|
||||
>a5 : Symbol(a5, Decl(constAssertions.ts, 27, 3))
|
||||
|
||||
let a6 = [...a5] as const;
|
||||
>a6 : Symbol(a6, Decl(constAssertions.ts, 28, 3))
|
||||
>a5 : Symbol(a5, Decl(constAssertions.ts, 27, 3))
|
||||
|
||||
let a7 = [...a6];
|
||||
>a7 : Symbol(a7, Decl(constAssertions.ts, 29, 3))
|
||||
>a6 : Symbol(a6, Decl(constAssertions.ts, 28, 3))
|
||||
|
||||
let a8 = ['abc', ...a7] as const;
|
||||
>a8 : Symbol(a8, Decl(constAssertions.ts, 30, 3))
|
||||
>a7 : Symbol(a7, Decl(constAssertions.ts, 29, 3))
|
||||
|
||||
let a9 = [...a8];
|
||||
>a9 : Symbol(a9, Decl(constAssertions.ts, 31, 3))
|
||||
>a8 : Symbol(a8, Decl(constAssertions.ts, 30, 3))
|
||||
|
||||
declare let d: { [x: string]: string };
|
||||
>d : Symbol(d, Decl(constAssertions.ts, 33, 11))
|
||||
>x : Symbol(x, Decl(constAssertions.ts, 33, 18))
|
||||
|
||||
let o1 = { x: 10, y: 20 } as const;
|
||||
>o1 : Symbol(o1, Decl(constAssertions.ts, 35, 3))
|
||||
>x : Symbol(x, Decl(constAssertions.ts, 35, 10))
|
||||
>y : Symbol(y, Decl(constAssertions.ts, 35, 17))
|
||||
|
||||
let o2 = { a: 1, 'b': 2, ['c']: 3, d() {}, ['e' + '']: 4 } as const;
|
||||
>o2 : Symbol(o2, Decl(constAssertions.ts, 36, 3))
|
||||
>a : Symbol(a, Decl(constAssertions.ts, 36, 10))
|
||||
>'b' : Symbol('b', Decl(constAssertions.ts, 36, 16))
|
||||
>['c'] : Symbol(['c'], Decl(constAssertions.ts, 36, 24))
|
||||
>'c' : Symbol(['c'], Decl(constAssertions.ts, 36, 24))
|
||||
>d : Symbol(d, Decl(constAssertions.ts, 36, 34))
|
||||
>['e' + ''] : Symbol(['e' + ''], Decl(constAssertions.ts, 36, 42))
|
||||
|
||||
let o3 = { ...o1, ...o2 } as const;
|
||||
>o3 : Symbol(o3, Decl(constAssertions.ts, 37, 3))
|
||||
>o1 : Symbol(o1, Decl(constAssertions.ts, 35, 3))
|
||||
>o2 : Symbol(o2, Decl(constAssertions.ts, 36, 3))
|
||||
|
||||
let o4 = { a: 1, b: 2 };
|
||||
>o4 : Symbol(o4, Decl(constAssertions.ts, 38, 3))
|
||||
>a : Symbol(a, Decl(constAssertions.ts, 38, 10))
|
||||
>b : Symbol(b, Decl(constAssertions.ts, 38, 16))
|
||||
|
||||
let o5 = { ...o4 } as const;
|
||||
>o5 : Symbol(o5, Decl(constAssertions.ts, 39, 3))
|
||||
>o4 : Symbol(o4, Decl(constAssertions.ts, 38, 3))
|
||||
|
||||
let o6 = { ...o5 };
|
||||
>o6 : Symbol(o6, Decl(constAssertions.ts, 40, 3))
|
||||
>o5 : Symbol(o5, Decl(constAssertions.ts, 39, 3))
|
||||
|
||||
let o7 = { ...d } as const;
|
||||
>o7 : Symbol(o7, Decl(constAssertions.ts, 41, 3))
|
||||
>d : Symbol(d, Decl(constAssertions.ts, 33, 11))
|
||||
|
||||
let o8 = { ...o7 };
|
||||
>o8 : Symbol(o8, Decl(constAssertions.ts, 42, 3))
|
||||
>o7 : Symbol(o7, Decl(constAssertions.ts, 41, 3))
|
||||
|
||||
let o9 = { x: 10, foo() { this.x = 20 } } as const; // Error
|
||||
>o9 : Symbol(o9, Decl(constAssertions.ts, 43, 3))
|
||||
>x : Symbol(x, Decl(constAssertions.ts, 43, 10))
|
||||
>foo : Symbol(foo, Decl(constAssertions.ts, 43, 17))
|
||||
>this.x : Symbol(x, Decl(constAssertions.ts, 43, 10))
|
||||
>this : Symbol(__object, Decl(constAssertions.ts, 43, 8))
|
||||
>x : Symbol(x, Decl(constAssertions.ts, 43, 10))
|
||||
|
||||
let p1 = (10) as const;
|
||||
>p1 : Symbol(p1, Decl(constAssertions.ts, 45, 3))
|
||||
|
||||
let p2 = ((-10)) as const;
|
||||
>p2 : Symbol(p2, Decl(constAssertions.ts, 46, 3))
|
||||
|
||||
let p3 = ([(10)]) as const;
|
||||
>p3 : Symbol(p3, Decl(constAssertions.ts, 47, 3))
|
||||
|
||||
let p4 = [[[[10]]]] as const;
|
||||
>p4 : Symbol(p4, Decl(constAssertions.ts, 48, 3))
|
||||
|
||||
let x1 = { x: 10, y: [20, 30], z: { a: { b: 42 } } } as const;
|
||||
>x1 : Symbol(x1, Decl(constAssertions.ts, 50, 3))
|
||||
>x : Symbol(x, Decl(constAssertions.ts, 50, 10))
|
||||
>y : Symbol(y, Decl(constAssertions.ts, 50, 17))
|
||||
>z : Symbol(z, Decl(constAssertions.ts, 50, 30))
|
||||
>a : Symbol(a, Decl(constAssertions.ts, 50, 35))
|
||||
>b : Symbol(b, Decl(constAssertions.ts, 50, 40))
|
||||
|
||||
let q1 = <const> 10;
|
||||
>q1 : Symbol(q1, Decl(constAssertions.ts, 52, 3))
|
||||
|
||||
let q2 = <const> 'abc';
|
||||
>q2 : Symbol(q2, Decl(constAssertions.ts, 53, 3))
|
||||
|
||||
let q3 = <const> true;
|
||||
>q3 : Symbol(q3, Decl(constAssertions.ts, 54, 3))
|
||||
|
||||
let q4 = <const> [1, 2, 3];
|
||||
>q4 : Symbol(q4, Decl(constAssertions.ts, 55, 3))
|
||||
|
||||
let q5 = <const> { x: 10, y: 20 };
|
||||
>q5 : Symbol(q5, Decl(constAssertions.ts, 56, 3))
|
||||
>x : Symbol(x, Decl(constAssertions.ts, 56, 18))
|
||||
>y : Symbol(y, Decl(constAssertions.ts, 56, 25))
|
||||
|
||||
declare function id<T>(x: T): T;
|
||||
>id : Symbol(id, Decl(constAssertions.ts, 56, 34))
|
||||
>T : Symbol(T, Decl(constAssertions.ts, 58, 20))
|
||||
>x : Symbol(x, Decl(constAssertions.ts, 58, 23))
|
||||
>T : Symbol(T, Decl(constAssertions.ts, 58, 20))
|
||||
>T : Symbol(T, Decl(constAssertions.ts, 58, 20))
|
||||
|
||||
let e1 = v1 as const; // Error
|
||||
>e1 : Symbol(e1, Decl(constAssertions.ts, 60, 3))
|
||||
>v1 : Symbol(v1, Decl(constAssertions.ts, 0, 3))
|
||||
|
||||
let e2 = (true ? 1 : 0) as const; // Error
|
||||
>e2 : Symbol(e2, Decl(constAssertions.ts, 61, 3))
|
||||
|
||||
let e3 = id(1) as const; // Error
|
||||
>e3 : Symbol(e3, Decl(constAssertions.ts, 62, 3))
|
||||
>id : Symbol(id, Decl(constAssertions.ts, 56, 34))
|
||||
|
356
tests/baselines/reference/constAssertions.types
Normal file
356
tests/baselines/reference/constAssertions.types
Normal file
|
@ -0,0 +1,356 @@
|
|||
=== tests/cases/conformance/expressions/typeAssertions/constAssertions.ts ===
|
||||
let v1 = 'abc' as const;
|
||||
>v1 : "abc"
|
||||
>'abc' as const : "abc"
|
||||
>'abc' : "abc"
|
||||
|
||||
let v2 = `abc` as const;
|
||||
>v2 : "abc"
|
||||
>`abc` as const : "abc"
|
||||
>`abc` : "abc"
|
||||
|
||||
let v3 = 10 as const;
|
||||
>v3 : 10
|
||||
>10 as const : 10
|
||||
>10 : 10
|
||||
|
||||
let v4 = -10 as const;
|
||||
>v4 : -10
|
||||
>-10 as const : -10
|
||||
>-10 : -10
|
||||
>10 : 10
|
||||
|
||||
let v5 = +10 as const;
|
||||
>v5 : 10
|
||||
>+10 as const : 10
|
||||
>+10 : 10
|
||||
>10 : 10
|
||||
|
||||
let v6 = 10n as const;
|
||||
>v6 : 10n
|
||||
>10n as const : 10n
|
||||
>10n : 10n
|
||||
|
||||
let v7 = -10n as const;
|
||||
>v7 : -10n
|
||||
>-10n as const : -10n
|
||||
>-10n : -10n
|
||||
>10n : 10n
|
||||
|
||||
let v8 = true as const;
|
||||
>v8 : true
|
||||
>true as const : true
|
||||
>true : true
|
||||
|
||||
let v9 = false as const;
|
||||
>v9 : false
|
||||
>false as const : false
|
||||
>false : false
|
||||
|
||||
let c1 = 'abc' as const;
|
||||
>c1 : "abc"
|
||||
>'abc' as const : "abc"
|
||||
>'abc' : "abc"
|
||||
|
||||
let c2 = `abc` as const;
|
||||
>c2 : "abc"
|
||||
>`abc` as const : "abc"
|
||||
>`abc` : "abc"
|
||||
|
||||
let c3 = 10 as const;
|
||||
>c3 : 10
|
||||
>10 as const : 10
|
||||
>10 : 10
|
||||
|
||||
let c4 = -10 as const;
|
||||
>c4 : -10
|
||||
>-10 as const : -10
|
||||
>-10 : -10
|
||||
>10 : 10
|
||||
|
||||
let c5 = +10 as const;
|
||||
>c5 : 10
|
||||
>+10 as const : 10
|
||||
>+10 : 10
|
||||
>10 : 10
|
||||
|
||||
let c6 = 10n as const;
|
||||
>c6 : 10n
|
||||
>10n as const : 10n
|
||||
>10n : 10n
|
||||
|
||||
let c7 = -10n as const;
|
||||
>c7 : -10n
|
||||
>-10n as const : -10n
|
||||
>-10n : -10n
|
||||
>10n : 10n
|
||||
|
||||
let c8 = true as const;
|
||||
>c8 : true
|
||||
>true as const : true
|
||||
>true : true
|
||||
|
||||
let c9 = false as const;
|
||||
>c9 : false
|
||||
>false as const : false
|
||||
>false : false
|
||||
|
||||
let vv1 = v1;
|
||||
>vv1 : "abc"
|
||||
>v1 : "abc"
|
||||
|
||||
let vc1 = c1;
|
||||
>vc1 : "abc"
|
||||
>c1 : "abc"
|
||||
|
||||
let a1 = [] as const;
|
||||
>a1 : readonly []
|
||||
>[] as const : readonly []
|
||||
>[] : readonly []
|
||||
|
||||
let a2 = [1, 2, 3] as const;
|
||||
>a2 : readonly [1, 2, 3]
|
||||
>[1, 2, 3] as const : readonly [1, 2, 3]
|
||||
>[1, 2, 3] : readonly [1, 2, 3]
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>3 : 3
|
||||
|
||||
let a3 = [10, 'hello', true] as const;
|
||||
>a3 : readonly [10, "hello", true]
|
||||
>[10, 'hello', true] as const : readonly [10, "hello", true]
|
||||
>[10, 'hello', true] : readonly [10, "hello", true]
|
||||
>10 : 10
|
||||
>'hello' : "hello"
|
||||
>true : true
|
||||
|
||||
let a4 = [...[1, 2, 3]] as const;
|
||||
>a4 : readonly (1 | 2 | 3)[]
|
||||
>[...[1, 2, 3]] as const : readonly (1 | 2 | 3)[]
|
||||
>[...[1, 2, 3]] : readonly (1 | 2 | 3)[]
|
||||
>...[1, 2, 3] : 1 | 2 | 3
|
||||
>[1, 2, 3] : readonly [1, 2, 3]
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>3 : 3
|
||||
|
||||
let a5 = [1, 2, 3];
|
||||
>a5 : number[]
|
||||
>[1, 2, 3] : number[]
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>3 : 3
|
||||
|
||||
let a6 = [...a5] as const;
|
||||
>a6 : readonly number[]
|
||||
>[...a5] as const : readonly number[]
|
||||
>[...a5] : readonly number[]
|
||||
>...a5 : number
|
||||
>a5 : number[]
|
||||
|
||||
let a7 = [...a6];
|
||||
>a7 : number[]
|
||||
>[...a6] : number[]
|
||||
>...a6 : number
|
||||
>a6 : readonly number[]
|
||||
|
||||
let a8 = ['abc', ...a7] as const;
|
||||
>a8 : readonly ["abc", ...number[]]
|
||||
>['abc', ...a7] as const : readonly ["abc", ...number[]]
|
||||
>['abc', ...a7] : readonly ["abc", ...number[]]
|
||||
>'abc' : "abc"
|
||||
>...a7 : number
|
||||
>a7 : number[]
|
||||
|
||||
let a9 = [...a8];
|
||||
>a9 : (number | "abc")[]
|
||||
>[...a8] : (number | "abc")[]
|
||||
>...a8 : number | "abc"
|
||||
>a8 : readonly ["abc", ...number[]]
|
||||
|
||||
declare let d: { [x: string]: string };
|
||||
>d : { [x: string]: string; }
|
||||
>x : string
|
||||
|
||||
let o1 = { x: 10, y: 20 } as const;
|
||||
>o1 : { readonly x: 10; readonly y: 20; }
|
||||
>{ x: 10, y: 20 } as const : { readonly x: 10; readonly y: 20; }
|
||||
>{ x: 10, y: 20 } : { readonly x: 10; readonly y: 20; }
|
||||
>x : 10
|
||||
>10 : 10
|
||||
>y : 20
|
||||
>20 : 20
|
||||
|
||||
let o2 = { a: 1, 'b': 2, ['c']: 3, d() {}, ['e' + '']: 4 } as const;
|
||||
>o2 : { readonly [x: string]: 1 | 2 | 3 | (() => void) | 4; readonly a: 1; readonly 'b': 2; readonly ['c']: 3; readonly d: () => void; }
|
||||
>{ a: 1, 'b': 2, ['c']: 3, d() {}, ['e' + '']: 4 } as const : { readonly [x: string]: 1 | 2 | 3 | (() => void) | 4; readonly a: 1; readonly 'b': 2; readonly ['c']: 3; readonly d: () => void; }
|
||||
>{ a: 1, 'b': 2, ['c']: 3, d() {}, ['e' + '']: 4 } : { readonly [x: string]: 1 | 2 | 3 | (() => void) | 4; readonly a: 1; readonly 'b': 2; readonly ['c']: 3; readonly d: () => void; }
|
||||
>a : 1
|
||||
>1 : 1
|
||||
>'b' : 2
|
||||
>2 : 2
|
||||
>['c'] : 3
|
||||
>'c' : "c"
|
||||
>3 : 3
|
||||
>d : () => void
|
||||
>['e' + ''] : 4
|
||||
>'e' + '' : string
|
||||
>'e' : "e"
|
||||
>'' : ""
|
||||
>4 : 4
|
||||
|
||||
let o3 = { ...o1, ...o2 } as const;
|
||||
>o3 : { readonly a: 1; readonly 'b': 2; readonly ['c']: 3; readonly d: () => void; readonly x: 10; readonly y: 20; }
|
||||
>{ ...o1, ...o2 } as const : { readonly a: 1; readonly 'b': 2; readonly ['c']: 3; readonly d: () => void; readonly x: 10; readonly y: 20; }
|
||||
>{ ...o1, ...o2 } : { readonly a: 1; readonly 'b': 2; readonly ['c']: 3; readonly d: () => void; readonly x: 10; readonly y: 20; }
|
||||
>o1 : { readonly x: 10; readonly y: 20; }
|
||||
>o2 : { readonly [x: string]: 1 | 2 | 3 | (() => void) | 4; readonly a: 1; readonly 'b': 2; readonly ['c']: 3; readonly d: () => void; }
|
||||
|
||||
let o4 = { a: 1, b: 2 };
|
||||
>o4 : { a: number; b: number; }
|
||||
>{ a: 1, b: 2 } : { a: number; b: number; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
>b : number
|
||||
>2 : 2
|
||||
|
||||
let o5 = { ...o4 } as const;
|
||||
>o5 : { readonly a: number; readonly b: number; }
|
||||
>{ ...o4 } as const : { readonly a: number; readonly b: number; }
|
||||
>{ ...o4 } : { readonly a: number; readonly b: number; }
|
||||
>o4 : { a: number; b: number; }
|
||||
|
||||
let o6 = { ...o5 };
|
||||
>o6 : { a: number; b: number; }
|
||||
>{ ...o5 } : { a: number; b: number; }
|
||||
>o5 : { readonly a: number; readonly b: number; }
|
||||
|
||||
let o7 = { ...d } as const;
|
||||
>o7 : { readonly [x: string]: string; }
|
||||
>{ ...d } as const : { readonly [x: string]: string; }
|
||||
>{ ...d } : { readonly [x: string]: string; }
|
||||
>d : { [x: string]: string; }
|
||||
|
||||
let o8 = { ...o7 };
|
||||
>o8 : { [x: string]: string; }
|
||||
>{ ...o7 } : { [x: string]: string; }
|
||||
>o7 : { readonly [x: string]: string; }
|
||||
|
||||
let o9 = { x: 10, foo() { this.x = 20 } } as const; // Error
|
||||
>o9 : { readonly x: 10; readonly foo: () => void; }
|
||||
>{ x: 10, foo() { this.x = 20 } } as const : { readonly x: 10; readonly foo: () => void; }
|
||||
>{ x: 10, foo() { this.x = 20 } } : { readonly x: 10; readonly foo: () => void; }
|
||||
>x : 10
|
||||
>10 : 10
|
||||
>foo : () => void
|
||||
>this.x = 20 : 20
|
||||
>this.x : any
|
||||
>this : { readonly x: 10; readonly foo: () => void; }
|
||||
>x : any
|
||||
>20 : 20
|
||||
|
||||
let p1 = (10) as const;
|
||||
>p1 : 10
|
||||
>(10) as const : 10
|
||||
>(10) : 10
|
||||
>10 : 10
|
||||
|
||||
let p2 = ((-10)) as const;
|
||||
>p2 : -10
|
||||
>((-10)) as const : -10
|
||||
>((-10)) : -10
|
||||
>(-10) : -10
|
||||
>-10 : -10
|
||||
>10 : 10
|
||||
|
||||
let p3 = ([(10)]) as const;
|
||||
>p3 : readonly [10]
|
||||
>([(10)]) as const : readonly [10]
|
||||
>([(10)]) : readonly [10]
|
||||
>[(10)] : readonly [10]
|
||||
>(10) : 10
|
||||
>10 : 10
|
||||
|
||||
let p4 = [[[[10]]]] as const;
|
||||
>p4 : readonly [readonly [readonly [readonly [10]]]]
|
||||
>[[[[10]]]] as const : readonly [readonly [readonly [readonly [10]]]]
|
||||
>[[[[10]]]] : readonly [readonly [readonly [readonly [10]]]]
|
||||
>[[[10]]] : readonly [readonly [readonly [10]]]
|
||||
>[[10]] : readonly [readonly [10]]
|
||||
>[10] : readonly [10]
|
||||
>10 : 10
|
||||
|
||||
let x1 = { x: 10, y: [20, 30], z: { a: { b: 42 } } } as const;
|
||||
>x1 : { readonly x: 10; readonly y: readonly [20, 30]; z: { a: { readonly b: 42; }; }; }
|
||||
>{ x: 10, y: [20, 30], z: { a: { b: 42 } } } as const : { readonly x: 10; readonly y: readonly [20, 30]; readonly z: { readonly a: { readonly b: 42; }; }; }
|
||||
>{ x: 10, y: [20, 30], z: { a: { b: 42 } } } : { readonly x: 10; readonly y: readonly [20, 30]; readonly z: { readonly a: { readonly b: 42; }; }; }
|
||||
>x : 10
|
||||
>10 : 10
|
||||
>y : readonly [20, 30]
|
||||
>[20, 30] : readonly [20, 30]
|
||||
>20 : 20
|
||||
>30 : 30
|
||||
>z : { readonly a: { readonly b: 42; }; }
|
||||
>{ a: { b: 42 } } : { readonly a: { readonly b: 42; }; }
|
||||
>a : { readonly b: 42; }
|
||||
>{ b: 42 } : { readonly b: 42; }
|
||||
>b : 42
|
||||
>42 : 42
|
||||
|
||||
let q1 = <const> 10;
|
||||
>q1 : 10
|
||||
><const> 10 : 10
|
||||
>10 : 10
|
||||
|
||||
let q2 = <const> 'abc';
|
||||
>q2 : "abc"
|
||||
><const> 'abc' : "abc"
|
||||
>'abc' : "abc"
|
||||
|
||||
let q3 = <const> true;
|
||||
>q3 : true
|
||||
><const> true : true
|
||||
>true : true
|
||||
|
||||
let q4 = <const> [1, 2, 3];
|
||||
>q4 : readonly [1, 2, 3]
|
||||
><const> [1, 2, 3] : readonly [1, 2, 3]
|
||||
>[1, 2, 3] : readonly [1, 2, 3]
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>3 : 3
|
||||
|
||||
let q5 = <const> { x: 10, y: 20 };
|
||||
>q5 : { readonly x: 10; readonly y: 20; }
|
||||
><const> { x: 10, y: 20 } : { readonly x: 10; readonly y: 20; }
|
||||
>{ x: 10, y: 20 } : { readonly x: 10; readonly y: 20; }
|
||||
>x : 10
|
||||
>10 : 10
|
||||
>y : 20
|
||||
>20 : 20
|
||||
|
||||
declare function id<T>(x: T): T;
|
||||
>id : <T>(x: T) => T
|
||||
>x : T
|
||||
|
||||
let e1 = v1 as const; // Error
|
||||
>e1 : "abc"
|
||||
>v1 as const : "abc"
|
||||
>v1 : "abc"
|
||||
|
||||
let e2 = (true ? 1 : 0) as const; // Error
|
||||
>e2 : 0 | 1
|
||||
>(true ? 1 : 0) as const : 0 | 1
|
||||
>(true ? 1 : 0) : 0 | 1
|
||||
>true ? 1 : 0 : 0 | 1
|
||||
>true : true
|
||||
>1 : 1
|
||||
>0 : 0
|
||||
|
||||
let e3 = id(1) as const; // Error
|
||||
>e3 : 1
|
||||
>id(1) as const : 1
|
||||
>id(1) : 1
|
||||
>id : <T>(x: T) => T
|
||||
>1 : 1
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(11,13): error TS2503: Cannot find namespace 'module'.
|
||||
tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(11,13): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.
|
||||
tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(11,13): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`.
|
||||
tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(11,19): error TS1005: ';' expected.
|
||||
tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(22,35): error TS1005: ')' expected.
|
||||
tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(22,39): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
|
||||
|
@ -105,7 +105,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(261,1): error TS
|
|||
~~~~~~
|
||||
!!! error TS2503: Cannot find namespace 'module'.
|
||||
~~~~~~
|
||||
!!! error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.
|
||||
!!! error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node`.
|
||||
~
|
||||
!!! error TS1005: ';' expected.
|
||||
|
||||
|
|
|
@ -93,7 +93,34 @@ let xyz: LikeA | LikeB = {
|
|||
}
|
||||
};
|
||||
|
||||
xyz;
|
||||
xyz;
|
||||
|
||||
// Repro from #29168
|
||||
|
||||
interface TestObject {
|
||||
type?: 'object';
|
||||
items: {
|
||||
[k: string]: TestGeneric;
|
||||
};
|
||||
}
|
||||
|
||||
interface TestString {
|
||||
type: 'string';
|
||||
}
|
||||
|
||||
type TestGeneric = (TestString | TestObject) & { [k: string]: any; };
|
||||
|
||||
const test: TestGeneric = {
|
||||
items: {
|
||||
hello: { type: 'string' },
|
||||
world: {
|
||||
items: {
|
||||
nested: { type: 'string' }
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//// [contextualTypeShouldBeLiteral.js]
|
||||
"use strict";
|
||||
|
@ -134,3 +161,13 @@ var xyz = {
|
|||
}
|
||||
};
|
||||
xyz;
|
||||
var test = {
|
||||
items: {
|
||||
hello: { type: 'string' },
|
||||
world: {
|
||||
items: {
|
||||
nested: { type: 'string' }
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -227,3 +227,59 @@ let xyz: LikeA | LikeB = {
|
|||
xyz;
|
||||
>xyz : Symbol(xyz, Decl(contextualTypeShouldBeLiteral.ts, 82, 3))
|
||||
|
||||
// Repro from #29168
|
||||
|
||||
interface TestObject {
|
||||
>TestObject : Symbol(TestObject, Decl(contextualTypeShouldBeLiteral.ts, 94, 4))
|
||||
|
||||
type?: 'object';
|
||||
>type : Symbol(TestObject.type, Decl(contextualTypeShouldBeLiteral.ts, 98, 22))
|
||||
|
||||
items: {
|
||||
>items : Symbol(TestObject.items, Decl(contextualTypeShouldBeLiteral.ts, 99, 18))
|
||||
|
||||
[k: string]: TestGeneric;
|
||||
>k : Symbol(k, Decl(contextualTypeShouldBeLiteral.ts, 101, 5))
|
||||
>TestGeneric : Symbol(TestGeneric, Decl(contextualTypeShouldBeLiteral.ts, 107, 1))
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
interface TestString {
|
||||
>TestString : Symbol(TestString, Decl(contextualTypeShouldBeLiteral.ts, 103, 1))
|
||||
|
||||
type: 'string';
|
||||
>type : Symbol(TestString.type, Decl(contextualTypeShouldBeLiteral.ts, 105, 22))
|
||||
}
|
||||
|
||||
type TestGeneric = (TestString | TestObject) & { [k: string]: any; };
|
||||
>TestGeneric : Symbol(TestGeneric, Decl(contextualTypeShouldBeLiteral.ts, 107, 1))
|
||||
>TestString : Symbol(TestString, Decl(contextualTypeShouldBeLiteral.ts, 103, 1))
|
||||
>TestObject : Symbol(TestObject, Decl(contextualTypeShouldBeLiteral.ts, 94, 4))
|
||||
>k : Symbol(k, Decl(contextualTypeShouldBeLiteral.ts, 109, 50))
|
||||
|
||||
const test: TestGeneric = {
|
||||
>test : Symbol(test, Decl(contextualTypeShouldBeLiteral.ts, 111, 5))
|
||||
>TestGeneric : Symbol(TestGeneric, Decl(contextualTypeShouldBeLiteral.ts, 107, 1))
|
||||
|
||||
items: {
|
||||
>items : Symbol(items, Decl(contextualTypeShouldBeLiteral.ts, 111, 27))
|
||||
|
||||
hello: { type: 'string' },
|
||||
>hello : Symbol(hello, Decl(contextualTypeShouldBeLiteral.ts, 112, 10))
|
||||
>type : Symbol(type, Decl(contextualTypeShouldBeLiteral.ts, 113, 12))
|
||||
|
||||
world: {
|
||||
>world : Symbol(world, Decl(contextualTypeShouldBeLiteral.ts, 113, 30))
|
||||
|
||||
items: {
|
||||
>items : Symbol(items, Decl(contextualTypeShouldBeLiteral.ts, 114, 12))
|
||||
|
||||
nested: { type: 'string' }
|
||||
>nested : Symbol(nested, Decl(contextualTypeShouldBeLiteral.ts, 115, 14))
|
||||
>type : Symbol(type, Decl(contextualTypeShouldBeLiteral.ts, 116, 17))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -222,3 +222,59 @@ let xyz: LikeA | LikeB = {
|
|||
xyz;
|
||||
>xyz : LikeA
|
||||
|
||||
// Repro from #29168
|
||||
|
||||
interface TestObject {
|
||||
type?: 'object';
|
||||
>type : "object" | undefined
|
||||
|
||||
items: {
|
||||
>items : { [k: string]: TestGeneric; }
|
||||
|
||||
[k: string]: TestGeneric;
|
||||
>k : string
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
interface TestString {
|
||||
type: 'string';
|
||||
>type : "string"
|
||||
}
|
||||
|
||||
type TestGeneric = (TestString | TestObject) & { [k: string]: any; };
|
||||
>TestGeneric : TestGeneric
|
||||
>k : string
|
||||
|
||||
const test: TestGeneric = {
|
||||
>test : TestGeneric
|
||||
>{ items: { hello: { type: 'string' }, world: { items: { nested: { type: 'string' } } } }} : { items: { hello: { type: "string"; }; world: { items: { nested: { type: "string"; }; }; }; }; }
|
||||
|
||||
items: {
|
||||
>items : { hello: { type: "string"; }; world: { items: { nested: { type: "string"; }; }; }; }
|
||||
>{ hello: { type: 'string' }, world: { items: { nested: { type: 'string' } } } } : { hello: { type: "string"; }; world: { items: { nested: { type: "string"; }; }; }; }
|
||||
|
||||
hello: { type: 'string' },
|
||||
>hello : { type: "string"; }
|
||||
>{ type: 'string' } : { type: "string"; }
|
||||
>type : "string"
|
||||
>'string' : "string"
|
||||
|
||||
world: {
|
||||
>world : { items: { nested: { type: "string"; }; }; }
|
||||
>{ items: { nested: { type: 'string' } } } : { items: { nested: { type: "string"; }; }; }
|
||||
|
||||
items: {
|
||||
>items : { nested: { type: "string"; }; }
|
||||
>{ nested: { type: 'string' } } : { nested: { type: "string"; }; }
|
||||
|
||||
nested: { type: 'string' }
|
||||
>nested : { type: "string"; }
|
||||
>{ type: 'string' } : { type: "string"; }
|
||||
>type : "string"
|
||||
>'string' : "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts(8,29): error TS7031: Binding element 'foo' implicitly has an 'any' type.
|
||||
tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts(14,27): error TS7006: Parameter 'foo' implicitly has an 'any' type.
|
||||
tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts(27,42): error TS7031: Binding element 'foo' implicitly has an 'any' type.
|
||||
|
||||
|
||||
==== tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts (3 errors) ====
|
||||
declare function id1<T>(input: T): T;
|
||||
declare function id2<T extends (x: any) => any>(input: T): T;
|
||||
declare function id3<T extends (x: { foo: any }) => any>(input: T): T;
|
||||
declare function id4<T extends (x: { foo?: number }) => any>(input: T): T;
|
||||
declare function id5<T extends (x?: number) => any>(input: T): T;
|
||||
|
||||
const f10 = function ({ foo = 42 }) { return foo };
|
||||
const f11 = id1(function ({ foo = 42 }) { return foo }); // Implicit any error
|
||||
~~~
|
||||
!!! error TS7031: Binding element 'foo' implicitly has an 'any' type.
|
||||
const f12 = id2(function ({ foo = 42 }) { return foo });
|
||||
const f13 = id3(function ({ foo = 42 }) { return foo });
|
||||
const f14 = id4(function ({ foo = 42 }) { return foo });
|
||||
|
||||
const f20 = function (foo = 42) { return foo };
|
||||
const f21 = id1(function (foo = 42) { return foo }); // Implicit any error
|
||||
~~~~~~~~
|
||||
!!! error TS7006: Parameter 'foo' implicitly has an 'any' type.
|
||||
const f22 = id2(function (foo = 42) { return foo });
|
||||
const f25 = id5(function (foo = 42) { return foo });
|
||||
|
||||
// Repro from #28816
|
||||
|
||||
function id<T>(input: T): T { return input }
|
||||
|
||||
function getFoo ({ foo = 42 }) {
|
||||
return foo;
|
||||
}
|
||||
|
||||
const newGetFoo = id(getFoo);
|
||||
const newGetFoo2 = id(function getFoo ({ foo = 42 }) {
|
||||
~~~
|
||||
!!! error TS7031: Binding element 'foo' implicitly has an 'any' type.
|
||||
return foo;
|
||||
});
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
//// [contextuallyTypedParametersWithInitializers.ts]
|
||||
declare function id1<T>(input: T): T;
|
||||
declare function id2<T extends (x: any) => any>(input: T): T;
|
||||
declare function id3<T extends (x: { foo: any }) => any>(input: T): T;
|
||||
declare function id4<T extends (x: { foo?: number }) => any>(input: T): T;
|
||||
declare function id5<T extends (x?: number) => any>(input: T): T;
|
||||
|
||||
const f10 = function ({ foo = 42 }) { return foo };
|
||||
const f11 = id1(function ({ foo = 42 }) { return foo }); // Implicit any error
|
||||
const f12 = id2(function ({ foo = 42 }) { return foo });
|
||||
const f13 = id3(function ({ foo = 42 }) { return foo });
|
||||
const f14 = id4(function ({ foo = 42 }) { return foo });
|
||||
|
||||
const f20 = function (foo = 42) { return foo };
|
||||
const f21 = id1(function (foo = 42) { return foo }); // Implicit any error
|
||||
const f22 = id2(function (foo = 42) { return foo });
|
||||
const f25 = id5(function (foo = 42) { return foo });
|
||||
|
||||
// Repro from #28816
|
||||
|
||||
function id<T>(input: T): T { return input }
|
||||
|
||||
function getFoo ({ foo = 42 }) {
|
||||
return foo;
|
||||
}
|
||||
|
||||
const newGetFoo = id(getFoo);
|
||||
const newGetFoo2 = id(function getFoo ({ foo = 42 }) {
|
||||
return foo;
|
||||
});
|
||||
|
||||
|
||||
//// [contextuallyTypedParametersWithInitializers.js]
|
||||
"use strict";
|
||||
var f10 = function (_a) {
|
||||
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
|
||||
return foo;
|
||||
};
|
||||
var f11 = id1(function (_a) {
|
||||
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
|
||||
return foo;
|
||||
}); // Implicit any error
|
||||
var f12 = id2(function (_a) {
|
||||
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
|
||||
return foo;
|
||||
});
|
||||
var f13 = id3(function (_a) {
|
||||
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
|
||||
return foo;
|
||||
});
|
||||
var f14 = id4(function (_a) {
|
||||
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
|
||||
return foo;
|
||||
});
|
||||
var f20 = function (foo) {
|
||||
if (foo === void 0) { foo = 42; }
|
||||
return foo;
|
||||
};
|
||||
var f21 = id1(function (foo) {
|
||||
if (foo === void 0) { foo = 42; }
|
||||
return foo;
|
||||
}); // Implicit any error
|
||||
var f22 = id2(function (foo) {
|
||||
if (foo === void 0) { foo = 42; }
|
||||
return foo;
|
||||
});
|
||||
var f25 = id5(function (foo) {
|
||||
if (foo === void 0) { foo = 42; }
|
||||
return foo;
|
||||
});
|
||||
// Repro from #28816
|
||||
function id(input) { return input; }
|
||||
function getFoo(_a) {
|
||||
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
|
||||
return foo;
|
||||
}
|
||||
var newGetFoo = id(getFoo);
|
||||
var newGetFoo2 = id(function getFoo(_a) {
|
||||
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
|
||||
return foo;
|
||||
});
|
||||
|
||||
|
||||
//// [contextuallyTypedParametersWithInitializers.d.ts]
|
||||
declare function id1<T>(input: T): T;
|
||||
declare function id2<T extends (x: any) => any>(input: T): T;
|
||||
declare function id3<T extends (x: {
|
||||
foo: any;
|
||||
}) => any>(input: T): T;
|
||||
declare function id4<T extends (x: {
|
||||
foo?: number;
|
||||
}) => any>(input: T): T;
|
||||
declare function id5<T extends (x?: number) => any>(input: T): T;
|
||||
declare const f10: ({ foo }: {
|
||||
foo?: number | undefined;
|
||||
}) => number;
|
||||
declare const f11: ({ foo }: any) => any;
|
||||
declare const f12: ({ foo }: any) => any;
|
||||
declare const f13: ({ foo }: {
|
||||
foo: any;
|
||||
}) => any;
|
||||
declare const f14: ({ foo }: {
|
||||
foo?: number | undefined;
|
||||
}) => number;
|
||||
declare const f20: (foo?: number) => number;
|
||||
declare const f21: (foo?: any) => any;
|
||||
declare const f22: (foo?: any) => any;
|
||||
declare const f25: (foo?: number | undefined) => number;
|
||||
declare function id<T>(input: T): T;
|
||||
declare function getFoo({ foo }: {
|
||||
foo?: number | undefined;
|
||||
}): number;
|
||||
declare const newGetFoo: typeof getFoo;
|
||||
declare const newGetFoo2: ({ foo }: any) => any;
|
|
@ -0,0 +1,128 @@
|
|||
=== tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts ===
|
||||
declare function id1<T>(input: T): T;
|
||||
>id1 : Symbol(id1, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 21))
|
||||
>input : Symbol(input, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 24))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 21))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 21))
|
||||
|
||||
declare function id2<T extends (x: any) => any>(input: T): T;
|
||||
>id2 : Symbol(id2, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 37))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 1, 21))
|
||||
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 1, 32))
|
||||
>input : Symbol(input, Decl(contextuallyTypedParametersWithInitializers.ts, 1, 48))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 1, 21))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 1, 21))
|
||||
|
||||
declare function id3<T extends (x: { foo: any }) => any>(input: T): T;
|
||||
>id3 : Symbol(id3, Decl(contextuallyTypedParametersWithInitializers.ts, 1, 61))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 2, 21))
|
||||
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 2, 32))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 2, 36))
|
||||
>input : Symbol(input, Decl(contextuallyTypedParametersWithInitializers.ts, 2, 57))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 2, 21))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 2, 21))
|
||||
|
||||
declare function id4<T extends (x: { foo?: number }) => any>(input: T): T;
|
||||
>id4 : Symbol(id4, Decl(contextuallyTypedParametersWithInitializers.ts, 2, 70))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 3, 21))
|
||||
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 3, 32))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 3, 36))
|
||||
>input : Symbol(input, Decl(contextuallyTypedParametersWithInitializers.ts, 3, 61))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 3, 21))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 3, 21))
|
||||
|
||||
declare function id5<T extends (x?: number) => any>(input: T): T;
|
||||
>id5 : Symbol(id5, Decl(contextuallyTypedParametersWithInitializers.ts, 3, 74))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 4, 21))
|
||||
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 4, 32))
|
||||
>input : Symbol(input, Decl(contextuallyTypedParametersWithInitializers.ts, 4, 52))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 4, 21))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 4, 21))
|
||||
|
||||
const f10 = function ({ foo = 42 }) { return foo };
|
||||
>f10 : Symbol(f10, Decl(contextuallyTypedParametersWithInitializers.ts, 6, 5))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 6, 23))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 6, 23))
|
||||
|
||||
const f11 = id1(function ({ foo = 42 }) { return foo }); // Implicit any error
|
||||
>f11 : Symbol(f11, Decl(contextuallyTypedParametersWithInitializers.ts, 7, 5))
|
||||
>id1 : Symbol(id1, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 0))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 7, 27))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 7, 27))
|
||||
|
||||
const f12 = id2(function ({ foo = 42 }) { return foo });
|
||||
>f12 : Symbol(f12, Decl(contextuallyTypedParametersWithInitializers.ts, 8, 5))
|
||||
>id2 : Symbol(id2, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 37))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 8, 27))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 8, 27))
|
||||
|
||||
const f13 = id3(function ({ foo = 42 }) { return foo });
|
||||
>f13 : Symbol(f13, Decl(contextuallyTypedParametersWithInitializers.ts, 9, 5))
|
||||
>id3 : Symbol(id3, Decl(contextuallyTypedParametersWithInitializers.ts, 1, 61))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 9, 27))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 9, 27))
|
||||
|
||||
const f14 = id4(function ({ foo = 42 }) { return foo });
|
||||
>f14 : Symbol(f14, Decl(contextuallyTypedParametersWithInitializers.ts, 10, 5))
|
||||
>id4 : Symbol(id4, Decl(contextuallyTypedParametersWithInitializers.ts, 2, 70))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 10, 27))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 10, 27))
|
||||
|
||||
const f20 = function (foo = 42) { return foo };
|
||||
>f20 : Symbol(f20, Decl(contextuallyTypedParametersWithInitializers.ts, 12, 5))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 12, 22))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 12, 22))
|
||||
|
||||
const f21 = id1(function (foo = 42) { return foo }); // Implicit any error
|
||||
>f21 : Symbol(f21, Decl(contextuallyTypedParametersWithInitializers.ts, 13, 5))
|
||||
>id1 : Symbol(id1, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 0))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 13, 26))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 13, 26))
|
||||
|
||||
const f22 = id2(function (foo = 42) { return foo });
|
||||
>f22 : Symbol(f22, Decl(contextuallyTypedParametersWithInitializers.ts, 14, 5))
|
||||
>id2 : Symbol(id2, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 37))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 14, 26))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 14, 26))
|
||||
|
||||
const f25 = id5(function (foo = 42) { return foo });
|
||||
>f25 : Symbol(f25, Decl(contextuallyTypedParametersWithInitializers.ts, 15, 5))
|
||||
>id5 : Symbol(id5, Decl(contextuallyTypedParametersWithInitializers.ts, 3, 74))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 15, 26))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 15, 26))
|
||||
|
||||
// Repro from #28816
|
||||
|
||||
function id<T>(input: T): T { return input }
|
||||
>id : Symbol(id, Decl(contextuallyTypedParametersWithInitializers.ts, 15, 52))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 12))
|
||||
>input : Symbol(input, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 15))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 12))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 12))
|
||||
>input : Symbol(input, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 15))
|
||||
|
||||
function getFoo ({ foo = 42 }) {
|
||||
>getFoo : Symbol(getFoo, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 44))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 21, 18))
|
||||
|
||||
return foo;
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 21, 18))
|
||||
}
|
||||
|
||||
const newGetFoo = id(getFoo);
|
||||
>newGetFoo : Symbol(newGetFoo, Decl(contextuallyTypedParametersWithInitializers.ts, 25, 5))
|
||||
>id : Symbol(id, Decl(contextuallyTypedParametersWithInitializers.ts, 15, 52))
|
||||
>getFoo : Symbol(getFoo, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 44))
|
||||
|
||||
const newGetFoo2 = id(function getFoo ({ foo = 42 }) {
|
||||
>newGetFoo2 : Symbol(newGetFoo2, Decl(contextuallyTypedParametersWithInitializers.ts, 26, 5))
|
||||
>id : Symbol(id, Decl(contextuallyTypedParametersWithInitializers.ts, 15, 52))
|
||||
>getFoo : Symbol(getFoo, Decl(contextuallyTypedParametersWithInitializers.ts, 26, 22))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 26, 40))
|
||||
|
||||
return foo;
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 26, 40))
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
=== tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts ===
|
||||
declare function id1<T>(input: T): T;
|
||||
>id1 : <T>(input: T) => T
|
||||
>input : T
|
||||
|
||||
declare function id2<T extends (x: any) => any>(input: T): T;
|
||||
>id2 : <T extends (x: any) => any>(input: T) => T
|
||||
>x : any
|
||||
>input : T
|
||||
|
||||
declare function id3<T extends (x: { foo: any }) => any>(input: T): T;
|
||||
>id3 : <T extends (x: { foo: any; }) => any>(input: T) => T
|
||||
>x : { foo: any; }
|
||||
>foo : any
|
||||
>input : T
|
||||
|
||||
declare function id4<T extends (x: { foo?: number }) => any>(input: T): T;
|
||||
>id4 : <T extends (x: { foo?: number | undefined; }) => any>(input: T) => T
|
||||
>x : { foo?: number | undefined; }
|
||||
>foo : number | undefined
|
||||
>input : T
|
||||
|
||||
declare function id5<T extends (x?: number) => any>(input: T): T;
|
||||
>id5 : <T extends (x?: number | undefined) => any>(input: T) => T
|
||||
>x : number | undefined
|
||||
>input : T
|
||||
|
||||
const f10 = function ({ foo = 42 }) { return foo };
|
||||
>f10 : ({ foo }: { foo?: number | undefined; }) => number
|
||||
>function ({ foo = 42 }) { return foo } : ({ foo }: { foo?: number | undefined; }) => number
|
||||
>foo : number
|
||||
>42 : 42
|
||||
>foo : number
|
||||
|
||||
const f11 = id1(function ({ foo = 42 }) { return foo }); // Implicit any error
|
||||
>f11 : ({ foo }: any) => any
|
||||
>id1(function ({ foo = 42 }) { return foo }) : ({ foo }: any) => any
|
||||
>id1 : <T>(input: T) => T
|
||||
>function ({ foo = 42 }) { return foo } : ({ foo }: any) => any
|
||||
>foo : any
|
||||
>42 : 42
|
||||
>foo : any
|
||||
|
||||
const f12 = id2(function ({ foo = 42 }) { return foo });
|
||||
>f12 : ({ foo }: any) => any
|
||||
>id2(function ({ foo = 42 }) { return foo }) : ({ foo }: any) => any
|
||||
>id2 : <T extends (x: any) => any>(input: T) => T
|
||||
>function ({ foo = 42 }) { return foo } : ({ foo }: any) => any
|
||||
>foo : any
|
||||
>42 : 42
|
||||
>foo : any
|
||||
|
||||
const f13 = id3(function ({ foo = 42 }) { return foo });
|
||||
>f13 : ({ foo }: { foo: any; }) => any
|
||||
>id3(function ({ foo = 42 }) { return foo }) : ({ foo }: { foo: any; }) => any
|
||||
>id3 : <T extends (x: { foo: any; }) => any>(input: T) => T
|
||||
>function ({ foo = 42 }) { return foo } : ({ foo }: { foo: any; }) => any
|
||||
>foo : any
|
||||
>42 : 42
|
||||
>foo : any
|
||||
|
||||
const f14 = id4(function ({ foo = 42 }) { return foo });
|
||||
>f14 : ({ foo }: { foo?: number | undefined; }) => number
|
||||
>id4(function ({ foo = 42 }) { return foo }) : ({ foo }: { foo?: number | undefined; }) => number
|
||||
>id4 : <T extends (x: { foo?: number | undefined; }) => any>(input: T) => T
|
||||
>function ({ foo = 42 }) { return foo } : ({ foo }: { foo?: number | undefined; }) => number
|
||||
>foo : number
|
||||
>42 : 42
|
||||
>foo : number
|
||||
|
||||
const f20 = function (foo = 42) { return foo };
|
||||
>f20 : (foo?: number) => number
|
||||
>function (foo = 42) { return foo } : (foo?: number) => number
|
||||
>foo : number
|
||||
>42 : 42
|
||||
>foo : number
|
||||
|
||||
const f21 = id1(function (foo = 42) { return foo }); // Implicit any error
|
||||
>f21 : (foo?: any) => any
|
||||
>id1(function (foo = 42) { return foo }) : (foo?: any) => any
|
||||
>id1 : <T>(input: T) => T
|
||||
>function (foo = 42) { return foo } : (foo?: any) => any
|
||||
>foo : any
|
||||
>42 : 42
|
||||
>foo : any
|
||||
|
||||
const f22 = id2(function (foo = 42) { return foo });
|
||||
>f22 : (foo?: any) => any
|
||||
>id2(function (foo = 42) { return foo }) : (foo?: any) => any
|
||||
>id2 : <T extends (x: any) => any>(input: T) => T
|
||||
>function (foo = 42) { return foo } : (foo?: any) => any
|
||||
>foo : any
|
||||
>42 : 42
|
||||
>foo : any
|
||||
|
||||
const f25 = id5(function (foo = 42) { return foo });
|
||||
>f25 : (foo?: number | undefined) => number
|
||||
>id5(function (foo = 42) { return foo }) : (foo?: number | undefined) => number
|
||||
>id5 : <T extends (x?: number | undefined) => any>(input: T) => T
|
||||
>function (foo = 42) { return foo } : (foo?: number | undefined) => number
|
||||
>foo : number | undefined
|
||||
>42 : 42
|
||||
>foo : number
|
||||
|
||||
// Repro from #28816
|
||||
|
||||
function id<T>(input: T): T { return input }
|
||||
>id : <T>(input: T) => T
|
||||
>input : T
|
||||
>input : T
|
||||
|
||||
function getFoo ({ foo = 42 }) {
|
||||
>getFoo : ({ foo }: { foo?: number | undefined; }) => number
|
||||
>foo : number
|
||||
>42 : 42
|
||||
|
||||
return foo;
|
||||
>foo : number
|
||||
}
|
||||
|
||||
const newGetFoo = id(getFoo);
|
||||
>newGetFoo : ({ foo }: { foo?: number | undefined; }) => number
|
||||
>id(getFoo) : ({ foo }: { foo?: number | undefined; }) => number
|
||||
>id : <T>(input: T) => T
|
||||
>getFoo : ({ foo }: { foo?: number | undefined; }) => number
|
||||
|
||||
const newGetFoo2 = id(function getFoo ({ foo = 42 }) {
|
||||
>newGetFoo2 : ({ foo }: any) => any
|
||||
>id(function getFoo ({ foo = 42 }) { return foo;}) : ({ foo }: any) => any
|
||||
>id : <T>(input: T) => T
|
||||
>function getFoo ({ foo = 42 }) { return foo;} : ({ foo }: any) => any
|
||||
>getFoo : ({ foo }: any) => any
|
||||
>foo : any
|
||||
>42 : 42
|
||||
|
||||
return foo;
|
||||
>foo : any
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
tests/cases/compiler/crashInGetTextOfComputedPropertyName.ts(23,24): error TS2525: Initializer provides no value for this binding element and the binding element has no default value.
|
||||
|
||||
|
||||
==== tests/cases/compiler/crashInGetTextOfComputedPropertyName.ts (1 errors) ====
|
||||
// https://github.com/Microsoft/TypeScript/issues/29006
|
||||
export interface A { type: 'a' }
|
||||
export interface B { type: 'b' }
|
||||
export type AB = A | B
|
||||
|
||||
const itemId = 'some-id'
|
||||
|
||||
// --- test on first level ---
|
||||
const items: { [id: string]: AB } = {}
|
||||
const { [itemId]: itemOk1 } = items
|
||||
typeof itemOk1 // pass
|
||||
|
||||
// --- test on second level ---
|
||||
interface ObjWithItems {
|
||||
items: {[s: string]: AB}
|
||||
}
|
||||
const objWithItems: ObjWithItems = { items: {}}
|
||||
|
||||
const itemOk2 = objWithItems.items[itemId]
|
||||
typeof itemOk2 // pass
|
||||
|
||||
const {
|
||||
items: { [itemId]: itemWithTSError } = {} /*happens when default value is provided*/
|
||||
~~~~~~~~~~~~~~~
|
||||
!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value.
|
||||
} = objWithItems
|
||||
|
||||
// in order to re-produce the error, uncomment next line:
|
||||
typeof itemWithTSError // :(
|
||||
|
||||
// will result in:
|
||||
// Error from compilation: TypeError: Cannot read property 'charCodeAt' of undefined TypeError: Cannot read property 'charCodeAt' of undefined
|
|
@ -0,0 +1,48 @@
|
|||
//// [crashInGetTextOfComputedPropertyName.ts]
|
||||
// https://github.com/Microsoft/TypeScript/issues/29006
|
||||
export interface A { type: 'a' }
|
||||
export interface B { type: 'b' }
|
||||
export type AB = A | B
|
||||
|
||||
const itemId = 'some-id'
|
||||
|
||||
// --- test on first level ---
|
||||
const items: { [id: string]: AB } = {}
|
||||
const { [itemId]: itemOk1 } = items
|
||||
typeof itemOk1 // pass
|
||||
|
||||
// --- test on second level ---
|
||||
interface ObjWithItems {
|
||||
items: {[s: string]: AB}
|
||||
}
|
||||
const objWithItems: ObjWithItems = { items: {}}
|
||||
|
||||
const itemOk2 = objWithItems.items[itemId]
|
||||
typeof itemOk2 // pass
|
||||
|
||||
const {
|
||||
items: { [itemId]: itemWithTSError } = {} /*happens when default value is provided*/
|
||||
} = objWithItems
|
||||
|
||||
// in order to re-produce the error, uncomment next line:
|
||||
typeof itemWithTSError // :(
|
||||
|
||||
// will result in:
|
||||
// Error from compilation: TypeError: Cannot read property 'charCodeAt' of undefined TypeError: Cannot read property 'charCodeAt' of undefined
|
||||
|
||||
//// [crashInGetTextOfComputedPropertyName.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var itemId = 'some-id';
|
||||
// --- test on first level ---
|
||||
var items = {};
|
||||
var _a = itemId, itemOk1 = items[_a];
|
||||
typeof itemOk1; // pass
|
||||
var objWithItems = { items: {} };
|
||||
var itemOk2 = objWithItems.items[itemId];
|
||||
typeof itemOk2; // pass
|
||||
var _b = objWithItems.items /*happens when default value is provided*/, _c = itemId, itemWithTSError = (_b === void 0 ? {} /*happens when default value is provided*/ : _b)[_c];
|
||||
// in order to re-produce the error, uncomment next line:
|
||||
typeof itemWithTSError; // :(
|
||||
// will result in:
|
||||
// Error from compilation: TypeError: Cannot read property 'charCodeAt' of undefined TypeError: Cannot read property 'charCodeAt' of undefined
|
|
@ -0,0 +1,71 @@
|
|||
=== tests/cases/compiler/crashInGetTextOfComputedPropertyName.ts ===
|
||||
// https://github.com/Microsoft/TypeScript/issues/29006
|
||||
export interface A { type: 'a' }
|
||||
>A : Symbol(A, Decl(crashInGetTextOfComputedPropertyName.ts, 0, 0))
|
||||
>type : Symbol(A.type, Decl(crashInGetTextOfComputedPropertyName.ts, 1, 20))
|
||||
|
||||
export interface B { type: 'b' }
|
||||
>B : Symbol(B, Decl(crashInGetTextOfComputedPropertyName.ts, 1, 32))
|
||||
>type : Symbol(B.type, Decl(crashInGetTextOfComputedPropertyName.ts, 2, 20))
|
||||
|
||||
export type AB = A | B
|
||||
>AB : Symbol(AB, Decl(crashInGetTextOfComputedPropertyName.ts, 2, 32))
|
||||
>A : Symbol(A, Decl(crashInGetTextOfComputedPropertyName.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(crashInGetTextOfComputedPropertyName.ts, 1, 32))
|
||||
|
||||
const itemId = 'some-id'
|
||||
>itemId : Symbol(itemId, Decl(crashInGetTextOfComputedPropertyName.ts, 5, 5))
|
||||
|
||||
// --- test on first level ---
|
||||
const items: { [id: string]: AB } = {}
|
||||
>items : Symbol(items, Decl(crashInGetTextOfComputedPropertyName.ts, 8, 5))
|
||||
>id : Symbol(id, Decl(crashInGetTextOfComputedPropertyName.ts, 8, 16))
|
||||
>AB : Symbol(AB, Decl(crashInGetTextOfComputedPropertyName.ts, 2, 32))
|
||||
|
||||
const { [itemId]: itemOk1 } = items
|
||||
>itemId : Symbol(itemId, Decl(crashInGetTextOfComputedPropertyName.ts, 5, 5))
|
||||
>itemOk1 : Symbol(itemOk1, Decl(crashInGetTextOfComputedPropertyName.ts, 9, 7))
|
||||
>items : Symbol(items, Decl(crashInGetTextOfComputedPropertyName.ts, 8, 5))
|
||||
|
||||
typeof itemOk1 // pass
|
||||
>itemOk1 : Symbol(itemOk1, Decl(crashInGetTextOfComputedPropertyName.ts, 9, 7))
|
||||
|
||||
// --- test on second level ---
|
||||
interface ObjWithItems {
|
||||
>ObjWithItems : Symbol(ObjWithItems, Decl(crashInGetTextOfComputedPropertyName.ts, 10, 14))
|
||||
|
||||
items: {[s: string]: AB}
|
||||
>items : Symbol(ObjWithItems.items, Decl(crashInGetTextOfComputedPropertyName.ts, 13, 24))
|
||||
>s : Symbol(s, Decl(crashInGetTextOfComputedPropertyName.ts, 14, 13))
|
||||
>AB : Symbol(AB, Decl(crashInGetTextOfComputedPropertyName.ts, 2, 32))
|
||||
}
|
||||
const objWithItems: ObjWithItems = { items: {}}
|
||||
>objWithItems : Symbol(objWithItems, Decl(crashInGetTextOfComputedPropertyName.ts, 16, 5))
|
||||
>ObjWithItems : Symbol(ObjWithItems, Decl(crashInGetTextOfComputedPropertyName.ts, 10, 14))
|
||||
>items : Symbol(items, Decl(crashInGetTextOfComputedPropertyName.ts, 16, 36))
|
||||
|
||||
const itemOk2 = objWithItems.items[itemId]
|
||||
>itemOk2 : Symbol(itemOk2, Decl(crashInGetTextOfComputedPropertyName.ts, 18, 5))
|
||||
>objWithItems.items : Symbol(ObjWithItems.items, Decl(crashInGetTextOfComputedPropertyName.ts, 13, 24))
|
||||
>objWithItems : Symbol(objWithItems, Decl(crashInGetTextOfComputedPropertyName.ts, 16, 5))
|
||||
>items : Symbol(ObjWithItems.items, Decl(crashInGetTextOfComputedPropertyName.ts, 13, 24))
|
||||
>itemId : Symbol(itemId, Decl(crashInGetTextOfComputedPropertyName.ts, 5, 5))
|
||||
|
||||
typeof itemOk2 // pass
|
||||
>itemOk2 : Symbol(itemOk2, Decl(crashInGetTextOfComputedPropertyName.ts, 18, 5))
|
||||
|
||||
const {
|
||||
items: { [itemId]: itemWithTSError } = {} /*happens when default value is provided*/
|
||||
>items : Symbol(ObjWithItems.items, Decl(crashInGetTextOfComputedPropertyName.ts, 13, 24))
|
||||
>itemId : Symbol(itemId, Decl(crashInGetTextOfComputedPropertyName.ts, 5, 5))
|
||||
>itemWithTSError : Symbol(itemWithTSError, Decl(crashInGetTextOfComputedPropertyName.ts, 22, 12))
|
||||
|
||||
} = objWithItems
|
||||
>objWithItems : Symbol(objWithItems, Decl(crashInGetTextOfComputedPropertyName.ts, 16, 5))
|
||||
|
||||
// in order to re-produce the error, uncomment next line:
|
||||
typeof itemWithTSError // :(
|
||||
>itemWithTSError : Symbol(itemWithTSError, Decl(crashInGetTextOfComputedPropertyName.ts, 22, 12))
|
||||
|
||||
// will result in:
|
||||
// Error from compilation: TypeError: Cannot read property 'charCodeAt' of undefined TypeError: Cannot read property 'charCodeAt' of undefined
|
|
@ -0,0 +1,71 @@
|
|||
=== tests/cases/compiler/crashInGetTextOfComputedPropertyName.ts ===
|
||||
// https://github.com/Microsoft/TypeScript/issues/29006
|
||||
export interface A { type: 'a' }
|
||||
>type : "a"
|
||||
|
||||
export interface B { type: 'b' }
|
||||
>type : "b"
|
||||
|
||||
export type AB = A | B
|
||||
>AB : AB
|
||||
|
||||
const itemId = 'some-id'
|
||||
>itemId : "some-id"
|
||||
>'some-id' : "some-id"
|
||||
|
||||
// --- test on first level ---
|
||||
const items: { [id: string]: AB } = {}
|
||||
>items : { [id: string]: AB; }
|
||||
>id : string
|
||||
>{} : {}
|
||||
|
||||
const { [itemId]: itemOk1 } = items
|
||||
>itemId : "some-id"
|
||||
>itemOk1 : AB
|
||||
>items : { [id: string]: AB; }
|
||||
|
||||
typeof itemOk1 // pass
|
||||
>typeof itemOk1 : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>itemOk1 : AB
|
||||
|
||||
// --- test on second level ---
|
||||
interface ObjWithItems {
|
||||
items: {[s: string]: AB}
|
||||
>items : { [s: string]: AB; }
|
||||
>s : string
|
||||
}
|
||||
const objWithItems: ObjWithItems = { items: {}}
|
||||
>objWithItems : ObjWithItems
|
||||
>{ items: {}} : { items: {}; }
|
||||
>items : {}
|
||||
>{} : {}
|
||||
|
||||
const itemOk2 = objWithItems.items[itemId]
|
||||
>itemOk2 : AB
|
||||
>objWithItems.items[itemId] : AB
|
||||
>objWithItems.items : { [s: string]: AB; }
|
||||
>objWithItems : ObjWithItems
|
||||
>items : { [s: string]: AB; }
|
||||
>itemId : "some-id"
|
||||
|
||||
typeof itemOk2 // pass
|
||||
>typeof itemOk2 : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>itemOk2 : AB
|
||||
|
||||
const {
|
||||
items: { [itemId]: itemWithTSError } = {} /*happens when default value is provided*/
|
||||
>items : any
|
||||
>itemId : "some-id"
|
||||
>itemWithTSError : any
|
||||
>{} : { some-id: any; }
|
||||
|
||||
} = objWithItems
|
||||
>objWithItems : ObjWithItems
|
||||
|
||||
// in order to re-produce the error, uncomment next line:
|
||||
typeof itemWithTSError // :(
|
||||
>typeof itemWithTSError : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>itemWithTSError : any
|
||||
|
||||
// will result in:
|
||||
// Error from compilation: TypeError: Cannot read property 'charCodeAt' of undefined TypeError: Cannot read property 'charCodeAt' of undefined
|
|
@ -1,9 +1,10 @@
|
|||
tests/cases/compiler/destructureComputedProperty.ts(7,7): error TS2341: Property 'p' is private and only accessible within class 'C'.
|
||||
tests/cases/compiler/destructureComputedProperty.ts(8,7): error TS2341: Property 'p' is private and only accessible within class 'C'.
|
||||
tests/cases/compiler/destructureComputedProperty.ts(9,7): error TS2341: Property 'p' is private and only accessible within class 'C'.
|
||||
tests/cases/compiler/destructureComputedProperty.ts(10,7): error TS2341: Property 'p' is private and only accessible within class 'C'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/destructureComputedProperty.ts (3 errors) ====
|
||||
==== tests/cases/compiler/destructureComputedProperty.ts (4 errors) ====
|
||||
declare const ab: { n: number } | { n: string };
|
||||
const nameN = "n";
|
||||
const { [nameN]: n } = ab;
|
||||
|
@ -17,6 +18,8 @@ tests/cases/compiler/destructureComputedProperty.ts(10,7): error TS2341: Propert
|
|||
~~~~~~~~~~~~~
|
||||
!!! error TS2341: Property 'p' is private and only accessible within class 'C'.
|
||||
const { [nameP]: p2 } = new C();
|
||||
~~~~~~~~~~~~~~~
|
||||
!!! error TS2341: Property 'p' is private and only accessible within class 'C'.
|
||||
const { p: p3 } = new C();
|
||||
~~~~~~~~~
|
||||
!!! error TS2341: Property 'p' is private and only accessible within class 'C'.
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
tests/cases/compiler/destructuredLateBoundNameHasCorrectTypes.ts(11,8): error TS2339: Property 'prop2' does not exist on type '{ prop: string; }'.
|
||||
tests/cases/compiler/destructuredLateBoundNameHasCorrectTypes.ts(11,21): error TS2525: Initializer provides no value for this binding element and the binding element has no default value.
|
||||
tests/cases/compiler/destructuredLateBoundNameHasCorrectTypes.ts(11,37): error TS2353: Object literal may only specify known properties, and 'prop' does not exist in type '{ prop2: any; }'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/destructuredLateBoundNameHasCorrectTypes.ts (1 errors) ====
|
||||
==== tests/cases/compiler/destructuredLateBoundNameHasCorrectTypes.ts (2 errors) ====
|
||||
let { [Symbol.iterator]: destructured } = [];
|
||||
void destructured;
|
||||
|
||||
|
@ -13,6 +14,8 @@ tests/cases/compiler/destructuredLateBoundNameHasCorrectTypes.ts(11,8): error TS
|
|||
const notPresent = "prop2";
|
||||
|
||||
let { [notPresent]: computed2 } = { prop: "b" };
|
||||
~~~~~~~~~~
|
||||
!!! error TS2339: Property 'prop2' does not exist on type '{ prop: string; }'.
|
||||
~~~~~~~~~
|
||||
!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value.
|
||||
~~~~
|
||||
!!! error TS2353: Object literal may only specify known properties, and 'prop' does not exist in type '{ prop2: any; }'.
|
||||
|
|
@ -32,7 +32,7 @@ const notPresent = "prop2";
|
|||
let { [notPresent]: computed2 } = { prop: "b" };
|
||||
>notPresent : "prop2"
|
||||
>computed2 : any
|
||||
>{ prop: "b" } : { prop: string; }
|
||||
>{ prop: "b" } : { prop: string; prop2: any; }
|
||||
>prop : string
|
||||
>"b" : "b"
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
tests/cases/compiler/destructuringAssignment_private.ts(6,10): error TS2341: Property 'x' is private and only accessible within class 'C'.
|
||||
tests/cases/compiler/destructuringAssignment_private.ts(7,4): error TS2341: Property 'o' is private and only accessible within class 'C'.
|
||||
tests/cases/compiler/destructuringAssignment_private.ts(10,10): error TS2341: Property 'x' is private and only accessible within class 'C'.
|
||||
tests/cases/compiler/destructuringAssignment_private.ts(13,4): error TS2341: Property 'o' is private and only accessible within class 'C'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/destructuringAssignment_private.ts (2 errors) ====
|
||||
==== tests/cases/compiler/destructuringAssignment_private.ts (4 errors) ====
|
||||
class C {
|
||||
private x = 0;
|
||||
private o = [{ a: 1 }];
|
||||
|
@ -14,4 +16,14 @@ tests/cases/compiler/destructuringAssignment_private.ts(7,4): error TS2341: Prop
|
|||
({ o: [{ a: x }]} = new C());
|
||||
~
|
||||
!!! error TS2341: Property 'o' is private and only accessible within class 'C'.
|
||||
|
||||
const nameX = "x";
|
||||
([{ a: { [nameX]: x } }] = [{ a: new C() }]);
|
||||
~~~~~~~
|
||||
!!! error TS2341: Property 'x' is private and only accessible within class 'C'.
|
||||
|
||||
const nameO = "o";
|
||||
({ [nameO]: [{ a: x }]} = new C());
|
||||
~~~~~~~
|
||||
!!! error TS2341: Property 'o' is private and only accessible within class 'C'.
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue