mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into definitionSpan
This commit is contained in:
@@ -44,6 +44,7 @@ scripts/ior.js
|
||||
scripts/authors.js
|
||||
scripts/configurePrerelease.js
|
||||
scripts/open-user-pr.js
|
||||
scripts/open-cherry-pick-pr.js
|
||||
scripts/processDiagnosticMessages.d.ts
|
||||
scripts/processDiagnosticMessages.js
|
||||
scripts/produceLKG.js
|
||||
|
||||
+4
-1
@@ -2,7 +2,7 @@
|
||||
"name": "typescript",
|
||||
"author": "Microsoft Corp.",
|
||||
"homepage": "https://www.typescriptlang.org/",
|
||||
"version": "3.5.0",
|
||||
"version": "3.6.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "TypeScript is a language for application scale JavaScript development",
|
||||
"keywords": [
|
||||
@@ -48,11 +48,13 @@
|
||||
"@types/mocha": "latest",
|
||||
"@types/ms": "latest",
|
||||
"@types/node": "8.5.5",
|
||||
"@types/node-fetch": "^2.3.4",
|
||||
"@types/q": "latest",
|
||||
"@types/source-map-support": "latest",
|
||||
"@types/through2": "latest",
|
||||
"@types/travis-fold": "latest",
|
||||
"@types/xml2js": "^0.4.0",
|
||||
"azure-devops-node-api": "^8.0.0",
|
||||
"browser-resolve": "^1.11.2",
|
||||
"browserify": "latest",
|
||||
"chai": "latest",
|
||||
@@ -74,6 +76,7 @@
|
||||
"mocha": "latest",
|
||||
"mocha-fivemat-progress-reporter": "latest",
|
||||
"ms": "latest",
|
||||
"node-fetch": "^2.6.0",
|
||||
"plugin-error": "latest",
|
||||
"pretty-hrtime": "^1.0.3",
|
||||
"prex": "^0.4.3",
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/// <reference lib="esnext.asynciterable" />
|
||||
// Must reference esnext.asynciterable lib, since octokit uses AsyncIterable internally
|
||||
/// <reference types="node" />
|
||||
|
||||
import Octokit = require("@octokit/rest");
|
||||
const {runSequence} = require("./run-sequence");
|
||||
import fs = require("fs");
|
||||
import path = require("path");
|
||||
|
||||
const userName = process.env.GH_USERNAME;
|
||||
const reviewers = process.env.REQUESTING_USER ? [process.env.REQUESTING_USER] : ["weswigham", "RyanCavanaugh"];
|
||||
const branchName = `pick/${process.env.SOURCE_ISSUE}/${process.env.TARGET_BRANCH}`;
|
||||
const remoteUrl = `https://${process.argv[2]}@github.com/${userName}/TypeScript.git`;
|
||||
|
||||
async function main() {
|
||||
if (!process.env.TARGET_BRANCH) {
|
||||
throw new Error("Target branch not specified");
|
||||
}
|
||||
if (!process.env.SOURCE_ISSUE) {
|
||||
throw new Error("Source issue not specified");
|
||||
}
|
||||
const currentSha = runSequence([
|
||||
["git", ["rev-parse", "HEAD"]]
|
||||
]);
|
||||
const currentAuthor = runSequence([
|
||||
["git", ["log", "-1", `--pretty="%aN <%aE>"`]]
|
||||
]);
|
||||
runSequence([
|
||||
["git", ["fetch", "origin", "master"]]
|
||||
]);
|
||||
let logText = runSequence([
|
||||
["git", ["log", `origin/master..${currentSha.trim()}`, `--pretty="%h %s%n%b"`, "--reverse"]]
|
||||
]);
|
||||
logText = `Cherry-pick PR #${process.env.SOURCE_ISSUE} into ${process.env.TARGET_BRANCH}
|
||||
|
||||
Component commits:
|
||||
${logText.trim()}`
|
||||
const logpath = path.join(__dirname, "../", "logmessage.txt");
|
||||
runSequence([
|
||||
["git", ["checkout", "-b", "temp-branch"]],
|
||||
["git", ["reset", "origin/master", "--soft"]]
|
||||
]);
|
||||
fs.writeFileSync(logpath, logText);
|
||||
runSequence([
|
||||
["git", ["commit", "-F", logpath, `--author="${currentAuthor.trim()}"`]]
|
||||
]);
|
||||
fs.unlinkSync(logpath);
|
||||
const squashSha = runSequence([
|
||||
["git", ["rev-parse", "HEAD"]]
|
||||
]);
|
||||
runSequence([
|
||||
["git", ["checkout", process.env.TARGET_BRANCH]], // checkout the target branch
|
||||
["git", ["checkout", "-b", branchName]], // create a new branch
|
||||
["git", ["cherry-pick", squashSha.trim()]], //
|
||||
["git", ["remote", "add", "fork", remoteUrl]], // Add the remote fork
|
||||
["git", ["push", "--set-upstream", "fork", branchName, "-f"]] // push the branch
|
||||
]);
|
||||
|
||||
const gh = new Octokit();
|
||||
gh.authenticate({
|
||||
type: "token",
|
||||
token: process.argv[2]
|
||||
});
|
||||
const r = await gh.pulls.create({
|
||||
owner: "Microsoft",
|
||||
repo: "TypeScript",
|
||||
maintainer_can_modify: true,
|
||||
title: `🤖 Cherry-pick PR #${process.env.SOURCE_ISSUE} into ${process.env.TARGET_BRANCH}`,
|
||||
head: `${userName}:${branchName}`,
|
||||
base: process.env.TARGET_BRANCH,
|
||||
body:
|
||||
`This cherry-pick was triggerd by a request on https://github.com/Microsoft/TypeScript/pull/${process.env.SOURCE_ISSUE}
|
||||
Please review the diff and merge if no changes are unexpected.
|
||||
You can view the cherry-pick log [here](https://typescript.visualstudio.com/TypeScript/_build/index?buildId=${process.env.BUILD_BUILDID}&_a=summary).
|
||||
|
||||
cc ${reviewers.map(r => "@" + r).join(" ")}`,
|
||||
});
|
||||
const num = r.data.number;
|
||||
console.log(`Pull request ${num} created.`);
|
||||
|
||||
await gh.issues.createComment({
|
||||
number: +process.env.SOURCE_ISSUE,
|
||||
owner: "Microsoft",
|
||||
repo: "TypeScript",
|
||||
body: `Hey @${process.env.REQUESTING_USER}, I've opened #${num} for you.`
|
||||
});
|
||||
}
|
||||
|
||||
main().catch(async e => {
|
||||
console.error(e);
|
||||
process.exitCode = 1;
|
||||
if (process.env.SOURCE_ISSUE) {
|
||||
const gh = new Octokit();
|
||||
gh.authenticate({
|
||||
type: "token",
|
||||
token: process.argv[2]
|
||||
});
|
||||
await gh.issues.createComment({
|
||||
number: +process.env.SOURCE_ISSUE,
|
||||
owner: "Microsoft",
|
||||
repo: "TypeScript",
|
||||
body: `Hey @${process.env.REQUESTING_USER}, I couldn't open a PR with the cherry-pick. ([You can check the log here](https://typescript.visualstudio.com/TypeScript/_build/index?buildId=${process.env.BUILD_BUILDID}&_a=summary)). You may need to squash and pick this PR into ${process.env.TARGET_BRANCH} manually.`
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -9,7 +9,7 @@ function padNum(number: number) {
|
||||
}
|
||||
|
||||
const userName = process.env.GH_USERNAME;
|
||||
const reviewers = process.env.requesting_user ? [process.env.requesting_user] : ["weswigham", "sandersn", "RyanCavanaugh"];
|
||||
const reviewers = process.env.REQUESTING_USER ? [process.env.REQUESTING_USER] : ["weswigham", "sandersn", "RyanCavanaugh"];
|
||||
const now = new Date();
|
||||
const branchName = `user-update-${process.env.TARGET_FORK}-${now.getFullYear()}${padNum(now.getMonth())}${padNum(now.getDay())}${process.env.TARGET_BRANCH ? "-" + process.env.TARGET_BRANCH : ""}`;
|
||||
const remoteUrl = `https://${process.argv[2]}@github.com/${userName}/TypeScript.git`;
|
||||
@@ -36,14 +36,14 @@ gh.pulls.create({
|
||||
head: `${userName}:${branchName}`,
|
||||
base: process.env.TARGET_BRANCH || "master",
|
||||
body:
|
||||
`${process.env.source_issue ? `This test run was triggerd by a request on https://github.com/Microsoft/TypeScript/pull/${process.env.source_issue} `+"\n" : ""}Please review the diff and merge if no changes are unexpected.
|
||||
`${process.env.SOURCE_ISSUE ? `This test run was triggerd by a request on https://github.com/Microsoft/TypeScript/pull/${process.env.SOURCE_ISSUE} `+"\n" : ""}Please review the diff and merge if no changes are unexpected.
|
||||
You can view the build log [here](https://typescript.visualstudio.com/TypeScript/_build/index?buildId=${process.env.BUILD_BUILDID}&_a=summary).
|
||||
|
||||
cc ${reviewers.map(r => "@" + r).join(" ")}`,
|
||||
}).then(async r => {
|
||||
const num = r.data.number;
|
||||
console.log(`Pull request ${num} created.`);
|
||||
if (!process.env.source_issue) {
|
||||
if (!process.env.SOURCE_ISSUE) {
|
||||
await gh.pulls.createReviewRequest({
|
||||
owner: process.env.TARGET_FORK,
|
||||
repo: "TypeScript",
|
||||
@@ -53,7 +53,7 @@ cc ${reviewers.map(r => "@" + r).join(" ")}`,
|
||||
}
|
||||
else {
|
||||
await gh.issues.createComment({
|
||||
number: +process.env.source_issue,
|
||||
number: +process.env.SOURCE_ISSUE,
|
||||
owner: "Microsoft",
|
||||
repo: "TypeScript",
|
||||
body: `The user suite test run you requested has finished and _failed_. I've opened a [PR with the baseline diff from master](${r.data.html_url}).`
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
// @ts-check
|
||||
/// <reference lib="esnext.asynciterable" />
|
||||
// Must reference esnext.asynciterable lib, since octokit uses AsyncIterable internally
|
||||
const Octokit = require("@octokit/rest");
|
||||
const ado = require("azure-devops-node-api");
|
||||
const { default: fetch } = require("node-fetch");
|
||||
|
||||
async function main() {
|
||||
if (!process.env.SOURCE_ISSUE) {
|
||||
throw new Error("No source issue specified");
|
||||
}
|
||||
if (!process.env.BUILD_BUILDID) {
|
||||
throw new Error("No build ID specified");
|
||||
}
|
||||
// The pipelines API does _not_ make getting the direct URL to a specific file _within_ an artifact trivial
|
||||
const cli = new ado.WebApi("https://typescript.visualstudio.com/defaultcollection", ado.getHandlerFromToken("")); // Empty token, anon auth
|
||||
const build = await cli.getBuildApi();
|
||||
const artifact = await build.getArtifact("typescript", +process.env.BUILD_BUILDID, "tgz");
|
||||
const updatedUrl = new URL(artifact.resource.url);
|
||||
updatedUrl.search = `artifactName=tgz&fileId=${artifact.resource.data}&fileName=manifest`;
|
||||
const resp = await (await fetch(`${updatedUrl}`)).json();
|
||||
const file = resp.items[0];
|
||||
const tgzUrl = new URL(artifact.resource.url);
|
||||
tgzUrl.search = `artifactName=tgz&fileId=${file.blob.id}&fileName=${file.path}`;
|
||||
const link = "" + tgzUrl;
|
||||
const gh = new Octokit();
|
||||
gh.authenticate({
|
||||
type: "token",
|
||||
token: process.argv[2]
|
||||
});
|
||||
await gh.issues.createComment({
|
||||
number: +process.env.SOURCE_ISSUE,
|
||||
owner: "Microsoft",
|
||||
repo: "TypeScript",
|
||||
body: `Hey @${process.env.REQUESTING_USER}, I've packed this into [an installable tgz](${link}). You can install it for testing by referencing it in your \`package.json\` like so:
|
||||
\`\`\`
|
||||
{
|
||||
"devDependencies": {
|
||||
"typescript": "${link}"
|
||||
}
|
||||
}
|
||||
\`\`\`
|
||||
and then running \`npm install\`.
|
||||
`
|
||||
});
|
||||
}
|
||||
|
||||
main().catch(async e => {
|
||||
console.error(e);
|
||||
process.exitCode = 1;
|
||||
if (process.env.SOURCE_ISSUE) {
|
||||
const gh = new Octokit();
|
||||
gh.authenticate({
|
||||
type: "token",
|
||||
token: process.argv[2]
|
||||
});
|
||||
await gh.issues.createComment({
|
||||
number: +process.env.SOURCE_ISSUE,
|
||||
owner: "Microsoft",
|
||||
repo: "TypeScript",
|
||||
body: `Hey @${process.env.REQUESTING_USER}, something went wrong when looking for the build artifact. ([You can check the log here](https://typescript.visualstudio.com/TypeScript/_build/index?buildId=${process.env.BUILD_BUILDID}&_a=summary)).`
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -5,12 +5,13 @@ const cp = require("child_process");
|
||||
* @param {[string, string[]][]} tasks
|
||||
* @param {cp.SpawnSyncOptions} opts
|
||||
*/
|
||||
function runSequence(tasks, opts = { timeout: 100000, shell: true, stdio: "inherit" }) {
|
||||
function runSequence(tasks, opts = { timeout: 100000, shell: true }) {
|
||||
let lastResult;
|
||||
for (const task of tasks) {
|
||||
console.log(`${task[0]} ${task[1].join(" ")}`);
|
||||
const result = cp.spawnSync(task[0], task[1], opts);
|
||||
if (result.status !== 0) throw new Error(`${task[0]} ${task[1].join(" ")} failed: ${result.stderr && result.stderr.toString()}`);
|
||||
console.log(result.stdout && result.stdout.toString());
|
||||
lastResult = result;
|
||||
}
|
||||
return lastResult && lastResult.stdout && lastResult.stdout.toString();
|
||||
|
||||
@@ -1,87 +1,91 @@
|
||||
// @ts-check
|
||||
/// <reference lib="esnext.asynciterable" />
|
||||
const Octokit = require("@octokit/rest");
|
||||
const {runSequence} = require("./run-sequence");
|
||||
const { runSequence } = require("./run-sequence");
|
||||
|
||||
// The first is used by bot-based kickoffs, the second by automatic triggers
|
||||
const triggeredPR = process.env.SOURCE_ISSUE || process.env.SYSTEM_PULLREQUEST_PULLREQUESTNUMBER;
|
||||
|
||||
/**
|
||||
* This program should be invoked as `node ./scripts/update-experimental-branches <GithubAccessToken> <Branch1> [Branch2] [...]`
|
||||
* This program should be invoked as `node ./scripts/update-experimental-branches <GithubAccessToken> <PR1> [PR2] [...]`
|
||||
* The order PR numbers are passed controls the order in which they are merged together.
|
||||
* TODO: the following is racey - if two experiment-enlisted PRs trigger simultaneously and witness one another in an unupdated state, they'll both produce
|
||||
* a new experimental branch, but each will be missing a change from the other. There's no _great_ way to fix this beyond setting the maximum concurrency
|
||||
* of this task to 1 (so only one job is allowed to update experiments at a time).
|
||||
*/
|
||||
async function main() {
|
||||
const branchesRaw = process.argv[3];
|
||||
const branches = process.argv.slice(3);
|
||||
if (!branches.length) {
|
||||
throw new Error(`No experimental branches, aborting...`);
|
||||
const prnums = process.argv.slice(3);
|
||||
if (!prnums.length) {
|
||||
return; // No enlisted PRs, nothing to update
|
||||
}
|
||||
console.log(`Performing experimental branch updating and merging for branches ${branchesRaw}`);
|
||||
if (!prnums.some(n => n === triggeredPR)) {
|
||||
return; // Only have work to do for enlisted PRs
|
||||
}
|
||||
console.log(`Performing experimental branch updating and merging for pull requests ${prnums.join(", ")}`);
|
||||
|
||||
const userName = process.env.GH_USERNAME;
|
||||
const remoteUrl = `https://${process.argv[2]}@github.com/${userName}/TypeScript.git`;
|
||||
|
||||
const gh = new Octokit();
|
||||
gh.authenticate({
|
||||
type: "token",
|
||||
token: process.argv[2]
|
||||
});
|
||||
|
||||
// Fetch all relevant refs
|
||||
runSequence([
|
||||
["git", ["fetch", "origin", "master:master", ...branches.map(b => `${b}:${b}`)]]
|
||||
])
|
||||
|
||||
// Forcibly cleanup workspace
|
||||
runSequence([
|
||||
["git", ["clean", "-fdx"]],
|
||||
["git", ["checkout", "."]],
|
||||
["git", ["fetch", "-fu", "origin", "master:master"]],
|
||||
["git", ["checkout", "master"]],
|
||||
["git", ["remote", "add", "fork", remoteUrl]], // Add the remote fork
|
||||
]);
|
||||
|
||||
// Update branches
|
||||
for (const branch of branches) {
|
||||
// Checkout, then get the merge base
|
||||
const mergeBase = runSequence([
|
||||
["git", ["checkout", branch]],
|
||||
["git", ["merge-base", branch, "master"]],
|
||||
]);
|
||||
// Simulate the merge and abort if there are conflicts
|
||||
const mergeTree = runSequence([
|
||||
["git", ["merge-tree", mergeBase, branch, "master"]]
|
||||
]);
|
||||
if (mergeTree.indexOf(`===${"="}===`)) { // 7 equals is the center of the merge conflict marker
|
||||
const res = await gh.pulls.list({owner: "Microsoft", repo: "TypeScript", base: branch});
|
||||
if (res && res.data && res.data[0]) {
|
||||
const pr = res.data[0];
|
||||
await gh.issues.createComment({
|
||||
owner: "Microsoft",
|
||||
repo: "TypeScript",
|
||||
number: pr.number,
|
||||
body: `This PR is configured as an experiment, and currently has merge conflicts with master - please rebase onto master and fix the conflicts.`
|
||||
});
|
||||
|
||||
const gh = new Octokit({
|
||||
auth: process.argv[2]
|
||||
});
|
||||
for (const numRaw of prnums) {
|
||||
const num = +numRaw;
|
||||
if (num) {
|
||||
// PR number rather than branch name - lookup info
|
||||
const inputPR = await gh.pulls.get({ owner: "Microsoft", repo: "TypeScript", pull_number: num });
|
||||
// GH calculates the rebaseable-ness of a PR into its target, so we can just use that here
|
||||
if (!inputPR.data.rebaseable) {
|
||||
if (+triggeredPR === num) {
|
||||
await gh.issues.createComment({
|
||||
owner: "Microsoft",
|
||||
repo: "TypeScript",
|
||||
issue_number: num,
|
||||
body: `This PR is configured as an experiment, and currently has rebase conflicts with master - please rebase onto master and fix the conflicts.`
|
||||
});
|
||||
throw new Error(`Rebase conflict detected in PR ${num} with master`);
|
||||
}
|
||||
return; // A PR is currently in conflict, give up
|
||||
}
|
||||
throw new Error(`Merge conflict detected on branch ${branch} with master`);
|
||||
runSequence([
|
||||
["git", ["fetch", "origin", `pull/${num}/head:${num}`]],
|
||||
["git", ["checkout", `${num}`]],
|
||||
["git", ["rebase", "master"]],
|
||||
["git", ["push", "-f", "-u", "fork", `${num}`]], // Keep a rebased copy of this branch in our fork
|
||||
]);
|
||||
|
||||
}
|
||||
else {
|
||||
throw new Error(`Invalid PR number: ${numRaw}`);
|
||||
}
|
||||
// Merge is good - apply a rebase and (force) push
|
||||
runSequence([
|
||||
["git", ["rebase", "master"]],
|
||||
["git", ["push", "-f", "-u", "origin", branch]],
|
||||
]);
|
||||
}
|
||||
|
||||
// Return to `master` and make a new `experimental` branch
|
||||
runSequence([
|
||||
["git", ["checkout", "master"]],
|
||||
["git", ["branch", "-D", "experimental"]],
|
||||
["git", ["checkout", "-b", "experimental"]],
|
||||
]);
|
||||
|
||||
// Merge each branch into `experimental` (which, if there is a conflict, we now know is from inter-experiment conflict)
|
||||
for (const branch of branches) {
|
||||
for (const branch of prnums) {
|
||||
// Find the merge base
|
||||
const mergeBase = runSequence([
|
||||
["git", ["merge-base", branch, "experimental"]],
|
||||
]);
|
||||
// Simulate the merge and abort if there are conflicts
|
||||
const mergeTree = runSequence([
|
||||
["git", ["merge-tree", mergeBase, branch, "experimental"]]
|
||||
["git", ["merge-tree", mergeBase.trim(), branch, "experimental"]]
|
||||
]);
|
||||
if (mergeTree.indexOf(`===${"="}===`)) { // 7 equals is the center of the merge conflict marker
|
||||
throw new Error(`Merge conflict detected on branch ${branch} with other experiment`);
|
||||
if (mergeTree.indexOf(`===${"="}===`) >= 0) { // 7 equals is the center of the merge conflict marker
|
||||
throw new Error(`Merge conflict detected involving PR ${branch} with other experiment`);
|
||||
}
|
||||
// Merge (always producing a merge commit)
|
||||
runSequence([
|
||||
@@ -90,7 +94,7 @@ async function main() {
|
||||
}
|
||||
// Every branch merged OK, force push the replacement `experimental` branch
|
||||
runSequence([
|
||||
["git", ["push", "-f", "-u", "origin", "experimental"]],
|
||||
["git", ["push", "-f", "-u", "fork", "experimental"]],
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
+10
-11
@@ -3229,8 +3229,7 @@ namespace ts {
|
||||
// A ClassDeclaration is ES6 syntax.
|
||||
transformFlags = subtreeFlags | TransformFlags.AssertES2015;
|
||||
|
||||
// A class with a parameter property assignment, property initializer, computed property name, or decorator is
|
||||
// TypeScript syntax.
|
||||
// A class with a parameter property assignment or decorator is TypeScript syntax.
|
||||
// An exported declaration may be TypeScript syntax, but is handled by the visitor
|
||||
// for a namespace declaration.
|
||||
if ((subtreeFlags & TransformFlags.ContainsTypeScriptClassSyntax)
|
||||
@@ -3247,8 +3246,7 @@ namespace ts {
|
||||
// A ClassExpression is ES6 syntax.
|
||||
let transformFlags = subtreeFlags | TransformFlags.AssertES2015;
|
||||
|
||||
// A class with a parameter property assignment, property initializer, or decorator is
|
||||
// TypeScript syntax.
|
||||
// A class with a parameter property assignment or decorator is TypeScript syntax.
|
||||
if (subtreeFlags & TransformFlags.ContainsTypeScriptClassSyntax
|
||||
|| node.typeParameters) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
@@ -3338,7 +3336,6 @@ namespace ts {
|
||||
|| hasModifier(node, ModifierFlags.TypeScriptModifier)
|
||||
|| node.typeParameters
|
||||
|| node.type
|
||||
|| (node.name && isComputedPropertyName(node.name)) // While computed method names aren't typescript, the TS transform must visit them to emit property declarations correctly
|
||||
|| !node.body) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
@@ -3369,7 +3366,6 @@ namespace ts {
|
||||
if (node.decorators
|
||||
|| hasModifier(node, ModifierFlags.TypeScriptModifier)
|
||||
|| node.type
|
||||
|| (node.name && isComputedPropertyName(node.name)) // While computed accessor names aren't typescript, the TS transform must visit them to emit property declarations correctly
|
||||
|| !node.body) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
@@ -3384,12 +3380,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
function computePropertyDeclaration(node: PropertyDeclaration, subtreeFlags: TransformFlags) {
|
||||
// A PropertyDeclaration is TypeScript syntax.
|
||||
let transformFlags = subtreeFlags | TransformFlags.AssertTypeScript;
|
||||
let transformFlags = subtreeFlags | TransformFlags.ContainsClassFields;
|
||||
|
||||
// If the PropertyDeclaration has an initializer or a computed name, we need to inform its ancestor
|
||||
// so that it handle the transformation.
|
||||
if (node.initializer || isComputedPropertyName(node.name)) {
|
||||
// Decorators, TypeScript-specific modifiers, and type annotations are TypeScript syntax.
|
||||
if (some(node.decorators) || hasModifier(node, ModifierFlags.TypeScriptModifier) || node.type) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
// Hoisted variables related to class properties should live within the TypeScript class wrapper.
|
||||
if (isComputedPropertyName(node.name) || (hasStaticModifier(node) && node.initializer)) {
|
||||
transformFlags |= TransformFlags.ContainsTypeScriptClassSyntax;
|
||||
}
|
||||
|
||||
|
||||
+10
-14
@@ -796,6 +796,7 @@ namespace ts {
|
||||
(result as SemanticDiagnosticsBuilderProgram).getSemanticDiagnosticsOfNextAffectedFile = getSemanticDiagnosticsOfNextAffectedFile;
|
||||
}
|
||||
else if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) {
|
||||
(result as EmitAndSemanticDiagnosticsBuilderProgram).getSemanticDiagnosticsOfNextAffectedFile = getSemanticDiagnosticsOfNextAffectedFile;
|
||||
(result as EmitAndSemanticDiagnosticsBuilderProgram).emitNextAffectedFile = emitNextAffectedFile;
|
||||
}
|
||||
else {
|
||||
@@ -913,6 +914,11 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
// Add file to affected file pending emit to handle for later emit time
|
||||
if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) {
|
||||
addToAffectedFilesPendingEmit(state, [(affected as SourceFile).path]);
|
||||
}
|
||||
|
||||
// Get diagnostics for the affected file if its not ignored
|
||||
if (ignoreSourceFile && ignoreSourceFile(affected as SourceFile)) {
|
||||
// Get next affected file
|
||||
@@ -951,18 +957,8 @@ namespace ts {
|
||||
|
||||
// When semantic builder asks for diagnostics of the whole program,
|
||||
// ensure that all the affected files are handled
|
||||
let affected: SourceFile | Program | undefined;
|
||||
let affectedFilesPendingEmit: Path[] | undefined;
|
||||
while (affected = getNextAffectedFile(state, cancellationToken, computeHash)) {
|
||||
if (affected !== state.program && kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) {
|
||||
(affectedFilesPendingEmit || (affectedFilesPendingEmit = [])).push((affected as SourceFile).path);
|
||||
}
|
||||
doneWithAffectedFile(state, affected);
|
||||
}
|
||||
|
||||
// In case of emit builder, cache the files to be emitted
|
||||
if (affectedFilesPendingEmit) {
|
||||
addToAffectedFilesPendingEmit(state, affectedFilesPendingEmit);
|
||||
// tslint:disable-next-line no-empty
|
||||
while (getSemanticDiagnosticsOfNextAffectedFile(cancellationToken)) {
|
||||
}
|
||||
|
||||
let diagnostics: Diagnostic[] | undefined;
|
||||
@@ -997,7 +993,7 @@ namespace ts {
|
||||
return map;
|
||||
}
|
||||
|
||||
export function createBuildProgramUsingProgramBuildInfo(program: ProgramBuildInfo): EmitAndSemanticDiagnosticsBuilderProgram & SemanticDiagnosticsBuilderProgram {
|
||||
export function createBuildProgramUsingProgramBuildInfo(program: ProgramBuildInfo): EmitAndSemanticDiagnosticsBuilderProgram {
|
||||
const fileInfos = createMapFromTemplate(program.fileInfos);
|
||||
const state: ReusableBuilderProgramState = {
|
||||
fileInfos,
|
||||
@@ -1181,7 +1177,7 @@ namespace ts {
|
||||
* The builder that can handle the changes in program and iterate through changed file to emit the files
|
||||
* The semantic diagnostics are cached per file and managed by clearing for the changed/affected files
|
||||
*/
|
||||
export interface EmitAndSemanticDiagnosticsBuilderProgram extends BuilderProgram {
|
||||
export interface EmitAndSemanticDiagnosticsBuilderProgram extends SemanticDiagnosticsBuilderProgram {
|
||||
/**
|
||||
* Emits the next affected file's emit result (EmitResult and sourceFiles emitted) or returns undefined if iteration is complete
|
||||
* The first of writeFile if provided, writeFile of BuilderProgramHost if provided, writeFile of compiler host
|
||||
|
||||
+231
-84
@@ -182,6 +182,10 @@ namespace ts {
|
||||
node = getParseTreeNode(node);
|
||||
return node ? getTypeOfNode(node) : errorType;
|
||||
},
|
||||
getTypeOfAssignmentPattern: nodeIn => {
|
||||
const node = getParseTreeNode(nodeIn, isAssignmentPattern);
|
||||
return node && getTypeOfAssignmentPattern(node) || errorType;
|
||||
},
|
||||
getPropertySymbolOfDestructuringAssignment: locationIn => {
|
||||
const location = getParseTreeNode(locationIn, isIdentifier);
|
||||
return location ? getPropertySymbolOfDestructuringAssignment(location) : undefined;
|
||||
@@ -5227,7 +5231,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
// Use contextual parameter type if one is available
|
||||
const type = declaration.symbol.escapedName === InternalSymbolName.This ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration);
|
||||
const type = declaration.symbol.escapedName === InternalSymbolName.This ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration, /*forCache*/ true);
|
||||
if (type) {
|
||||
return addOptionality(type, isOptional);
|
||||
}
|
||||
@@ -5917,7 +5921,20 @@ namespace ts {
|
||||
return anyType;
|
||||
}
|
||||
|
||||
function getTypeOfSymbolWithDeferredType(symbol: Symbol) {
|
||||
const links = getSymbolLinks(symbol);
|
||||
if (!links.type) {
|
||||
Debug.assertDefined(links.deferralParent);
|
||||
Debug.assertDefined(links.deferralConstituents);
|
||||
links.type = links.deferralParent!.flags & TypeFlags.Union ? getUnionType(links.deferralConstituents!) : getIntersectionType(links.deferralConstituents!);
|
||||
}
|
||||
return links.type;
|
||||
}
|
||||
|
||||
function getTypeOfSymbol(symbol: Symbol): Type {
|
||||
if (getCheckFlags(symbol) & CheckFlags.DeferredType) {
|
||||
return getTypeOfSymbolWithDeferredType(symbol);
|
||||
}
|
||||
if (getCheckFlags(symbol) & CheckFlags.Instantiated) {
|
||||
return getTypeOfInstantiatedSymbol(symbol);
|
||||
}
|
||||
@@ -7052,10 +7069,10 @@ namespace ts {
|
||||
// Union the result types when more than one signature matches
|
||||
if (unionSignatures.length > 1) {
|
||||
let thisParameter = signature.thisParameter;
|
||||
if (forEach(unionSignatures, sig => sig.thisParameter)) {
|
||||
// TODO: GH#18217 We tested that *some* has thisParameter and now act as if *all* do
|
||||
const firstThisParameterOfUnionSignatures = forEach(unionSignatures, sig => sig.thisParameter);
|
||||
if (firstThisParameterOfUnionSignatures) {
|
||||
const thisType = getUnionType(map(unionSignatures, sig => sig.thisParameter ? getTypeOfSymbol(sig.thisParameter) : anyType), UnionReduction.Subtype);
|
||||
thisParameter = createSymbolWithType(signature.thisParameter!, thisType);
|
||||
thisParameter = createSymbolWithType(firstThisParameterOfUnionSignatures, thisType);
|
||||
}
|
||||
s = createUnionSignature(signature, unionSignatures);
|
||||
s.thisParameter = thisParameter;
|
||||
@@ -7299,7 +7316,8 @@ namespace ts {
|
||||
stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
|
||||
}
|
||||
}
|
||||
const numberIndexInfo = symbol.flags & SymbolFlags.Enum ? enumNumberIndexInfo : undefined;
|
||||
const numberIndexInfo = symbol.flags & SymbolFlags.Enum && (getDeclaredTypeOfSymbol(symbol).flags & TypeFlags.Enum ||
|
||||
some(type.properties, prop => !!(getTypeOfSymbol(prop).flags & TypeFlags.NumberLike))) ? enumNumberIndexInfo : undefined;
|
||||
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
|
||||
// We resolve the members before computing the signatures because a signature may use
|
||||
// typeof with a qualified name expression that circularly references the type we are
|
||||
@@ -7999,10 +8017,13 @@ namespace ts {
|
||||
else if (isUnion) {
|
||||
const indexInfo = !isLateBoundName(name) && (isNumericLiteralName(name) && getIndexInfoOfType(type, IndexKind.Number) || getIndexInfoOfType(type, IndexKind.String));
|
||||
if (indexInfo) {
|
||||
checkFlags |= indexInfo.isReadonly ? CheckFlags.Readonly : 0;
|
||||
checkFlags |= CheckFlags.WritePartial;
|
||||
checkFlags |= CheckFlags.WritePartial | (indexInfo.isReadonly ? CheckFlags.Readonly : 0);
|
||||
indexTypes = append(indexTypes, isTupleType(type) ? getRestTypeOfTupleType(type) || undefinedType : indexInfo.type);
|
||||
}
|
||||
else if (isObjectLiteralType(type)) {
|
||||
checkFlags |= CheckFlags.WritePartial;
|
||||
indexTypes = append(indexTypes, undefinedType);
|
||||
}
|
||||
else {
|
||||
checkFlags |= CheckFlags.ReadPartial;
|
||||
}
|
||||
@@ -8057,7 +8078,15 @@ namespace ts {
|
||||
|
||||
result.declarations = declarations!;
|
||||
result.nameType = nameType;
|
||||
result.type = isUnion ? getUnionType(propTypes) : getIntersectionType(propTypes);
|
||||
if (propTypes.length > 2) {
|
||||
// When `propTypes` has the potential to explode in size when normalized, defer normalization until absolutely needed
|
||||
result.checkFlags |= CheckFlags.DeferredType;
|
||||
result.deferralParent = containingType;
|
||||
result.deferralConstituents = propTypes;
|
||||
}
|
||||
else {
|
||||
result.type = isUnion ? getUnionType(propTypes) : getIntersectionType(propTypes);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -8166,6 +8195,9 @@ namespace ts {
|
||||
propTypes.push(getTypeOfSymbol(prop));
|
||||
}
|
||||
}
|
||||
if (kind === IndexKind.String) {
|
||||
append(propTypes, getIndexTypeOfType(type, IndexKind.Number));
|
||||
}
|
||||
if (propTypes.length) {
|
||||
return getUnionType(propTypes, UnionReduction.Subtype);
|
||||
}
|
||||
@@ -9908,6 +9940,12 @@ namespace ts {
|
||||
else {
|
||||
// We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
|
||||
// the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
|
||||
// If the estimated size of the resulting union type exceeds 100000 constituents, report an error.
|
||||
const size = reduceLeft(typeSet, (n, t) => n * (t.flags & TypeFlags.Union ? (<UnionType>t).types.length : 1), 1);
|
||||
if (size >= 100000) {
|
||||
error(currentNode, Diagnostics.Expression_produces_a_union_type_that_is_too_complex_to_represent);
|
||||
return errorType;
|
||||
}
|
||||
const unionIndex = findIndex(typeSet, t => (t.flags & TypeFlags.Union) !== 0);
|
||||
const unionType = <UnionType>typeSet[unionIndex];
|
||||
result = getUnionType(map(unionType.types, t => getIntersectionType(replaceElement(typeSet, unionIndex, t))),
|
||||
@@ -10067,7 +10105,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) {
|
||||
function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) {
|
||||
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
|
||||
const propName = isTypeUsableAsPropertyName(indexType) ?
|
||||
getPropertyNameFromType(indexType) :
|
||||
@@ -10141,7 +10179,7 @@ namespace ts {
|
||||
if (objectType.symbol === globalThisSymbol && propName !== undefined && globalThisSymbol.exports!.has(propName) && (globalThisSymbol.exports!.get(propName)!.flags & SymbolFlags.BlockScoped)) {
|
||||
error(accessExpression, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(propName), typeToString(objectType));
|
||||
}
|
||||
else if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors) {
|
||||
else if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors && !suppressNoImplicitAnyError) {
|
||||
if (propName !== undefined && typeHasStaticProperty(propName, objectType)) {
|
||||
error(accessExpression, Diagnostics.Property_0_is_a_static_member_of_type_1, propName as string, typeToString(objectType));
|
||||
}
|
||||
@@ -10161,7 +10199,29 @@ namespace ts {
|
||||
error(accessExpression, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1, typeToString(objectType), suggestion);
|
||||
}
|
||||
else {
|
||||
error(accessExpression, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(objectType));
|
||||
let errorInfo: DiagnosticMessageChain | undefined;
|
||||
if (indexType.flags & TypeFlags.EnumLiteral) {
|
||||
errorInfo = chainDiagnosticMessages(/* details */ undefined, Diagnostics.Property_0_does_not_exist_on_type_1, "[" + typeToString(indexType) + "]", typeToString(objectType));
|
||||
}
|
||||
else if (indexType.flags & TypeFlags.UniqueESSymbol) {
|
||||
const symbolName = getFullyQualifiedName((indexType as UniqueESSymbolType).symbol, accessExpression);
|
||||
errorInfo = chainDiagnosticMessages(/* details */ undefined, Diagnostics.Property_0_does_not_exist_on_type_1, "[" + symbolName + "]", typeToString(objectType));
|
||||
}
|
||||
else if (indexType.flags & TypeFlags.StringLiteral) {
|
||||
errorInfo = chainDiagnosticMessages(/* details */ undefined, Diagnostics.Property_0_does_not_exist_on_type_1, (indexType as StringLiteralType).value, typeToString(objectType));
|
||||
}
|
||||
else if (indexType.flags & TypeFlags.NumberLiteral) {
|
||||
errorInfo = chainDiagnosticMessages(/* details */ undefined, Diagnostics.Property_0_does_not_exist_on_type_1, (indexType as NumberLiteralType).value, typeToString(objectType));
|
||||
}
|
||||
else if (indexType.flags & (TypeFlags.Number | TypeFlags.String)) {
|
||||
errorInfo = chainDiagnosticMessages(/* details */ undefined, Diagnostics.No_index_signature_with_a_parameter_of_type_0_was_found_on_type_1, typeToString(indexType), typeToString(objectType));
|
||||
}
|
||||
|
||||
errorInfo = chainDiagnosticMessages(
|
||||
errorInfo,
|
||||
Diagnostics.Element_implicitly_has_an_any_type_because_expression_of_type_0_can_t_be_used_to_index_type_1, typeToString(fullIndexType), typeToString(objectType)
|
||||
);
|
||||
diagnostics.add(createDiagnosticForNodeFromMessageChain(accessExpression, errorInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10360,7 +10420,7 @@ namespace ts {
|
||||
const propTypes: Type[] = [];
|
||||
let wasMissingProp = false;
|
||||
for (const t of (<UnionType>indexType).types) {
|
||||
const propType = getPropertyTypeForIndexType(objectType, apparentObjectType, t, accessNode, accessFlags);
|
||||
const propType = getPropertyTypeForIndexType(objectType, apparentObjectType, t, indexType, wasMissingProp, accessNode, accessFlags);
|
||||
if (propType) {
|
||||
propTypes.push(propType);
|
||||
}
|
||||
@@ -10378,7 +10438,7 @@ namespace ts {
|
||||
}
|
||||
return accessFlags & AccessFlags.Writing ? getIntersectionType(propTypes) : getUnionType(propTypes);
|
||||
}
|
||||
return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, accessNode, accessFlags | AccessFlags.CacheSymbol);
|
||||
return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, indexType, /* supressNoImplicitAnyError */ false, accessNode, accessFlags | AccessFlags.CacheSymbol);
|
||||
}
|
||||
|
||||
function getTypeFromIndexedAccessTypeNode(node: IndexedAccessTypeNode) {
|
||||
@@ -11462,6 +11522,7 @@ namespace ts {
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.FunctionDeclaration: // Function declarations can have context when annotated with a jsdoc @type
|
||||
return isContextSensitiveFunctionLikeDeclaration(<FunctionExpression | ArrowFunction | MethodDeclaration>node);
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return some((<ObjectLiteralExpression>node).properties, isContextSensitive);
|
||||
@@ -11495,6 +11556,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isContextSensitiveFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean {
|
||||
if (isFunctionDeclaration(node) && (!isInJSFile(node) || !getTypeForDeclarationFromJSDocComment(node))) {
|
||||
return false;
|
||||
}
|
||||
// Functions with type parameters are not context sensitive.
|
||||
if (node.typeParameters) {
|
||||
return false;
|
||||
@@ -12281,8 +12345,8 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isIgnoredJsxProperty(source: Type, sourceProp: Symbol, targetMemberType: Type | undefined) {
|
||||
return getObjectFlags(source) & ObjectFlags.JsxAttributes && !(isUnhyphenatedJsxName(sourceProp.escapedName) || targetMemberType);
|
||||
function isIgnoredJsxProperty(source: Type, sourceProp: Symbol) {
|
||||
return getObjectFlags(source) & ObjectFlags.JsxAttributes && !isUnhyphenatedJsxName(sourceProp.escapedName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -12928,6 +12992,18 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function propagateSidebandVarianceFlags(typeArguments: readonly Type[], variances: VarianceFlags[]) {
|
||||
for (let i = 0; i < variances.length; i++) {
|
||||
const v = variances[i];
|
||||
if (v & VarianceFlags.Unmeasurable) {
|
||||
instantiateType(typeArguments[i], reportUnmeasurableMarkers);
|
||||
}
|
||||
if (v & VarianceFlags.Unreliable) {
|
||||
instantiateType(typeArguments[i], reportUnreliableMarkers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if possibly recursive types are related. First, check if the result is already available in the global cache.
|
||||
// Second, check if we have already started a comparison of the given two types in which case we assume the result to be true.
|
||||
// Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are
|
||||
@@ -12945,6 +13021,16 @@ namespace ts {
|
||||
// as a failure, and should be updated as a reported failure by the bottom of this function.
|
||||
}
|
||||
else {
|
||||
if (outofbandVarianceMarkerHandler) {
|
||||
// We're in the middle of variance checking - integrate any unmeasurable/unreliable flags from this cached component
|
||||
if (source.flags & (TypeFlags.Object | TypeFlags.Conditional) && source.aliasSymbol &&
|
||||
source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol) {
|
||||
propagateSidebandVarianceFlags(source.aliasTypeArguments, getAliasVariances(source.aliasSymbol));
|
||||
}
|
||||
if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (<TypeReference>source).target === (<TypeReference>target).target && length((<TypeReference>source).typeArguments)) {
|
||||
propagateSidebandVarianceFlags((<TypeReference>source).typeArguments!, getVariances((<TypeReference>source).target));
|
||||
}
|
||||
}
|
||||
return related === RelationComparisonResult.Succeeded ? Ternary.True : Ternary.False;
|
||||
}
|
||||
}
|
||||
@@ -13463,6 +13549,49 @@ namespace ts {
|
||||
return result || properties;
|
||||
}
|
||||
|
||||
function isPropertySymbolTypeRelated(sourceProp: Symbol, targetProp: Symbol, getTypeOfSourceProperty: (sym: Symbol) => Type, reportErrors: boolean): Ternary {
|
||||
const targetIsOptional = strictNullChecks && !!(getCheckFlags(targetProp) & CheckFlags.Partial);
|
||||
const source = getTypeOfSourceProperty(sourceProp);
|
||||
if (getCheckFlags(targetProp) & CheckFlags.DeferredType && !getSymbolLinks(targetProp).type) {
|
||||
// Rather than resolving (and normalizing) the type, relate constituent-by-constituent without performing normalization or seconadary passes
|
||||
const links = getSymbolLinks(targetProp);
|
||||
Debug.assertDefined(links.deferralParent);
|
||||
Debug.assertDefined(links.deferralConstituents);
|
||||
const unionParent = !!(links.deferralParent!.flags & TypeFlags.Union);
|
||||
let result = unionParent ? Ternary.False : Ternary.True;
|
||||
const targetTypes = links.deferralConstituents!;
|
||||
for (const targetType of targetTypes) {
|
||||
const related = isRelatedTo(source, targetType, /*reportErrors*/ false, /*headMessage*/ undefined, /*isIntersectionConstituent*/ !unionParent);
|
||||
if (!unionParent) {
|
||||
if (!related) {
|
||||
// Can't assign to a target individually - have to fallback to assigning to the _whole_ intersection (which forces normalization)
|
||||
return isRelatedTo(source, addOptionality(getTypeOfSymbol(targetProp), targetIsOptional), reportErrors);
|
||||
}
|
||||
result &= related;
|
||||
}
|
||||
else {
|
||||
if (related) {
|
||||
return related;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unionParent && !result && targetIsOptional) {
|
||||
result = isRelatedTo(source, undefinedType);
|
||||
}
|
||||
if (unionParent && !result && reportErrors) {
|
||||
// The easiest way to get the right errors here is to un-defer (which may be costly)
|
||||
// If it turns out this is too costly too often, we can replicate the error handling logic within
|
||||
// typeRelatedToSomeType without the discriminatable type branch (as that requires a manifest union
|
||||
// type on which to hand discriminable properties, which we are expressly trying to avoid here)
|
||||
return isRelatedTo(source, addOptionality(getTypeOfSymbol(targetProp), targetIsOptional), reportErrors);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return isRelatedTo(source, addOptionality(getTypeOfSymbol(targetProp), targetIsOptional), reportErrors);
|
||||
}
|
||||
}
|
||||
|
||||
function propertyRelatedTo(source: Type, target: Type, sourceProp: Symbol, targetProp: Symbol, getTypeOfSourceProperty: (sym: Symbol) => Type, reportErrors: boolean): Ternary {
|
||||
const sourcePropFlags = getDeclarationModifierFlagsFromSymbol(sourceProp);
|
||||
const targetPropFlags = getDeclarationModifierFlagsFromSymbol(targetProp);
|
||||
@@ -13505,7 +13634,7 @@ namespace ts {
|
||||
return Ternary.False;
|
||||
}
|
||||
// If the target comes from a partial union prop, allow `undefined` in the target type
|
||||
const related = isRelatedTo(getTypeOfSourceProperty(sourceProp), addOptionality(getTypeOfSymbol(targetProp), !!(getCheckFlags(targetProp) & CheckFlags.Partial)), reportErrors);
|
||||
const related = isPropertySymbolTypeRelated(sourceProp, targetProp, getTypeOfSourceProperty, reportErrors);
|
||||
if (!related) {
|
||||
if (reportErrors) {
|
||||
reportError(Diagnostics.Types_of_property_0_are_incompatible, symbolToString(targetProp));
|
||||
@@ -13617,9 +13746,6 @@ namespace ts {
|
||||
if (!(targetProp.flags & SymbolFlags.Prototype)) {
|
||||
const sourceProp = getPropertyOfType(source, targetProp.escapedName);
|
||||
if (sourceProp && sourceProp !== targetProp) {
|
||||
if (isIgnoredJsxProperty(source, sourceProp, getTypeOfSymbol(targetProp))) {
|
||||
continue;
|
||||
}
|
||||
const related = propertyRelatedTo(source, target, sourceProp, targetProp, getTypeOfSymbol, reportErrors);
|
||||
if (!related) {
|
||||
return Ternary.False;
|
||||
@@ -13765,7 +13891,7 @@ namespace ts {
|
||||
function eachPropertyRelatedTo(source: Type, target: Type, kind: IndexKind, reportErrors: boolean): Ternary {
|
||||
let result = Ternary.True;
|
||||
for (const prop of getPropertiesOfObjectType(source)) {
|
||||
if (isIgnoredJsxProperty(source, prop, /*targetMemberType*/ undefined)) {
|
||||
if (isIgnoredJsxProperty(source, prop)) {
|
||||
continue;
|
||||
}
|
||||
// Skip over symbol-named members
|
||||
@@ -13977,12 +14103,6 @@ namespace ts {
|
||||
if (unreliable) {
|
||||
variance |= VarianceFlags.Unreliable;
|
||||
}
|
||||
const covariantID = getRelationKey(typeWithSub, typeWithSuper, assignableRelation);
|
||||
const contravariantID = getRelationKey(typeWithSuper, typeWithSub, assignableRelation);
|
||||
// We delete the results of these checks, as we want them to actually be run, see the `Unmeasurable` variance we cache,
|
||||
// And then fall back to a structural result.
|
||||
assignableRelation.delete(covariantID);
|
||||
assignableRelation.delete(contravariantID);
|
||||
}
|
||||
variances.push(variance);
|
||||
}
|
||||
@@ -14503,7 +14623,7 @@ namespace ts {
|
||||
* with no call or construct signatures.
|
||||
*/
|
||||
function isObjectTypeWithInferableIndex(type: Type) {
|
||||
return type.symbol && (type.symbol.flags & (SymbolFlags.ObjectLiteral | SymbolFlags.TypeLiteral | SymbolFlags.ValueModule)) !== 0 &&
|
||||
return type.symbol && (type.symbol.flags & (SymbolFlags.ObjectLiteral | SymbolFlags.TypeLiteral | SymbolFlags.Enum | SymbolFlags.ValueModule)) !== 0 &&
|
||||
!typeHasCallOrConstructSignatures(type);
|
||||
}
|
||||
|
||||
@@ -14647,26 +14767,34 @@ namespace ts {
|
||||
|
||||
function getWidenedTypeWithContext(type: Type, context: WideningContext | undefined): Type {
|
||||
if (getObjectFlags(type) & ObjectFlags.RequiresWidening) {
|
||||
if (context === undefined && type.widened) {
|
||||
return type.widened;
|
||||
}
|
||||
let result: Type | undefined;
|
||||
if (type.flags & TypeFlags.Nullable) {
|
||||
return anyType;
|
||||
result = anyType;
|
||||
}
|
||||
if (isObjectLiteralType(type)) {
|
||||
return getWidenedTypeOfObjectLiteral(type, context);
|
||||
else if (isObjectLiteralType(type)) {
|
||||
result = getWidenedTypeOfObjectLiteral(type, context);
|
||||
}
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
else if (type.flags & TypeFlags.Union) {
|
||||
const unionContext = context || createWideningContext(/*parent*/ undefined, /*propertyName*/ undefined, (<UnionType>type).types);
|
||||
const widenedTypes = sameMap((<UnionType>type).types, t => t.flags & TypeFlags.Nullable ? t : getWidenedTypeWithContext(t, unionContext));
|
||||
// Widening an empty object literal transitions from a highly restrictive type to
|
||||
// a highly inclusive one. For that reason we perform subtype reduction here if the
|
||||
// union includes empty object types (e.g. reducing {} | string to just {}).
|
||||
return getUnionType(widenedTypes, some(widenedTypes, isEmptyObjectType) ? UnionReduction.Subtype : UnionReduction.Literal);
|
||||
result = getUnionType(widenedTypes, some(widenedTypes, isEmptyObjectType) ? UnionReduction.Subtype : UnionReduction.Literal);
|
||||
}
|
||||
if (type.flags & TypeFlags.Intersection) {
|
||||
return getIntersectionType(sameMap((<IntersectionType>type).types, getWidenedType));
|
||||
else if (type.flags & TypeFlags.Intersection) {
|
||||
result = getIntersectionType(sameMap((<IntersectionType>type).types, getWidenedType));
|
||||
}
|
||||
if (isArrayType(type) || isTupleType(type)) {
|
||||
return createTypeReference((<TypeReference>type).target, sameMap((<TypeReference>type).typeArguments, getWidenedType));
|
||||
else if (isArrayType(type) || isTupleType(type)) {
|
||||
result = createTypeReference((<TypeReference>type).target, sameMap((<TypeReference>type).typeArguments, getWidenedType));
|
||||
}
|
||||
if (result && context === undefined) {
|
||||
type.widened = result;
|
||||
}
|
||||
return result || type;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
@@ -14832,13 +14960,6 @@ namespace ts {
|
||||
return context && createInferenceContextWorker(map(context.inferences, cloneInferenceInfo), context.signature, context.flags | extraFlags, context.compareTypes);
|
||||
}
|
||||
|
||||
function cloneInferredPartOfContext(context: InferenceContext): InferenceContext | undefined {
|
||||
const inferences = filter(context.inferences, hasInferenceCandidates);
|
||||
return inferences.length ?
|
||||
createInferenceContextWorker(map(inferences, cloneInferenceInfo), context.signature, context.flags, context.compareTypes) :
|
||||
undefined;
|
||||
}
|
||||
|
||||
function createInferenceContextWorker(inferences: InferenceInfo[], signature: Signature | undefined, flags: InferenceFlags, compareTypes: TypeComparer): InferenceContext {
|
||||
const context: InferenceContext = {
|
||||
inferences,
|
||||
@@ -15070,11 +15191,7 @@ namespace ts {
|
||||
if (source.aliasSymbol && source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol) {
|
||||
// Source and target are types originating in the same generic type alias declaration.
|
||||
// Simply infer from source type arguments to target type arguments.
|
||||
const sourceTypes = source.aliasTypeArguments;
|
||||
const targetTypes = target.aliasTypeArguments!;
|
||||
for (let i = 0; i < sourceTypes.length; i++) {
|
||||
inferFromTypes(sourceTypes[i], targetTypes[i]);
|
||||
}
|
||||
inferFromTypeArguments(source.aliasTypeArguments, target.aliasTypeArguments!, getAliasVariances(source.aliasSymbol));
|
||||
return;
|
||||
}
|
||||
if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union && !(source.flags & TypeFlags.EnumLiteral && target.flags & TypeFlags.EnumLiteral) ||
|
||||
@@ -15180,18 +15297,7 @@ namespace ts {
|
||||
}
|
||||
if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (<TypeReference>source).target === (<TypeReference>target).target) {
|
||||
// If source and target are references to the same generic type, infer from type arguments
|
||||
const sourceTypes = (<TypeReference>source).typeArguments || emptyArray;
|
||||
const targetTypes = (<TypeReference>target).typeArguments || emptyArray;
|
||||
const count = sourceTypes.length < targetTypes.length ? sourceTypes.length : targetTypes.length;
|
||||
const variances = getVariances((<TypeReference>source).target);
|
||||
for (let i = 0; i < count; i++) {
|
||||
if (i < variances.length && (variances[i] & VarianceFlags.VarianceMask) === VarianceFlags.Contravariant) {
|
||||
inferFromContravariantTypes(sourceTypes[i], targetTypes[i]);
|
||||
}
|
||||
else {
|
||||
inferFromTypes(sourceTypes[i], targetTypes[i]);
|
||||
}
|
||||
}
|
||||
inferFromTypeArguments((<TypeReference>source).typeArguments || emptyArray, (<TypeReference>target).typeArguments || emptyArray, getVariances((<TypeReference>source).target));
|
||||
}
|
||||
else if (source.flags & TypeFlags.Index && target.flags & TypeFlags.Index) {
|
||||
contravariant = !contravariant;
|
||||
@@ -15311,6 +15417,18 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function inferFromTypeArguments(sourceTypes: readonly Type[], targetTypes: readonly Type[], variances: readonly VarianceFlags[]) {
|
||||
const count = sourceTypes.length < targetTypes.length ? sourceTypes.length : targetTypes.length;
|
||||
for (let i = 0; i < count; i++) {
|
||||
if (i < variances.length && (variances[i] & VarianceFlags.VarianceMask) === VarianceFlags.Contravariant) {
|
||||
inferFromContravariantTypes(sourceTypes[i], targetTypes[i]);
|
||||
}
|
||||
else {
|
||||
inferFromTypes(sourceTypes[i], targetTypes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function inferFromContravariantTypes(source: Type, target: Type) {
|
||||
if (strictFunctionTypes || priority & InferencePriority.AlwaysStrict) {
|
||||
contravariant = !contravariant;
|
||||
@@ -18150,7 +18268,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Return contextual type of parameter or undefined if no contextual type is available
|
||||
function getContextuallyTypedParameterType(parameter: ParameterDeclaration): Type | undefined {
|
||||
function getContextuallyTypedParameterType(parameter: ParameterDeclaration, forCache: boolean): Type | undefined {
|
||||
const func = parameter.parent;
|
||||
if (!isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
|
||||
return undefined;
|
||||
@@ -18171,8 +18289,21 @@ namespace ts {
|
||||
links.resolvedSignature = cached;
|
||||
return type;
|
||||
}
|
||||
const contextualSignature = getContextualSignature(func);
|
||||
let contextualSignature = getContextualSignature(func);
|
||||
if (contextualSignature) {
|
||||
if (forCache) {
|
||||
// Calling the below guarantees the types are primed and assigned in the same way
|
||||
// as when the parameter is reached via `checkFunctionExpressionOrObjectLiteralMethod`.
|
||||
// This should prevent any uninstantiated inference variables in the contextual signature
|
||||
// from leaking, and should lock in cached parameter types via `assignContextualParameterTypes`
|
||||
// which we will then immediately use the results of below.
|
||||
contextuallyCheckFunctionExpressionOrObjectLiteralMethod(func);
|
||||
const type = getTypeOfSymbol(getMergedSymbol(func.symbol));
|
||||
if (isTypeAny(type)) {
|
||||
return type;
|
||||
}
|
||||
contextualSignature = getSignaturesOfType(type, SignatureKind.Call)[0];
|
||||
}
|
||||
const index = func.parameters.indexOf(parameter) - (getThisParameter(func) ? 1 : 0);
|
||||
return parameter.dotDotDotToken && lastOrUndefined(func.parameters) === parameter ?
|
||||
getRestTypeAtPosition(contextualSignature, index) :
|
||||
@@ -18187,7 +18318,7 @@ namespace ts {
|
||||
}
|
||||
switch (declaration.kind) {
|
||||
case SyntaxKind.Parameter:
|
||||
return getContextuallyTypedParameterType(declaration);
|
||||
return getContextuallyTypedParameterType(declaration, /*forCache*/ false);
|
||||
case SyntaxKind.BindingElement:
|
||||
return getContextualTypeForBindingElement(declaration);
|
||||
// By default, do nothing and return undefined - only parameters and binding elements have context implied by a parent
|
||||
@@ -18344,11 +18475,13 @@ namespace ts {
|
||||
}
|
||||
return contextSensitive === true ? getTypeOfExpression(left) : contextSensitive;
|
||||
case SyntaxKind.BarBarToken:
|
||||
// When an || expression has a contextual type, the operands are contextually typed by that type. When an ||
|
||||
// expression has no contextual type, the right operand is contextually typed by the type of the left operand,
|
||||
// except for the special case of Javascript declarations of the form `namespace.prop = namespace.prop || {}`
|
||||
// When an || expression has a contextual type, the operands are contextually typed by that type, except
|
||||
// when that type originates in a binding pattern, the right operand is contextually typed by the type of
|
||||
// the left operand. When an || expression has no contextual type, the right operand is contextually typed
|
||||
// by the type of the left operand, except for the special case of Javascript declarations of the form
|
||||
// `namespace.prop = namespace.prop || {}`.
|
||||
const type = getContextualType(binaryExpression, contextFlags);
|
||||
return !type && node === right && !isDefaultedExpandoInitializer(binaryExpression) ?
|
||||
return node === right && (type && type.pattern || !type && !isDefaultedExpandoInitializer(binaryExpression)) ?
|
||||
getTypeOfExpression(left) : type;
|
||||
case SyntaxKind.AmpersandAmpersandToken:
|
||||
case SyntaxKind.CommaToken:
|
||||
@@ -20088,7 +20221,8 @@ namespace ts {
|
||||
let propType: Type;
|
||||
const leftType = checkNonNullExpression(left);
|
||||
const parentSymbol = getNodeLinks(left).resolvedSymbol;
|
||||
const apparentType = getApparentType(getWidenedType(leftType));
|
||||
// We widen array literals to get type any[] instead of undefined[] in non-strict mode
|
||||
const apparentType = getApparentType(isEmptyArrayLiteralType(leftType) ? getWidenedType(leftType) : leftType);
|
||||
if (isTypeAny(apparentType) || apparentType === silentNeverType) {
|
||||
if (isIdentifier(left) && parentSymbol) {
|
||||
markAliasReferenced(parentSymbol, node);
|
||||
@@ -20101,7 +20235,7 @@ namespace ts {
|
||||
markAliasReferenced(parentSymbol, node);
|
||||
}
|
||||
if (!prop) {
|
||||
const indexInfo = assignmentKind === AssignmentKind.None || !isGenericObjectType(leftType) ? getIndexInfoOfType(apparentType, IndexKind.String) : undefined;
|
||||
const indexInfo = assignmentKind === AssignmentKind.None || !isGenericObjectType(leftType) || isThisTypeParameter(leftType) ? getIndexInfoOfType(apparentType, IndexKind.String) : undefined;
|
||||
if (!(indexInfo && indexInfo.type)) {
|
||||
if (isJSLiteralType(leftType)) {
|
||||
return anyType;
|
||||
@@ -20814,7 +20948,8 @@ namespace ts {
|
||||
// We clone the inference context to avoid disturbing a resolution in progress for an
|
||||
// outer call expression. Effectively we just want a snapshot of whatever has been
|
||||
// inferred for any outer call expression so far.
|
||||
const outerMapper = getMapperFromContext(cloneInferenceContext(getInferenceContext(node), InferenceFlags.NoDefault));
|
||||
const outerContext = getInferenceContext(node);
|
||||
const outerMapper = getMapperFromContext(cloneInferenceContext(outerContext, InferenceFlags.NoDefault));
|
||||
const instantiatedType = instantiateType(contextualType, outerMapper);
|
||||
// If the contextual type is a generic function type with a single call signature, we
|
||||
// instantiate the type with its own type parameters and type arguments. This ensures that
|
||||
@@ -20831,8 +20966,13 @@ namespace ts {
|
||||
// Inferences made from return types have lower priority than all other inferences.
|
||||
inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, InferencePriority.ReturnType);
|
||||
// Create a type mapper for instantiating generic contextual types using the inferences made
|
||||
// from the return type.
|
||||
context.returnMapper = getMapperFromContext(cloneInferredPartOfContext(context));
|
||||
// from the return type. We need a separate inference pass here because (a) instantiation of
|
||||
// the source type uses the outer context's return mapper (which excludes inferences made from
|
||||
// outer arguments), and (b) we don't want any further inferences going into this context.
|
||||
const returnContext = createInferenceContext(signature.typeParameters!, signature, context.flags);
|
||||
const returnSourceType = instantiateType(contextualType, outerContext && outerContext.returnMapper);
|
||||
inferTypes(returnContext.inferences, returnSourceType, inferenceTargetType);
|
||||
context.returnMapper = some(returnContext.inferences, hasInferenceCandidates) ? getMapperFromContext(returnContext) : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22956,12 +23096,18 @@ namespace ts {
|
||||
checkGrammarForGenerator(node);
|
||||
}
|
||||
|
||||
const links = getNodeLinks(node);
|
||||
const type = getTypeOfSymbol(getMergedSymbol(node.symbol));
|
||||
if (isTypeAny(type)) {
|
||||
return type;
|
||||
}
|
||||
|
||||
contextuallyCheckFunctionExpressionOrObjectLiteralMethod(node, checkMode);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
function contextuallyCheckFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | ArrowFunction | MethodDeclaration, checkMode?: CheckMode) {
|
||||
const links = getNodeLinks(node);
|
||||
// Check if function expression is contextually typed and assign parameter types if so.
|
||||
if (!(links.flags & NodeCheckFlags.ContextChecked)) {
|
||||
const contextualSignature = getContextualSignature(node);
|
||||
@@ -22971,6 +23117,10 @@ namespace ts {
|
||||
if (!(links.flags & NodeCheckFlags.ContextChecked)) {
|
||||
links.flags |= NodeCheckFlags.ContextChecked;
|
||||
if (contextualSignature) {
|
||||
const type = getTypeOfSymbol(getMergedSymbol(node.symbol));
|
||||
if (isTypeAny(type)) {
|
||||
return;
|
||||
}
|
||||
const signature = getSignaturesOfType(type, SignatureKind.Call)[0];
|
||||
if (isContextSensitive(node)) {
|
||||
const inferenceContext = getInferenceContext(node);
|
||||
@@ -22991,8 +23141,6 @@ namespace ts {
|
||||
checkSignatureDeclaration(node);
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
function getReturnOrPromisedType(node: FunctionLikeDeclaration | MethodSignature, functionFlags: FunctionFlags) {
|
||||
@@ -29960,7 +30108,7 @@ namespace ts {
|
||||
// }
|
||||
// [ a ] from
|
||||
// [a] = [ some array ...]
|
||||
function getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr: Expression): Type {
|
||||
function getTypeOfAssignmentPattern(expr: AssignmentPattern): Type | undefined {
|
||||
Debug.assert(expr.kind === SyntaxKind.ObjectLiteralExpression || expr.kind === SyntaxKind.ArrayLiteralExpression);
|
||||
// If this is from "for of"
|
||||
// for ( { a } of elems) {
|
||||
@@ -29979,17 +30127,16 @@ namespace ts {
|
||||
// for ({ skills: { primary, secondary } } = multiRobot, i = 0; i < 1; i++) {
|
||||
if (expr.parent.kind === SyntaxKind.PropertyAssignment) {
|
||||
const node = cast(expr.parent.parent, isObjectLiteralExpression);
|
||||
const typeOfParentObjectLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(node);
|
||||
const typeOfParentObjectLiteral = getTypeOfAssignmentPattern(node) || errorType;
|
||||
const propertyIndex = indexOfNode(node.properties, expr.parent);
|
||||
return checkObjectLiteralDestructuringPropertyAssignment(node, typeOfParentObjectLiteral || errorType, propertyIndex)!; // TODO: GH#18217
|
||||
return checkObjectLiteralDestructuringPropertyAssignment(node, typeOfParentObjectLiteral, propertyIndex);
|
||||
}
|
||||
// Array literal assignment - array destructuring pattern
|
||||
Debug.assert(expr.parent.kind === SyntaxKind.ArrayLiteralExpression);
|
||||
const node = cast(expr.parent, isArrayLiteralExpression);
|
||||
// [{ property1: p1, property2 }] = elems;
|
||||
const typeOfArrayLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(<Expression>expr.parent);
|
||||
const elementType = checkIteratedTypeOrElementType(typeOfArrayLiteral || errorType, expr.parent, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || errorType;
|
||||
return checkArrayLiteralDestructuringElementAssignment(<ArrayLiteralExpression>expr.parent, typeOfArrayLiteral,
|
||||
(<ArrayLiteralExpression>expr.parent).elements.indexOf(expr), elementType || errorType)!; // TODO: GH#18217
|
||||
const typeOfArrayLiteral = getTypeOfAssignmentPattern(node) || errorType;
|
||||
const elementType = checkIteratedTypeOrElementType(typeOfArrayLiteral, expr.parent, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || errorType;
|
||||
return checkArrayLiteralDestructuringElementAssignment(node, typeOfArrayLiteral, node.elements.indexOf(expr), elementType);
|
||||
}
|
||||
|
||||
// Gets the property symbol corresponding to the property in destructuring assignment
|
||||
@@ -30000,7 +30147,7 @@ namespace ts {
|
||||
// [a] = [ property1, property2 ]
|
||||
function getPropertySymbolOfDestructuringAssignment(location: Identifier) {
|
||||
// Get the type of the object or array literal and then look for property of given name in the type
|
||||
const typeOfObjectLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(<Expression>location.parent.parent);
|
||||
const typeOfObjectLiteral = getTypeOfAssignmentPattern(cast(location.parent.parent, isAssignmentPattern));
|
||||
return typeOfObjectLiteral && getPropertyOfType(typeOfObjectLiteral, location.escapedText);
|
||||
}
|
||||
|
||||
|
||||
@@ -1022,8 +1022,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface OptionsBase {
|
||||
interface OptionsBase {
|
||||
[option: string]: CompilerOptionsValue | undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.5";
|
||||
export const versionMajorMinor = "3.6";
|
||||
/** The version of the TypeScript compiler release */
|
||||
export const version = `${versionMajorMinor}.0-dev`;
|
||||
}
|
||||
|
||||
@@ -3927,6 +3927,10 @@
|
||||
"category": "Message",
|
||||
"code": 6219
|
||||
},
|
||||
"'package.json' had a falsy '{0}' field.": {
|
||||
"category": "Message",
|
||||
"code": 6220
|
||||
},
|
||||
|
||||
"Projects to reference": {
|
||||
"category": "Message",
|
||||
@@ -4288,6 +4292,14 @@
|
||||
"category": "Error",
|
||||
"code": 7052
|
||||
},
|
||||
"Element implicitly has an 'any' type because expression of type '{0}' can't be used to index type '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 7053
|
||||
},
|
||||
"No index signature with a parameter of type '{0}' was found on type '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 7054
|
||||
},
|
||||
"You cannot rename this element.": {
|
||||
"category": "Error",
|
||||
"code": 8000
|
||||
|
||||
+12
-3
@@ -284,7 +284,6 @@ namespace ts {
|
||||
// Write build information if applicable
|
||||
if (!buildInfoPath || targetSourceFile || emitSkipped) return;
|
||||
const program = host.getProgramBuildInfo();
|
||||
if (!bundle && !program) return;
|
||||
if (host.isEmitBlocked(buildInfoPath) || compilerOptions.noEmit) {
|
||||
emitSkipped = true;
|
||||
return;
|
||||
@@ -638,7 +637,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function emitUsingBuildInfo(config: ParsedCommandLine, host: EmitUsingBuildInfoHost, getCommandLine: (ref: ProjectReference) => ParsedCommandLine | undefined): EmitUsingBuildInfoResult {
|
||||
export function emitUsingBuildInfo(
|
||||
config: ParsedCommandLine,
|
||||
host: EmitUsingBuildInfoHost,
|
||||
getCommandLine: (ref: ProjectReference) => ParsedCommandLine | undefined,
|
||||
customTransformers?: CustomTransformers
|
||||
): EmitUsingBuildInfoResult {
|
||||
const { buildInfoPath, jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath } = getOutputPathsForBundle(config.options, /*forceDtsPaths*/ false);
|
||||
const buildInfoText = host.readFile(Debug.assertDefined(buildInfoPath));
|
||||
if (!buildInfoText) return buildInfoPath!;
|
||||
@@ -723,7 +727,12 @@ namespace ts {
|
||||
useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(),
|
||||
getProgramBuildInfo: returnUndefined
|
||||
};
|
||||
emitFiles(notImplementedResolver, emitHost, /*targetSourceFile*/ undefined, getTransformers(config.options), /*emitOnlyDtsFiles*/ false);
|
||||
emitFiles(
|
||||
notImplementedResolver,
|
||||
emitHost,
|
||||
/*targetSourceFile*/ undefined,
|
||||
getTransformers(config.options, customTransformers)
|
||||
);
|
||||
return outputFiles;
|
||||
}
|
||||
|
||||
|
||||
@@ -141,7 +141,15 @@ namespace ts {
|
||||
|
||||
function readPackageJsonPathField<K extends "typings" | "types" | "main" | "tsconfig">(jsonContent: PackageJson, fieldName: K, baseDirectory: string, state: ModuleResolutionState): PackageJson[K] | undefined {
|
||||
const fileName = readPackageJsonField(jsonContent, fieldName, "string", state);
|
||||
if (fileName === undefined) return;
|
||||
if (fileName === undefined) {
|
||||
return;
|
||||
}
|
||||
if (!fileName) {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.package_json_had_a_falsy_0_field, fieldName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const path = normalizePath(combinePaths(baseDirectory, fileName));
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, fileName, path);
|
||||
|
||||
@@ -175,9 +175,9 @@ namespace ts.moduleSpecifiers {
|
||||
|
||||
function discoverProbableSymlinks(files: ReadonlyArray<SourceFile>, getCanonicalFileName: GetCanonicalFileName, cwd: string): ReadonlyMap<string> {
|
||||
const result = createMap<string>();
|
||||
const symlinks = mapDefined(files, sf =>
|
||||
sf.resolvedModules && firstDefinedIterator(sf.resolvedModules.values(), res =>
|
||||
res && res.originalPath && res.resolvedFileName !== res.originalPath ? [res.resolvedFileName, res.originalPath] : undefined));
|
||||
const symlinks = flatten<readonly [string, string]>(mapDefined(files, sf =>
|
||||
sf.resolvedModules && compact(arrayFrom(mapIterator(sf.resolvedModules.values(), res =>
|
||||
res && res.originalPath && res.resolvedFileName !== res.originalPath ? [res.resolvedFileName, res.originalPath] as const : undefined)))));
|
||||
for (const [resolvedPath, originalPath] of symlinks) {
|
||||
const [commonResolved, commonOriginal] = guessDirectorySymlink(resolvedPath, originalPath, cwd, getCanonicalFileName);
|
||||
result.set(commonOriginal, commonResolved);
|
||||
|
||||
@@ -54,6 +54,7 @@ namespace ts {
|
||||
writeLog(s: string): void;
|
||||
maxNumberOfFilesToIterateForInvalidation?: number;
|
||||
getCurrentProgram(): Program | undefined;
|
||||
fileIsOpen(filePath: Path): boolean;
|
||||
}
|
||||
|
||||
interface DirectoryWatchesOfFailedLookup {
|
||||
@@ -698,6 +699,11 @@ namespace ts {
|
||||
// If something to do with folder/file starting with "." in node_modules folder, skip it
|
||||
if (isPathIgnored(fileOrDirectoryPath)) return false;
|
||||
|
||||
// prevent saving an open file from over-eagerly triggering invalidation
|
||||
if (resolutionHost.fileIsOpen(fileOrDirectoryPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Some file or directory in the watching directory is created
|
||||
// Return early if it does not have any of the watching extension or not the custom failed lookup path
|
||||
const dirOfFileOrDirectory = getDirectoryPath(fileOrDirectoryPath);
|
||||
|
||||
@@ -44,6 +44,7 @@ namespace ts {
|
||||
addRange(transformers, customTransformers && map(customTransformers.before, wrapScriptTransformerFactory));
|
||||
|
||||
transformers.push(transformTypeScript);
|
||||
transformers.push(transformClassFields);
|
||||
|
||||
if (jsx === JsxEmit.React) {
|
||||
transformers.push(transformJsx);
|
||||
|
||||
@@ -0,0 +1,491 @@
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
const enum ClassPropertySubstitutionFlags {
|
||||
/**
|
||||
* Enables substitutions for class expressions with static fields
|
||||
* which have initializers that reference the class name.
|
||||
*/
|
||||
ClassAliases = 1 << 0,
|
||||
}
|
||||
/**
|
||||
* Transforms ECMAScript Class Syntax.
|
||||
* TypeScript parameter property syntax is transformed in the TypeScript transformer.
|
||||
* For now, this transforms public field declarations using TypeScript class semantics
|
||||
* (where the declarations get elided and initializers are transformed as assignments in the constructor).
|
||||
* Eventually, this transform will change to the ECMAScript semantics (with Object.defineProperty).
|
||||
*/
|
||||
export function transformClassFields(context: TransformationContext) {
|
||||
const {
|
||||
hoistVariableDeclaration,
|
||||
endLexicalEnvironment,
|
||||
resumeLexicalEnvironment
|
||||
} = context;
|
||||
const resolver = context.getEmitResolver();
|
||||
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
context.onSubstituteNode = onSubstituteNode;
|
||||
|
||||
let enabledSubstitutions: ClassPropertySubstitutionFlags;
|
||||
|
||||
let classAliases: Identifier[];
|
||||
|
||||
/**
|
||||
* Tracks what computed name expressions originating from elided names must be inlined
|
||||
* at the next execution site, in document order
|
||||
*/
|
||||
let pendingExpressions: Expression[] | undefined;
|
||||
|
||||
/**
|
||||
* Tracks what computed name expression statements and static property initializers must be
|
||||
* emitted at the next execution site, in document order (for decorated classes).
|
||||
*/
|
||||
let pendingStatements: Statement[] | undefined;
|
||||
|
||||
return chainBundle(transformSourceFile);
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
if (node.isDeclarationFile) {
|
||||
return node;
|
||||
}
|
||||
const visited = visitEachChild(node, visitor, context);
|
||||
addEmitHelpers(visited, context.readEmitHelpers());
|
||||
return visited;
|
||||
}
|
||||
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
if (!(node.transformFlags & TransformFlags.ContainsClassFields)) return node;
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ClassExpression:
|
||||
return visitClassExpression(node as ClassExpression);
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return visitClassDeclaration(node as ClassDeclaration);
|
||||
case SyntaxKind.VariableStatement:
|
||||
return visitVariableStatement(node as VariableStatement);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the members of a class that has fields.
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function classElementVisitor(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Constructor:
|
||||
// Constructors for classes using class fields are transformed in
|
||||
// `visitClassDeclaration` or `visitClassExpression`.
|
||||
return undefined;
|
||||
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
// Visit the name of the member (if it's a computed property name).
|
||||
return visitEachChild(node, classElementVisitor, context);
|
||||
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
return visitPropertyDeclaration(node as PropertyDeclaration);
|
||||
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
return visitComputedPropertyName(node as ComputedPropertyName);
|
||||
|
||||
default:
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
function visitVariableStatement(node: VariableStatement) {
|
||||
const savedPendingStatements = pendingStatements;
|
||||
pendingStatements = [];
|
||||
|
||||
const visitedNode = visitEachChild(node, visitor, context);
|
||||
const statement = some(pendingStatements) ?
|
||||
[visitedNode, ...pendingStatements] :
|
||||
visitedNode;
|
||||
|
||||
pendingStatements = savedPendingStatements;
|
||||
return statement;
|
||||
}
|
||||
|
||||
function visitComputedPropertyName(name: ComputedPropertyName) {
|
||||
let node = visitEachChild(name, visitor, context);
|
||||
if (some(pendingExpressions)) {
|
||||
const expressions = pendingExpressions;
|
||||
expressions.push(name.expression);
|
||||
pendingExpressions = [];
|
||||
node = updateComputedPropertyName(
|
||||
node,
|
||||
inlineExpressions(expressions)
|
||||
);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function visitPropertyDeclaration(node: PropertyDeclaration) {
|
||||
Debug.assert(!some(node.decorators));
|
||||
// Create a temporary variable to store a computed property name (if necessary).
|
||||
// If it's not inlineable, then we emit an expression after the class which assigns
|
||||
// the property name to the temporary variable.
|
||||
const expr = getPropertyNameExpressionIfNeeded(node.name, !!node.initializer);
|
||||
if (expr && !isSimpleInlineableExpression(expr)) {
|
||||
(pendingExpressions || (pendingExpressions = [])).push(expr);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function visitClassDeclaration(node: ClassDeclaration) {
|
||||
if (!forEach(node.members, isPropertyDeclaration)) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
const savedPendingExpressions = pendingExpressions;
|
||||
pendingExpressions = undefined;
|
||||
|
||||
const extendsClauseElement = getEffectiveBaseTypeNode(node);
|
||||
const isDerivedClass = !!(extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== SyntaxKind.NullKeyword);
|
||||
|
||||
const statements: Statement[] = [
|
||||
updateClassDeclaration(
|
||||
node,
|
||||
node.decorators,
|
||||
node.modifiers,
|
||||
node.name,
|
||||
node.typeParameters,
|
||||
node.heritageClauses,
|
||||
transformClassMembers(node, isDerivedClass)
|
||||
)
|
||||
];
|
||||
|
||||
// Write any pending expressions from elided or moved computed property names
|
||||
if (some(pendingExpressions)) {
|
||||
statements.push(createExpressionStatement(inlineExpressions(pendingExpressions!)));
|
||||
}
|
||||
pendingExpressions = savedPendingExpressions;
|
||||
|
||||
// Emit static property assignment. Because classDeclaration is lexically evaluated,
|
||||
// it is safe to emit static property assignment after classDeclaration
|
||||
// From ES6 specification:
|
||||
// HasLexicalDeclaration (N) : Determines if the argument identifier has a binding in this environment record that was created using
|
||||
// a lexical declaration such as a LexicalDeclaration or a ClassDeclaration.
|
||||
const staticProperties = getInitializedProperties(node, /*isStatic*/ true);
|
||||
if (some(staticProperties)) {
|
||||
addInitializedPropertyStatements(statements, staticProperties, getInternalName(node));
|
||||
}
|
||||
|
||||
return statements;
|
||||
}
|
||||
|
||||
function visitClassExpression(node: ClassExpression): Expression {
|
||||
if (!forEach(node.members, isPropertyDeclaration)) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
const savedPendingExpressions = pendingExpressions;
|
||||
pendingExpressions = undefined;
|
||||
|
||||
// If this class expression is a transformation of a decorated class declaration,
|
||||
// then we want to output the pendingExpressions as statements, not as inlined
|
||||
// expressions with the class statement.
|
||||
//
|
||||
// In this case, we use pendingStatements to produce the same output as the
|
||||
// class declaration transformation. The VariableStatement visitor will insert
|
||||
// these statements after the class expression variable statement.
|
||||
const isDecoratedClassDeclaration = isClassDeclaration(getOriginalNode(node));
|
||||
|
||||
const staticProperties = getInitializedProperties(node, /*isStatic*/ true);
|
||||
const extendsClauseElement = getEffectiveBaseTypeNode(node);
|
||||
const isDerivedClass = !!(extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== SyntaxKind.NullKeyword);
|
||||
|
||||
const classExpression = updateClassExpression(
|
||||
node,
|
||||
node.modifiers,
|
||||
node.name,
|
||||
node.typeParameters,
|
||||
visitNodes(node.heritageClauses, visitor, isHeritageClause),
|
||||
transformClassMembers(node, isDerivedClass)
|
||||
);
|
||||
|
||||
if (some(staticProperties) || some(pendingExpressions)) {
|
||||
if (isDecoratedClassDeclaration) {
|
||||
Debug.assertDefined(pendingStatements, "Decorated classes transformed by TypeScript are expected to be within a variable declaration.");
|
||||
|
||||
// Write any pending expressions from elided or moved computed property names
|
||||
if (pendingStatements && pendingExpressions && some(pendingExpressions)) {
|
||||
pendingStatements.push(createExpressionStatement(inlineExpressions(pendingExpressions)));
|
||||
}
|
||||
pendingExpressions = savedPendingExpressions;
|
||||
|
||||
if (pendingStatements && some(staticProperties)) {
|
||||
addInitializedPropertyStatements(pendingStatements, staticProperties, getInternalName(node));
|
||||
}
|
||||
return classExpression;
|
||||
}
|
||||
else {
|
||||
const expressions: Expression[] = [];
|
||||
const isClassWithConstructorReference = resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference;
|
||||
const temp = createTempVariable(hoistVariableDeclaration, !!isClassWithConstructorReference);
|
||||
if (isClassWithConstructorReference) {
|
||||
// record an alias as the class name is not in scope for statics.
|
||||
enableSubstitutionForClassAliases();
|
||||
const alias = getSynthesizedClone(temp);
|
||||
alias.autoGenerateFlags &= ~GeneratedIdentifierFlags.ReservedInNestedScopes;
|
||||
classAliases[getOriginalNodeId(node)] = alias;
|
||||
}
|
||||
|
||||
// To preserve the behavior of the old emitter, we explicitly indent
|
||||
// the body of a class with static initializers.
|
||||
setEmitFlags(classExpression, EmitFlags.Indented | getEmitFlags(classExpression));
|
||||
expressions.push(startOnNewLine(createAssignment(temp, classExpression)));
|
||||
// Add any pending expressions leftover from elided or relocated computed property names
|
||||
addRange(expressions, map(pendingExpressions, startOnNewLine));
|
||||
addRange(expressions, generateInitializedPropertyExpressions(staticProperties, temp));
|
||||
expressions.push(startOnNewLine(temp));
|
||||
|
||||
pendingExpressions = savedPendingExpressions;
|
||||
return inlineExpressions(expressions);
|
||||
}
|
||||
}
|
||||
|
||||
pendingExpressions = savedPendingExpressions;
|
||||
return classExpression;
|
||||
}
|
||||
|
||||
function transformClassMembers(node: ClassDeclaration | ClassExpression, isDerivedClass: boolean) {
|
||||
const members: ClassElement[] = [];
|
||||
const constructor = transformConstructor(node, isDerivedClass);
|
||||
if (constructor) {
|
||||
members.push(constructor);
|
||||
}
|
||||
addRange(members, visitNodes(node.members, classElementVisitor, isClassElement));
|
||||
return setTextRange(createNodeArray(members), /*location*/ node.members);
|
||||
}
|
||||
|
||||
function transformConstructor(node: ClassDeclaration | ClassExpression, isDerivedClass: boolean) {
|
||||
const constructor = visitNode(getFirstConstructorWithBody(node), visitor, isConstructorDeclaration);
|
||||
const containsPropertyInitializer = forEach(node.members, isInitializedProperty);
|
||||
if (!containsPropertyInitializer) {
|
||||
return constructor;
|
||||
}
|
||||
const parameters = visitParameterList(constructor ? constructor.parameters : undefined, visitor, context);
|
||||
const body = transformConstructorBody(node, constructor, isDerivedClass);
|
||||
if (!body) {
|
||||
return undefined;
|
||||
}
|
||||
return startOnNewLine(
|
||||
setOriginalNode(
|
||||
setTextRange(
|
||||
createConstructor(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
parameters,
|
||||
body
|
||||
),
|
||||
constructor || node
|
||||
),
|
||||
constructor
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function transformConstructorBody(node: ClassDeclaration | ClassExpression, constructor: ConstructorDeclaration | undefined, isDerivedClass: boolean) {
|
||||
const properties = getInitializedProperties(node, /*isStatic*/ false);
|
||||
|
||||
// Only generate synthetic constructor when there are property initializers to move.
|
||||
if (!constructor && !some(properties)) {
|
||||
return visitFunctionBody(/*node*/ undefined, visitor, context);
|
||||
}
|
||||
|
||||
resumeLexicalEnvironment();
|
||||
|
||||
let indexOfFirstStatement = 0;
|
||||
let statements: Statement[] = [];
|
||||
|
||||
if (!constructor && isDerivedClass) {
|
||||
// Add a synthetic `super` call:
|
||||
//
|
||||
// super(...arguments);
|
||||
//
|
||||
statements.push(
|
||||
createExpressionStatement(
|
||||
createCall(
|
||||
createSuper(),
|
||||
/*typeArguments*/ undefined,
|
||||
[createSpread(createIdentifier("arguments"))]
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (constructor) {
|
||||
indexOfFirstStatement = addPrologueDirectivesAndInitialSuperCall(constructor, statements, visitor);
|
||||
}
|
||||
|
||||
// Add the property initializers. Transforms this:
|
||||
//
|
||||
// public x = 1;
|
||||
//
|
||||
// Into this:
|
||||
//
|
||||
// constructor() {
|
||||
// this.x = 1;
|
||||
// }
|
||||
//
|
||||
addInitializedPropertyStatements(statements, properties, createThis());
|
||||
|
||||
// Add existing statements, skipping the initial super call.
|
||||
if (constructor) {
|
||||
addRange(statements, visitNodes(constructor.body!.statements, visitor, isStatement, indexOfFirstStatement));
|
||||
}
|
||||
|
||||
statements = mergeLexicalEnvironment(statements, endLexicalEnvironment());
|
||||
|
||||
return setTextRange(
|
||||
createBlock(
|
||||
setTextRange(
|
||||
createNodeArray(statements),
|
||||
/*location*/ constructor ? constructor.body!.statements : node.members
|
||||
),
|
||||
/*multiLine*/ true
|
||||
),
|
||||
/*location*/ constructor ? constructor.body : undefined
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates assignment statements for property initializers.
|
||||
*
|
||||
* @param properties An array of property declarations to transform.
|
||||
* @param receiver The receiver on which each property should be assigned.
|
||||
*/
|
||||
function addInitializedPropertyStatements(statements: Statement[], properties: ReadonlyArray<PropertyDeclaration>, receiver: LeftHandSideExpression) {
|
||||
for (const property of properties) {
|
||||
const statement = createExpressionStatement(transformInitializedProperty(property, receiver));
|
||||
setSourceMapRange(statement, moveRangePastModifiers(property));
|
||||
setCommentRange(statement, property);
|
||||
setOriginalNode(statement, property);
|
||||
statements.push(statement);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates assignment expressions for property initializers.
|
||||
*
|
||||
* @param properties An array of property declarations to transform.
|
||||
* @param receiver The receiver on which each property should be assigned.
|
||||
*/
|
||||
function generateInitializedPropertyExpressions(properties: ReadonlyArray<PropertyDeclaration>, receiver: LeftHandSideExpression) {
|
||||
const expressions: Expression[] = [];
|
||||
for (const property of properties) {
|
||||
const expression = transformInitializedProperty(property, receiver);
|
||||
startOnNewLine(expression);
|
||||
setSourceMapRange(expression, moveRangePastModifiers(property));
|
||||
setCommentRange(expression, property);
|
||||
setOriginalNode(expression, property);
|
||||
expressions.push(expression);
|
||||
}
|
||||
|
||||
return expressions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a property initializer into an assignment statement.
|
||||
*
|
||||
* @param property The property declaration.
|
||||
* @param receiver The object receiving the property assignment.
|
||||
*/
|
||||
function transformInitializedProperty(property: PropertyDeclaration, receiver: LeftHandSideExpression) {
|
||||
// We generate a name here in order to reuse the value cached by the relocated computed name expression (which uses the same generated name)
|
||||
const propertyName = isComputedPropertyName(property.name) && !isSimpleInlineableExpression(property.name.expression)
|
||||
? updateComputedPropertyName(property.name, getGeneratedNameForNode(property.name))
|
||||
: property.name;
|
||||
const initializer = visitNode(property.initializer!, visitor, isExpression);
|
||||
const memberAccess = createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName);
|
||||
|
||||
return createAssignment(memberAccess, initializer);
|
||||
}
|
||||
|
||||
function enableSubstitutionForClassAliases() {
|
||||
if ((enabledSubstitutions & ClassPropertySubstitutionFlags.ClassAliases) === 0) {
|
||||
enabledSubstitutions |= ClassPropertySubstitutionFlags.ClassAliases;
|
||||
|
||||
// We need to enable substitutions for identifiers. This allows us to
|
||||
// substitute class names inside of a class declaration.
|
||||
context.enableSubstitution(SyntaxKind.Identifier);
|
||||
|
||||
// Keep track of class aliases.
|
||||
classAliases = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param hint The context for the emitter.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (hint === EmitHint.Expression) {
|
||||
return substituteExpression(node as Expression);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteExpression(node: Expression) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return substituteExpressionIdentifier(node as Identifier);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteExpressionIdentifier(node: Identifier): Expression {
|
||||
return trySubstituteClassAlias(node) || node;
|
||||
}
|
||||
|
||||
function trySubstituteClassAlias(node: Identifier): Expression | undefined {
|
||||
if (enabledSubstitutions & ClassPropertySubstitutionFlags.ClassAliases) {
|
||||
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ConstructorReferenceInClass) {
|
||||
// Due to the emit for class decorators, any reference to the class from inside of the class body
|
||||
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
|
||||
// behavior of class names in ES6.
|
||||
// Also, when emitting statics for class expressions, we must substitute a class alias for
|
||||
// constructor references in static property initializers.
|
||||
const declaration = resolver.getReferencedValueDeclaration(node);
|
||||
if (declaration) {
|
||||
const classAlias = classAliases[declaration.id!]; // TODO: GH#18217
|
||||
if (classAlias) {
|
||||
const clone = getSynthesizedClone(classAlias);
|
||||
setSourceMapRange(clone, node);
|
||||
setCommentRange(clone, node);
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the name is a computed property, this function transforms it, then either returns an expression which caches the
|
||||
* value of the result or the expression itself if the value is either unused or safe to inline into multiple locations
|
||||
* @param shouldHoist Does the expression need to be reused? (ie, for an initializer or a decorator)
|
||||
*/
|
||||
function getPropertyNameExpressionIfNeeded(name: PropertyName, shouldHoist: boolean): Expression | undefined {
|
||||
if (isComputedPropertyName(name)) {
|
||||
const expression = visitNode(name.expression, visitor, isExpression);
|
||||
const innerExpression = skipPartiallyEmittedExpressions(expression);
|
||||
const inlinable = isSimpleInlineableExpression(innerExpression);
|
||||
const alreadyTransformed = isAssignmentExpression(innerExpression) && isGeneratedIdentifier(innerExpression.left);
|
||||
if (!alreadyTransformed && !inlinable && shouldHoist) {
|
||||
const generatedName = getGeneratedNameForNode(name);
|
||||
hoistVariableDeclaration(generatedName);
|
||||
return createAssignment(generatedName, expression);
|
||||
}
|
||||
return (inlinable || isIdentifier(innerExpression)) ? undefined : expression;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+146
-347
@@ -64,6 +64,7 @@ namespace ts {
|
||||
let currentLexicalScope: SourceFile | Block | ModuleBlock | CaseBlock;
|
||||
let currentNameScope: ClassDeclaration | undefined;
|
||||
let currentScopeFirstDeclarationsOfName: UnderscoreEscapedMap<Node> | undefined;
|
||||
let currentClassHasParameterProperties: boolean | undefined;
|
||||
|
||||
/**
|
||||
* Keeps track of whether expression substitution has been enabled for specific edge cases.
|
||||
@@ -83,12 +84,6 @@ namespace ts {
|
||||
*/
|
||||
let applicableSubstitutions: TypeScriptSubstitutionFlags;
|
||||
|
||||
/**
|
||||
* Tracks what computed name expressions originating from elided names must be inlined
|
||||
* at the next execution site, in document order
|
||||
*/
|
||||
let pendingExpressions: Expression[] | undefined;
|
||||
|
||||
return transformSourceFileOrBundle;
|
||||
|
||||
function transformSourceFileOrBundle(node: SourceFile | Bundle) {
|
||||
@@ -136,6 +131,7 @@ namespace ts {
|
||||
const savedCurrentScope = currentLexicalScope;
|
||||
const savedCurrentNameScope = currentNameScope;
|
||||
const savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName;
|
||||
const savedCurrentClassHasParameterProperties = currentClassHasParameterProperties;
|
||||
|
||||
// Handle state changes before visiting a node.
|
||||
onBeforeVisitNode(node);
|
||||
@@ -149,6 +145,7 @@ namespace ts {
|
||||
|
||||
currentLexicalScope = savedCurrentScope;
|
||||
currentNameScope = savedCurrentNameScope;
|
||||
currentClassHasParameterProperties = savedCurrentClassHasParameterProperties;
|
||||
return visited;
|
||||
}
|
||||
|
||||
@@ -321,6 +318,9 @@ namespace ts {
|
||||
return undefined;
|
||||
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
// Property declarations are not TypeScript syntax, but they must be visited
|
||||
// for the decorator transformation.
|
||||
return visitPropertyDeclaration(node as PropertyDeclaration);
|
||||
case SyntaxKind.IndexSignature:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
@@ -437,7 +437,6 @@ namespace ts {
|
||||
// - decorators
|
||||
// - optional `implements` heritage clause
|
||||
// - parameter property assignments in the constructor
|
||||
// - property declarations
|
||||
// - index signatures
|
||||
// - method overload signatures
|
||||
return visitClassDeclaration(<ClassDeclaration>node);
|
||||
@@ -449,7 +448,6 @@ namespace ts {
|
||||
// - decorators
|
||||
// - optional `implements` heritage clause
|
||||
// - parameter property assignments in the constructor
|
||||
// - property declarations
|
||||
// - index signatures
|
||||
// - method overload signatures
|
||||
return visitClassExpression(<ClassExpression>node);
|
||||
@@ -611,10 +609,6 @@ namespace ts {
|
||||
if (!isClassLikeDeclarationWithTypeScriptSyntax(node) && !(currentNamespace && hasModifier(node, ModifierFlags.Export))) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
const savedPendingExpressions = pendingExpressions;
|
||||
pendingExpressions = undefined;
|
||||
|
||||
const staticProperties = getInitializedProperties(node, /*isStatic*/ true);
|
||||
const facts = getClassFacts(node, staticProperties);
|
||||
|
||||
@@ -624,25 +618,11 @@ namespace ts {
|
||||
|
||||
const name = node.name || (facts & ClassFacts.NeedsName ? getGeneratedNameForNode(node) : undefined);
|
||||
const classStatement = facts & ClassFacts.HasConstructorDecorators
|
||||
? createClassDeclarationHeadWithDecorators(node, name, facts)
|
||||
? createClassDeclarationHeadWithDecorators(node, name)
|
||||
: createClassDeclarationHeadWithoutDecorators(node, name, facts);
|
||||
|
||||
let statements: Statement[] = [classStatement];
|
||||
|
||||
// Write any pending expressions from elided or moved computed property names
|
||||
if (some(pendingExpressions)) {
|
||||
statements.push(createExpressionStatement(inlineExpressions(pendingExpressions!)));
|
||||
}
|
||||
pendingExpressions = savedPendingExpressions;
|
||||
|
||||
// Emit static property assignment. Because classDeclaration is lexically evaluated,
|
||||
// it is safe to emit static property assignment after classDeclaration
|
||||
// From ES6 specification:
|
||||
// HasLexicalDeclaration (N) : Determines if the argument identifier has a binding in this environment record that was created using
|
||||
// a lexical declaration such as a LexicalDeclaration or a ClassDeclaration.
|
||||
if (facts & ClassFacts.HasStaticInitializedProperties) {
|
||||
addInitializedPropertyStatements(statements, staticProperties, facts & ClassFacts.UseImmediatelyInvokedFunctionExpression ? getInternalName(node) : getLocalName(node));
|
||||
}
|
||||
|
||||
// Write any decorators of the node.
|
||||
addClassElementDecorationStatements(statements, node, /*isStatic*/ false);
|
||||
@@ -745,7 +725,7 @@ namespace ts {
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.heritageClauses, visitor, isHeritageClause),
|
||||
transformClassMembers(node, (facts & ClassFacts.IsDerivedClass) !== 0)
|
||||
transformClassMembers(node)
|
||||
);
|
||||
|
||||
// To better align with the old emitter, we should not emit a trailing source map
|
||||
@@ -765,7 +745,7 @@ namespace ts {
|
||||
* Transforms a decorated class declaration and appends the resulting statements. If
|
||||
* the class requires an alias to avoid issues with double-binding, the alias is returned.
|
||||
*/
|
||||
function createClassDeclarationHeadWithDecorators(node: ClassDeclaration, name: Identifier | undefined, facts: ClassFacts) {
|
||||
function createClassDeclarationHeadWithDecorators(node: ClassDeclaration, name: Identifier | undefined) {
|
||||
// When we emit an ES6 class that has a class decorator, we must tailor the
|
||||
// emit to certain specific cases.
|
||||
//
|
||||
@@ -860,7 +840,7 @@ namespace ts {
|
||||
// ${members}
|
||||
// }
|
||||
const heritageClauses = visitNodes(node.heritageClauses, visitor, isHeritageClause);
|
||||
const members = transformClassMembers(node, (facts & ClassFacts.IsDerivedClass) !== 0);
|
||||
const members = transformClassMembers(node);
|
||||
const classExpression = createClassExpression(/*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members);
|
||||
setOriginalNode(classExpression, node);
|
||||
setTextRange(classExpression, location);
|
||||
@@ -888,49 +868,19 @@ namespace ts {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
const savedPendingExpressions = pendingExpressions;
|
||||
pendingExpressions = undefined;
|
||||
|
||||
const staticProperties = getInitializedProperties(node, /*isStatic*/ true);
|
||||
const heritageClauses = visitNodes(node.heritageClauses, visitor, isHeritageClause);
|
||||
const members = transformClassMembers(node, some(heritageClauses, c => c.token === SyntaxKind.ExtendsKeyword));
|
||||
const members = transformClassMembers(node);
|
||||
|
||||
const classExpression = createClassExpression(
|
||||
/*modifiers*/ undefined,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
heritageClauses,
|
||||
node.heritageClauses,
|
||||
members
|
||||
);
|
||||
|
||||
setOriginalNode(classExpression, node);
|
||||
setTextRange(classExpression, node);
|
||||
|
||||
if (some(staticProperties) || some(pendingExpressions)) {
|
||||
const expressions: Expression[] = [];
|
||||
const isClassWithConstructorReference = resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference;
|
||||
const temp = createTempVariable(hoistVariableDeclaration, !!isClassWithConstructorReference);
|
||||
if (isClassWithConstructorReference) {
|
||||
// record an alias as the class name is not in scope for statics.
|
||||
enableSubstitutionForClassAliases();
|
||||
const alias = getSynthesizedClone(temp);
|
||||
alias.autoGenerateFlags &= ~GeneratedIdentifierFlags.ReservedInNestedScopes;
|
||||
classAliases[getOriginalNodeId(node)] = alias;
|
||||
}
|
||||
|
||||
// To preserve the behavior of the old emitter, we explicitly indent
|
||||
// the body of a class with static initializers.
|
||||
setEmitFlags(classExpression, EmitFlags.Indented | getEmitFlags(classExpression));
|
||||
expressions.push(startOnNewLine(createAssignment(temp, classExpression)));
|
||||
// Add any pending expressions leftover from elided or relocated computed property names
|
||||
addRange(expressions, map(pendingExpressions, startOnNewLine));
|
||||
pendingExpressions = savedPendingExpressions;
|
||||
addRange(expressions, generateInitializedPropertyExpressions(staticProperties, temp));
|
||||
expressions.push(startOnNewLine(temp));
|
||||
return inlineExpressions(expressions);
|
||||
}
|
||||
|
||||
pendingExpressions = savedPendingExpressions;
|
||||
return classExpression;
|
||||
}
|
||||
|
||||
@@ -938,61 +888,81 @@ namespace ts {
|
||||
* Transforms the members of a class.
|
||||
*
|
||||
* @param node The current class.
|
||||
* @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'.
|
||||
*/
|
||||
function transformClassMembers(node: ClassDeclaration | ClassExpression, isDerivedClass: boolean) {
|
||||
function transformClassMembers(node: ClassDeclaration | ClassExpression) {
|
||||
const members: ClassElement[] = [];
|
||||
const constructor = transformConstructor(node, isDerivedClass);
|
||||
if (constructor) {
|
||||
members.push(constructor);
|
||||
}
|
||||
|
||||
addRange(members, visitNodes(node.members, classElementVisitor, isClassElement));
|
||||
return setTextRange(createNodeArray(members), /*location*/ node.members);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms (or creates) a constructor for a class.
|
||||
*
|
||||
* @param node The current class.
|
||||
* @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'.
|
||||
*/
|
||||
function transformConstructor(node: ClassDeclaration | ClassExpression, isDerivedClass: boolean) {
|
||||
// Check if we have property assignment inside class declaration.
|
||||
// If there is a property assignment, we need to emit constructor whether users define it or not
|
||||
// If there is no property assignment, we can omit constructor if users do not define it
|
||||
const existingMembers = visitNodes(node.members, classElementVisitor, isClassElement);
|
||||
const constructor = getFirstConstructorWithBody(node);
|
||||
const hasInstancePropertyWithInitializer = forEach(node.members, isInstanceInitializedProperty);
|
||||
const hasParameterPropertyAssignments = constructor &&
|
||||
constructor.transformFlags & TransformFlags.ContainsTypeScriptClassSyntax &&
|
||||
forEach(constructor.parameters, isParameterWithPropertyAssignment);
|
||||
const parametersWithPropertyAssignments =
|
||||
constructor && hasTypeScriptClassSyntax(constructor)
|
||||
? filter(constructor.parameters, isParameterPropertyDeclaration)
|
||||
: undefined;
|
||||
if (some(parametersWithPropertyAssignments) && constructor) {
|
||||
currentClassHasParameterProperties = true;
|
||||
|
||||
// If the class does not contain nodes that require a synthesized constructor,
|
||||
// accept the current constructor if it exists.
|
||||
if (!hasInstancePropertyWithInitializer && !hasParameterPropertyAssignments) {
|
||||
return visitEachChild(constructor, visitor, context);
|
||||
}
|
||||
|
||||
const parameters = transformConstructorParameters(constructor);
|
||||
const body = transformConstructorBody(node, constructor, isDerivedClass);
|
||||
|
||||
// constructor(${parameters}) {
|
||||
// ${body}
|
||||
// }
|
||||
return startOnNewLine(
|
||||
setOriginalNode(
|
||||
setTextRange(
|
||||
createConstructor(
|
||||
// Create property declarations for constructor parameter properties.
|
||||
addRange(
|
||||
members,
|
||||
parametersWithPropertyAssignments.map(param =>
|
||||
createProperty(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
parameters,
|
||||
body
|
||||
param.name,
|
||||
/*questionOrExclamationToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
/*initializer*/ undefined
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
const parameters = transformConstructorParameters(constructor);
|
||||
const body = transformConstructorBody(node.members, constructor, parametersWithPropertyAssignments);
|
||||
members.push(startOnNewLine(
|
||||
setOriginalNode(
|
||||
setTextRange(
|
||||
createConstructor(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
parameters,
|
||||
body
|
||||
),
|
||||
constructor
|
||||
),
|
||||
constructor || node
|
||||
),
|
||||
constructor
|
||||
)
|
||||
);
|
||||
constructor
|
||||
)
|
||||
));
|
||||
addRange(
|
||||
members,
|
||||
visitNodes(
|
||||
existingMembers,
|
||||
member => {
|
||||
if (isPropertyDeclaration(member) && !hasStaticModifier(member) && !!member.initializer) {
|
||||
const updated = updateProperty(
|
||||
member,
|
||||
member.decorators,
|
||||
member.modifiers,
|
||||
member.name,
|
||||
member.questionToken,
|
||||
member.type,
|
||||
/*initializer*/ undefined
|
||||
);
|
||||
setCommentRange(updated, node);
|
||||
setSourceMapRange(updated, node);
|
||||
return updated;
|
||||
}
|
||||
return member;
|
||||
},
|
||||
isClassElement
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
if (constructor) {
|
||||
members.push(visitEachChild(constructor, visitor, context));
|
||||
}
|
||||
addRange(members, existingMembers);
|
||||
}
|
||||
return setTextRange(createNodeArray(members), /*location*/ node.members);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1001,7 +971,7 @@ namespace ts {
|
||||
*
|
||||
* @param constructor The constructor declaration.
|
||||
*/
|
||||
function transformConstructorParameters(constructor: ConstructorDeclaration | undefined) {
|
||||
function transformConstructorParameters(constructor: ConstructorDeclaration) {
|
||||
// The ES2015 spec specifies in 14.5.14. Runtime Semantics: ClassDefinitionEvaluation:
|
||||
// If constructor is empty, then
|
||||
// If ClassHeritag_eopt is present and protoParent is not null, then
|
||||
@@ -1022,70 +992,54 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms (or creates) a constructor body for a class with parameter property
|
||||
* assignments or instance property initializers.
|
||||
* Transforms (or creates) a constructor body for a class with parameter property assignments.
|
||||
*
|
||||
* @param node The current class.
|
||||
* @param constructor The current class constructor.
|
||||
* @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'.
|
||||
*/
|
||||
function transformConstructorBody(node: ClassExpression | ClassDeclaration, constructor: ConstructorDeclaration | undefined, isDerivedClass: boolean) {
|
||||
function transformConstructorBody(members: NodeArray<ClassElement>, constructor: ConstructorDeclaration, propertyAssignments: ReadonlyArray<ParameterPropertyDeclaration>) {
|
||||
let statements: Statement[] = [];
|
||||
let indexOfFirstStatement = 0;
|
||||
|
||||
resumeLexicalEnvironment();
|
||||
|
||||
if (constructor) {
|
||||
indexOfFirstStatement = addPrologueDirectivesAndInitialSuperCall(constructor, statements);
|
||||
indexOfFirstStatement = addPrologueDirectivesAndInitialSuperCall(constructor, statements, visitor);
|
||||
|
||||
// Add parameters with property assignments. Transforms this:
|
||||
//
|
||||
// constructor (public x, public y) {
|
||||
// }
|
||||
//
|
||||
// Into this:
|
||||
//
|
||||
// constructor (x, y) {
|
||||
// this.x = x;
|
||||
// this.y = y;
|
||||
// }
|
||||
//
|
||||
const propertyAssignments = getParametersWithPropertyAssignments(constructor);
|
||||
addRange(statements, map(propertyAssignments, transformParameterWithPropertyAssignment));
|
||||
}
|
||||
else if (isDerivedClass) {
|
||||
// Add a synthetic `super` call:
|
||||
//
|
||||
// super(...arguments);
|
||||
//
|
||||
statements.push(
|
||||
createExpressionStatement(
|
||||
createCall(
|
||||
createSuper(),
|
||||
/*typeArguments*/ undefined,
|
||||
[createSpread(createIdentifier("arguments"))]
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Add the property initializers. Transforms this:
|
||||
// Add parameters with property assignments. Transforms this:
|
||||
//
|
||||
// public x = 1;
|
||||
// constructor (public x, public y) {
|
||||
// }
|
||||
//
|
||||
// Into this:
|
||||
//
|
||||
// constructor() {
|
||||
// this.x = 1;
|
||||
// constructor (x, y) {
|
||||
// this.x = x;
|
||||
// this.y = y;
|
||||
// }
|
||||
//
|
||||
const properties = getInitializedProperties(node, /*isStatic*/ false);
|
||||
addInitializedPropertyStatements(statements, properties, createThis());
|
||||
addRange(statements, map(propertyAssignments, transformParameterWithPropertyAssignment));
|
||||
|
||||
if (constructor) {
|
||||
// The class already had a constructor, so we should add the existing statements, skipping the initial super call.
|
||||
addRange(statements, visitNodes(constructor.body!.statements, visitor, isStatement, indexOfFirstStatement));
|
||||
}
|
||||
// Get property initializers.
|
||||
const classBodyProperties = members.filter(member => isPropertyDeclaration(member) && !hasStaticModifier(member) && !!member.initializer) as PropertyDeclaration[];
|
||||
addRange(statements, classBodyProperties.map(
|
||||
prop => {
|
||||
const name = prop.name;
|
||||
const lhs = (!isComputedPropertyName(name) || isSimpleInlineableExpression(name.expression)) ?
|
||||
createMemberAccessForPropertyName(createThis(), name, prop) :
|
||||
createElementAccess(createThis(), getGeneratedNameForNode(name));
|
||||
const initializerNode = createExpressionStatement(
|
||||
createAssignment(lhs, prop.initializer!)
|
||||
);
|
||||
setOriginalNode(initializerNode, prop);
|
||||
setTextRange(initializerNode, prop);
|
||||
setCommentRange(initializerNode, prop);
|
||||
setSourceMapRange(initializerNode, prop);
|
||||
return initializerNode;
|
||||
}
|
||||
));
|
||||
|
||||
// Add the existing statements, skipping the initial super call.
|
||||
addRange(statements, visitNodes(constructor.body!.statements, visitor, isStatement, indexOfFirstStatement));
|
||||
|
||||
// End the lexical environment.
|
||||
statements = mergeLexicalEnvironment(statements, endLexicalEnvironment());
|
||||
@@ -1093,7 +1047,7 @@ namespace ts {
|
||||
createBlock(
|
||||
setTextRange(
|
||||
createNodeArray(statements),
|
||||
/*location*/ constructor ? constructor.body!.statements : node.members
|
||||
/*location*/ constructor ? constructor.body!.statements : members
|
||||
),
|
||||
/*multiLine*/ true
|
||||
),
|
||||
@@ -1101,61 +1055,16 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds super call and preceding prologue directives into the list of statements.
|
||||
*
|
||||
* @param ctor The constructor node.
|
||||
* @returns index of the statement that follows super call
|
||||
*/
|
||||
function addPrologueDirectivesAndInitialSuperCall(ctor: ConstructorDeclaration, result: Statement[]): number {
|
||||
if (ctor.body) {
|
||||
const statements = ctor.body.statements;
|
||||
// add prologue directives to the list (if any)
|
||||
const index = addPrologue(result, statements, /*ensureUseStrict*/ false, visitor);
|
||||
if (index === statements.length) {
|
||||
// list contains nothing but prologue directives (or empty) - exit
|
||||
return index;
|
||||
}
|
||||
|
||||
const statement = statements[index];
|
||||
if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCall((<ExpressionStatement>statement).expression)) {
|
||||
result.push(visitNode(statement, visitor, isStatement));
|
||||
return index + 1;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all parameters of a constructor that should be transformed into property assignments.
|
||||
*
|
||||
* @param node The constructor node.
|
||||
*/
|
||||
function getParametersWithPropertyAssignments(node: ConstructorDeclaration): ReadonlyArray<ParameterDeclaration> {
|
||||
return filter(node.parameters, isParameterWithPropertyAssignment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a parameter should be transformed into a property assignment.
|
||||
*
|
||||
* @param parameter The parameter node.
|
||||
*/
|
||||
function isParameterWithPropertyAssignment(parameter: ParameterDeclaration) {
|
||||
return hasModifier(parameter, ModifierFlags.ParameterPropertyModifier)
|
||||
&& isIdentifier(parameter.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a parameter into a property assignment statement.
|
||||
*
|
||||
* @param node The parameter declaration.
|
||||
*/
|
||||
function transformParameterWithPropertyAssignment(node: ParameterDeclaration) {
|
||||
Debug.assert(isIdentifier(node.name));
|
||||
const name = node.name as Identifier;
|
||||
function transformParameterWithPropertyAssignment(node: ParameterPropertyDeclaration) {
|
||||
const name = node.name;
|
||||
if (!isIdentifier(name)) {
|
||||
return undefined;
|
||||
}
|
||||
const propertyName = getMutableClone(name);
|
||||
setEmitFlags(propertyName, EmitFlags.NoComments | EmitFlags.NoSourceMap);
|
||||
|
||||
@@ -1184,99 +1093,6 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all property declarations with initializers on either the static or instance side of a class.
|
||||
*
|
||||
* @param node The class node.
|
||||
* @param isStatic A value indicating whether to get properties from the static or instance side of the class.
|
||||
*/
|
||||
function getInitializedProperties(node: ClassExpression | ClassDeclaration, isStatic: boolean): ReadonlyArray<PropertyDeclaration> {
|
||||
return filter(node.members, isStatic ? isStaticInitializedProperty : isInstanceInitializedProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether a class element is a static property declaration with an initializer.
|
||||
*
|
||||
* @param member The class element node.
|
||||
*/
|
||||
function isStaticInitializedProperty(member: ClassElement): member is PropertyDeclaration {
|
||||
return isInitializedProperty(member, /*isStatic*/ true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether a class element is an instance property declaration with an initializer.
|
||||
*
|
||||
* @param member The class element node.
|
||||
*/
|
||||
function isInstanceInitializedProperty(member: ClassElement): member is PropertyDeclaration {
|
||||
return isInitializedProperty(member, /*isStatic*/ false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether a class element is either a static or an instance property declaration with an initializer.
|
||||
*
|
||||
* @param member The class element node.
|
||||
* @param isStatic A value indicating whether the member should be a static or instance member.
|
||||
*/
|
||||
function isInitializedProperty(member: ClassElement, isStatic: boolean) {
|
||||
return member.kind === SyntaxKind.PropertyDeclaration
|
||||
&& isStatic === hasModifier(member, ModifierFlags.Static)
|
||||
&& (<PropertyDeclaration>member).initializer !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates assignment statements for property initializers.
|
||||
*
|
||||
* @param properties An array of property declarations to transform.
|
||||
* @param receiver The receiver on which each property should be assigned.
|
||||
*/
|
||||
function addInitializedPropertyStatements(statements: Statement[], properties: ReadonlyArray<PropertyDeclaration>, receiver: LeftHandSideExpression) {
|
||||
for (const property of properties) {
|
||||
const statement = createExpressionStatement(transformInitializedProperty(property, receiver));
|
||||
setSourceMapRange(statement, moveRangePastModifiers(property));
|
||||
setCommentRange(statement, property);
|
||||
setOriginalNode(statement, property);
|
||||
statements.push(statement);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates assignment expressions for property initializers.
|
||||
*
|
||||
* @param properties An array of property declarations to transform.
|
||||
* @param receiver The receiver on which each property should be assigned.
|
||||
*/
|
||||
function generateInitializedPropertyExpressions(properties: ReadonlyArray<PropertyDeclaration>, receiver: LeftHandSideExpression) {
|
||||
const expressions: Expression[] = [];
|
||||
for (const property of properties) {
|
||||
const expression = transformInitializedProperty(property, receiver);
|
||||
startOnNewLine(expression);
|
||||
setSourceMapRange(expression, moveRangePastModifiers(property));
|
||||
setCommentRange(expression, property);
|
||||
setOriginalNode(expression, property);
|
||||
expressions.push(expression);
|
||||
}
|
||||
|
||||
return expressions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a property initializer into an assignment statement.
|
||||
*
|
||||
* @param property The property declaration.
|
||||
* @param receiver The object receiving the property assignment.
|
||||
*/
|
||||
function transformInitializedProperty(property: PropertyDeclaration, receiver: LeftHandSideExpression) {
|
||||
// We generate a name here in order to reuse the value cached by the relocated computed name expression (which uses the same generated name)
|
||||
const propertyName = isComputedPropertyName(property.name) && !isSimpleInlineableExpression(property.name.expression)
|
||||
? updateComputedPropertyName(property.name, getGeneratedNameForNode(property.name))
|
||||
: property.name;
|
||||
const initializer = visitNode(property.initializer!, visitor, isExpression);
|
||||
const memberAccess = createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName);
|
||||
|
||||
return createAssignment(memberAccess, initializer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets either the static or instance members of a class that are decorated, or have
|
||||
* parameters that are decorated.
|
||||
@@ -2144,16 +1960,6 @@ namespace ts {
|
||||
: createIdentifier("BigInt");
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple inlinable expression is an expression which can be copied into multiple locations
|
||||
* without risk of repeating any sideeffects and whose value could not possibly change between
|
||||
* any such locations
|
||||
*/
|
||||
function isSimpleInlineableExpression(expression: Expression) {
|
||||
return !isIdentifier(expression) && isSimpleCopiableExpression(expression) ||
|
||||
isWellKnownSymbolSyntactically(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an expression that represents a property name. For a computed property, a
|
||||
* name is generated for the node.
|
||||
@@ -2175,26 +1981,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the name is a computed property, this function transforms it, then either returns an expression which caches the
|
||||
* value of the result or the expression itself if the value is either unused or safe to inline into multiple locations
|
||||
* @param shouldHoist Does the expression need to be reused? (ie, for an initializer or a decorator)
|
||||
* @param omitSimple Should expressions with no observable side-effects be elided? (ie, the expression is not hoisted for a decorator or initializer and is a literal)
|
||||
*/
|
||||
function getPropertyNameExpressionIfNeeded(name: PropertyName, shouldHoist: boolean, omitSimple: boolean): Expression | undefined {
|
||||
if (isComputedPropertyName(name)) {
|
||||
const expression = visitNode(name.expression, visitor, isExpression);
|
||||
const innerExpression = skipPartiallyEmittedExpressions(expression);
|
||||
const inlinable = isSimpleInlineableExpression(innerExpression);
|
||||
if (!inlinable && shouldHoist) {
|
||||
const generatedName = getGeneratedNameForNode(name);
|
||||
hoistVariableDeclaration(generatedName);
|
||||
return createAssignment(generatedName, expression);
|
||||
}
|
||||
return (omitSimple && (inlinable || isIdentifier(innerExpression))) ? undefined : expression;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the property name of a class element, for use when emitting property
|
||||
* initializers. For a computed property on a node with decorators, a temporary
|
||||
@@ -2204,18 +1990,20 @@ namespace ts {
|
||||
*/
|
||||
function visitPropertyNameOfClassElement(member: ClassElement): PropertyName {
|
||||
const name = member.name!;
|
||||
let expr = getPropertyNameExpressionIfNeeded(name, some(member.decorators), /*omitSimple*/ false);
|
||||
if (expr) { // expr only exists if `name` is a computed property name
|
||||
// Inline any pending expressions from previous elided or relocated computed property name expressions in order to preserve execution order
|
||||
if (some(pendingExpressions)) {
|
||||
expr = inlineExpressions([...pendingExpressions, expr]);
|
||||
pendingExpressions.length = 0;
|
||||
// Computed property names need to be transformed into a hoisted variable when they are used more than once.
|
||||
// The names are used more than once when:
|
||||
// - the property is non-static and its initializer is moved to the constructor (when there are parameter property assignments).
|
||||
// - the property has a decorator.
|
||||
if (isComputedPropertyName(name) && ((!hasStaticModifier(member) && currentClassHasParameterProperties) || some(member.decorators))) {
|
||||
const expression = visitNode(name.expression, visitor, isExpression);
|
||||
const innerExpression = skipPartiallyEmittedExpressions(expression);
|
||||
if (!isSimpleInlineableExpression(innerExpression)) {
|
||||
const generatedName = getGeneratedNameForNode(name);
|
||||
hoistVariableDeclaration(generatedName);
|
||||
return updateComputedPropertyName(name, createAssignment(generatedName, expression));
|
||||
}
|
||||
return updateComputedPropertyName(name as ComputedPropertyName, expr);
|
||||
}
|
||||
else {
|
||||
return name;
|
||||
}
|
||||
return visitNode(name, visitor, isPropertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2261,12 +2049,23 @@ namespace ts {
|
||||
return !nodeIsMissing(node.body);
|
||||
}
|
||||
|
||||
function visitPropertyDeclaration(node: PropertyDeclaration): undefined {
|
||||
const expr = getPropertyNameExpressionIfNeeded(node.name, some(node.decorators) || !!node.initializer, /*omitSimple*/ true);
|
||||
if (expr && !isSimpleInlineableExpression(expr)) {
|
||||
(pendingExpressions || (pendingExpressions = [])).push(expr);
|
||||
function visitPropertyDeclaration(node: PropertyDeclaration) {
|
||||
const updated = updateProperty(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
visitPropertyNameOfClassElement(node),
|
||||
/*questionOrExclamationToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
visitNode(node.initializer, visitor)
|
||||
);
|
||||
if (updated !== node) {
|
||||
// While we emit the source map for the node after skipping decorators and modifiers,
|
||||
// we need to emit the comments for the original range.
|
||||
setCommentRange(updated, node);
|
||||
setSourceMapRange(updated, moveRangePastDecorators(node));
|
||||
}
|
||||
return undefined;
|
||||
return updated;
|
||||
}
|
||||
|
||||
function visitConstructor(node: ConstructorDeclaration) {
|
||||
|
||||
@@ -240,6 +240,47 @@ namespace ts {
|
||||
isIdentifier(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple inlinable expression is an expression which can be copied into multiple locations
|
||||
* without risk of repeating any sideeffects and whose value could not possibly change between
|
||||
* any such locations
|
||||
*/
|
||||
export function isSimpleInlineableExpression(expression: Expression) {
|
||||
return !isIdentifier(expression) && isSimpleCopiableExpression(expression) ||
|
||||
isWellKnownSymbolSyntactically(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds super call and preceding prologue directives into the list of statements.
|
||||
*
|
||||
* @param ctor The constructor node.
|
||||
* @param result The list of statements.
|
||||
* @param visitor The visitor to apply to each node added to the result array.
|
||||
* @returns index of the statement that follows super call
|
||||
*/
|
||||
export function addPrologueDirectivesAndInitialSuperCall(ctor: ConstructorDeclaration, result: Statement[], visitor: Visitor): number {
|
||||
if (ctor.body) {
|
||||
const statements = ctor.body.statements;
|
||||
// add prologue directives to the list (if any)
|
||||
const index = addPrologue(result, statements, /*ensureUseStrict*/ false, visitor);
|
||||
if (index === statements.length) {
|
||||
// list contains nothing but prologue directives (or empty) - exit
|
||||
return index;
|
||||
}
|
||||
|
||||
const statement = statements[index];
|
||||
if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCall((<ExpressionStatement>statement).expression)) {
|
||||
result.push(visitNode(statement, visitor, isStatement));
|
||||
return index + 1;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param input Template string input strings
|
||||
* @param args Names which need to be made file-level unique
|
||||
@@ -255,4 +296,43 @@ namespace ts {
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all property declarations with initializers on either the static or instance side of a class.
|
||||
*
|
||||
* @param node The class node.
|
||||
* @param isStatic A value indicating whether to get properties from the static or instance side of the class.
|
||||
*/
|
||||
export function getInitializedProperties(node: ClassExpression | ClassDeclaration, isStatic: boolean): ReadonlyArray<PropertyDeclaration> {
|
||||
return filter(node.members, isStatic ? isStaticInitializedProperty : isInstanceInitializedProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether a class element is a static property declaration with an initializer.
|
||||
*
|
||||
* @param member The class element node.
|
||||
*/
|
||||
export function isStaticInitializedProperty(member: ClassElement): member is PropertyDeclaration & { initializer: Expression; } {
|
||||
return isInitializedProperty(member) && hasStaticModifier(member);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether a class element is an instance property declaration with an initializer.
|
||||
*
|
||||
* @param member The class element node.
|
||||
*/
|
||||
export function isInstanceInitializedProperty(member: ClassElement): member is PropertyDeclaration & { initializer: Expression; } {
|
||||
return isInitializedProperty(member) && !hasStaticModifier(member);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether a class element is either a static or an instance property declaration with an initializer.
|
||||
*
|
||||
* @param member The class element node.
|
||||
* @param isStatic A value indicating whether the member should be a static or instance member.
|
||||
*/
|
||||
export function isInitializedProperty(member: ClassElement): member is PropertyDeclaration & { initializer: Expression; } {
|
||||
return member.kind === SyntaxKind.PropertyDeclaration
|
||||
&& (<PropertyDeclaration>member).initializer !== undefined;
|
||||
}
|
||||
}
|
||||
+1725
-1232
File diff suppressed because it is too large
Load Diff
@@ -30,6 +30,7 @@
|
||||
"transformers/utilities.ts",
|
||||
"transformers/destructuring.ts",
|
||||
"transformers/ts.ts",
|
||||
"transformers/classFields.ts",
|
||||
"transformers/es2017.ts",
|
||||
"transformers/es2018.ts",
|
||||
"transformers/es2019.ts",
|
||||
|
||||
@@ -3068,6 +3068,9 @@ namespace ts {
|
||||
|
||||
// Diagnostics were produced and outputs were generated in spite of them.
|
||||
DiagnosticsPresent_OutputsGenerated = 2,
|
||||
|
||||
// When build skipped because passed in project is invalid
|
||||
InvalidProject_OutputsSkipped = 3,
|
||||
}
|
||||
|
||||
export interface EmitResult {
|
||||
@@ -3154,6 +3157,7 @@ namespace ts {
|
||||
*/
|
||||
getExportSymbolOfSymbol(symbol: Symbol): Symbol;
|
||||
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined;
|
||||
getTypeOfAssignmentPattern(pattern: AssignmentPattern): Type;
|
||||
getTypeAtLocation(node: Node): Type;
|
||||
getTypeFromTypeNode(node: TypeNode): Type;
|
||||
|
||||
@@ -3751,6 +3755,8 @@ namespace ts {
|
||||
extendedContainers?: Symbol[]; // Containers (other than the parent) which this symbol is aliased in
|
||||
extendedContainersByFile?: Map<Symbol[]>; // Containers (other than the parent) which this symbol is aliased in
|
||||
variances?: VarianceFlags[]; // Alias symbol type argument variance cache
|
||||
deferralConstituents?: Type[]; // Calculated list of constituents for a deferred type
|
||||
deferralParent?: Type; // Source union/intersection of a deferred type
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -3777,6 +3783,7 @@ namespace ts {
|
||||
ReverseMapped = 1 << 13, // Property of reverse-inferred homomorphic mapped type
|
||||
OptionalParameter = 1 << 14, // Optional parameter
|
||||
RestParameter = 1 << 15, // Rest parameter
|
||||
DeferredType = 1 << 16, // Calculation of the type of this symbol is deferred due to processing costs, should be fetched with `getTypeOfSymbolWithDeferredType`
|
||||
Synthetic = SyntheticProperty | SyntheticMethod,
|
||||
Discriminant = HasNonUniformType | HasLiteralType,
|
||||
Partial = ReadPartial | WritePartial
|
||||
@@ -4009,6 +4016,8 @@ namespace ts {
|
||||
restrictiveInstantiation?: Type; // Instantiation with type parameters mapped to unconstrained form
|
||||
/* @internal */
|
||||
immediateBaseConstraint?: Type; // Immediate base constraint cache
|
||||
/* @internal */
|
||||
widened?: Type; // Cached widened form of the type
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -5188,6 +5197,7 @@ namespace ts {
|
||||
ContainsYield = 1 << 17,
|
||||
ContainsHoistedDeclarationOrCompletion = 1 << 18,
|
||||
ContainsDynamicImport = 1 << 19,
|
||||
ContainsClassFields = 1 << 20,
|
||||
|
||||
// Please leave this as 1 << 29.
|
||||
// It is the maximum bit we can set before we outgrow the size of a v8 small integer (SMI) on an x86 system.
|
||||
|
||||
+80
-43
@@ -88,8 +88,6 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export type ReportEmitErrorSummary = (errorCount: number) => void;
|
||||
|
||||
export function getErrorCountForSummary(diagnostics: ReadonlyArray<Diagnostic>) {
|
||||
return countWhere(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error);
|
||||
}
|
||||
@@ -113,12 +111,12 @@ namespace ts {
|
||||
getCurrentDirectory(): string;
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
getSourceFiles(): ReadonlyArray<SourceFile>;
|
||||
getSyntacticDiagnostics(): ReadonlyArray<Diagnostic>;
|
||||
getOptionsDiagnostics(): ReadonlyArray<Diagnostic>;
|
||||
getGlobalDiagnostics(): ReadonlyArray<Diagnostic>;
|
||||
getSemanticDiagnostics(): ReadonlyArray<Diagnostic>;
|
||||
getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getOptionsDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getConfigFileParsingDiagnostics(): ReadonlyArray<Diagnostic>;
|
||||
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback): EmitResult;
|
||||
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult;
|
||||
}
|
||||
|
||||
export function listFiles(program: ProgramToEmitFilesAndReportErrors, writeFileName: (s: string) => void) {
|
||||
@@ -132,25 +130,35 @@ namespace ts {
|
||||
/**
|
||||
* Helper that emit files, report diagnostics and lists emitted and/or source files depending on compiler options
|
||||
*/
|
||||
export function emitFilesAndReportErrors(program: ProgramToEmitFilesAndReportErrors, reportDiagnostic: DiagnosticReporter, writeFileName?: (s: string) => void, reportSummary?: ReportEmitErrorSummary, writeFile?: WriteFileCallback) {
|
||||
export function emitFilesAndReportErrors(
|
||||
program: ProgramToEmitFilesAndReportErrors,
|
||||
reportDiagnostic: DiagnosticReporter,
|
||||
writeFileName?: (s: string) => void,
|
||||
reportSummary?: ReportEmitErrorSummary,
|
||||
writeFile?: WriteFileCallback,
|
||||
cancellationToken?: CancellationToken,
|
||||
emitOnlyDtsFiles?: boolean,
|
||||
customTransformers?: CustomTransformers
|
||||
) {
|
||||
// First get and report any syntactic errors.
|
||||
const diagnostics = program.getConfigFileParsingDiagnostics().slice();
|
||||
const configFileParsingDiagnosticsLength = diagnostics.length;
|
||||
addRange(diagnostics, program.getSyntacticDiagnostics());
|
||||
addRange(diagnostics, program.getSyntacticDiagnostics(/*sourceFile*/ undefined, cancellationToken));
|
||||
|
||||
// If we didn't have any syntactic errors, then also try getting the global and
|
||||
// semantic errors.
|
||||
if (diagnostics.length === configFileParsingDiagnosticsLength) {
|
||||
addRange(diagnostics, program.getOptionsDiagnostics());
|
||||
addRange(diagnostics, program.getGlobalDiagnostics());
|
||||
addRange(diagnostics, program.getOptionsDiagnostics(cancellationToken));
|
||||
addRange(diagnostics, program.getGlobalDiagnostics(cancellationToken));
|
||||
|
||||
if (diagnostics.length === configFileParsingDiagnosticsLength) {
|
||||
addRange(diagnostics, program.getSemanticDiagnostics());
|
||||
addRange(diagnostics, program.getSemanticDiagnostics(/*sourceFile*/ undefined, cancellationToken));
|
||||
}
|
||||
}
|
||||
|
||||
// Emit and report any errors we ran into.
|
||||
const { emittedFiles, emitSkipped, diagnostics: emitDiagnostics } = program.emit(/*targetSourceFile*/ undefined, writeFile);
|
||||
const emitResult = program.emit(/*targetSourceFile*/ undefined, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers);
|
||||
const { emittedFiles, diagnostics: emitDiagnostics } = emitResult;
|
||||
addRange(diagnostics, emitDiagnostics);
|
||||
|
||||
sortAndDeduplicateDiagnostics(diagnostics).forEach(reportDiagnostic);
|
||||
@@ -167,7 +175,34 @@ namespace ts {
|
||||
reportSummary(getErrorCountForSummary(diagnostics));
|
||||
}
|
||||
|
||||
if (emitSkipped && diagnostics.length > 0) {
|
||||
return {
|
||||
emitResult,
|
||||
diagnostics,
|
||||
};
|
||||
}
|
||||
|
||||
export function emitFilesAndReportErrorsAndGetExitStatus(
|
||||
program: ProgramToEmitFilesAndReportErrors,
|
||||
reportDiagnostic: DiagnosticReporter,
|
||||
writeFileName?: (s: string) => void,
|
||||
reportSummary?: ReportEmitErrorSummary,
|
||||
writeFile?: WriteFileCallback,
|
||||
cancellationToken?: CancellationToken,
|
||||
emitOnlyDtsFiles?: boolean,
|
||||
customTransformers?: CustomTransformers
|
||||
) {
|
||||
const { emitResult, diagnostics } = emitFilesAndReportErrors(
|
||||
program,
|
||||
reportDiagnostic,
|
||||
writeFileName,
|
||||
reportSummary,
|
||||
writeFile,
|
||||
cancellationToken,
|
||||
emitOnlyDtsFiles,
|
||||
customTransformers
|
||||
);
|
||||
|
||||
if (emitResult.emitSkipped && diagnostics.length > 0) {
|
||||
// If the emitter didn't emit anything, then pass that value along.
|
||||
return ExitStatus.DiagnosticsPresent_OutputsSkipped;
|
||||
}
|
||||
@@ -375,6 +410,33 @@ namespace ts {
|
||||
return host;
|
||||
}
|
||||
|
||||
export interface IncrementalCompilationOptions {
|
||||
rootNames: ReadonlyArray<string>;
|
||||
options: CompilerOptions;
|
||||
configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>;
|
||||
projectReferences?: ReadonlyArray<ProjectReference>;
|
||||
host?: CompilerHost;
|
||||
reportDiagnostic?: DiagnosticReporter;
|
||||
reportErrorSummary?: ReportEmitErrorSummary;
|
||||
afterProgramEmitAndDiagnostics?(program: EmitAndSemanticDiagnosticsBuilderProgram): void;
|
||||
system?: System;
|
||||
}
|
||||
export function performIncrementalCompilation(input: IncrementalCompilationOptions) {
|
||||
const system = input.system || sys;
|
||||
const host = input.host || (input.host = createIncrementalCompilerHost(input.options, system));
|
||||
const builderProgram = createIncrementalProgram(input);
|
||||
const exitStatus = emitFilesAndReportErrorsAndGetExitStatus(
|
||||
builderProgram,
|
||||
input.reportDiagnostic || createDiagnosticReporter(system),
|
||||
s => host.trace && host.trace(s),
|
||||
input.reportErrorSummary || input.options.pretty ? errorCount => system.write(getErrorSummaryText(errorCount, system.newLine)) : undefined
|
||||
);
|
||||
if (input.afterProgramEmitAndDiagnostics) input.afterProgramEmitAndDiagnostics(builderProgram);
|
||||
return exitStatus;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ts {
|
||||
export function readBuilderProgram(compilerOptions: CompilerOptions, readFile: (path: string) => string | undefined) {
|
||||
if (compilerOptions.out || compilerOptions.outFile) return undefined;
|
||||
const buildInfoPath = getOutputPathForBuildInfo(compilerOptions);
|
||||
@@ -395,7 +457,7 @@ namespace ts {
|
||||
return host;
|
||||
}
|
||||
|
||||
interface IncrementalProgramOptions<T extends BuilderProgram> {
|
||||
export interface IncrementalProgramOptions<T extends BuilderProgram> {
|
||||
rootNames: ReadonlyArray<string>;
|
||||
options: CompilerOptions;
|
||||
configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>;
|
||||
@@ -403,7 +465,8 @@ namespace ts {
|
||||
host?: CompilerHost;
|
||||
createProgram?: CreateProgram<T>;
|
||||
}
|
||||
function createIncrementalProgram<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>({
|
||||
|
||||
export function createIncrementalProgram<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>({
|
||||
rootNames, options, configFileParsingDiagnostics, projectReferences, host, createProgram
|
||||
}: IncrementalProgramOptions<T>): T {
|
||||
host = host || createIncrementalCompilerHost(options);
|
||||
@@ -412,33 +475,6 @@ namespace ts {
|
||||
return createProgram(rootNames, options, host, oldProgram, configFileParsingDiagnostics, projectReferences);
|
||||
}
|
||||
|
||||
export interface IncrementalCompilationOptions {
|
||||
rootNames: ReadonlyArray<string>;
|
||||
options: CompilerOptions;
|
||||
configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>;
|
||||
projectReferences?: ReadonlyArray<ProjectReference>;
|
||||
host?: CompilerHost;
|
||||
reportDiagnostic?: DiagnosticReporter;
|
||||
reportErrorSummary?: ReportEmitErrorSummary;
|
||||
afterProgramEmitAndDiagnostics?(program: EmitAndSemanticDiagnosticsBuilderProgram): void;
|
||||
system?: System;
|
||||
}
|
||||
export function performIncrementalCompilation(input: IncrementalCompilationOptions) {
|
||||
const system = input.system || sys;
|
||||
const host = input.host || (input.host = createIncrementalCompilerHost(input.options, system));
|
||||
const builderProgram = createIncrementalProgram(input);
|
||||
const exitStatus = emitFilesAndReportErrors(
|
||||
builderProgram,
|
||||
input.reportDiagnostic || createDiagnosticReporter(system),
|
||||
s => host.trace && host.trace(s),
|
||||
input.reportErrorSummary || input.options.pretty ? errorCount => system.write(getErrorSummaryText(errorCount, system.newLine)) : undefined
|
||||
);
|
||||
if (input.afterProgramEmitAndDiagnostics) input.afterProgramEmitAndDiagnostics(builderProgram);
|
||||
return exitStatus;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ts {
|
||||
export type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string, options: CompilerOptions) => void;
|
||||
/** Create the program with rootNames and options, if they are undefined, oldProgram and new configFile diagnostics create new program */
|
||||
export type CreateProgram<T extends BuilderProgram> = (rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference> | undefined) => T;
|
||||
@@ -691,6 +727,7 @@ namespace ts {
|
||||
hasChangedAutomaticTypeDirectiveNames = true;
|
||||
scheduleProgramUpdate();
|
||||
};
|
||||
compilerHost.fileIsOpen = returnFalse;
|
||||
compilerHost.maxNumberOfFilesToIterateForInvalidation = host.maxNumberOfFilesToIterateForInvalidation;
|
||||
compilerHost.getCurrentProgram = getCurrentProgram;
|
||||
compilerHost.writeLog = writeLog;
|
||||
|
||||
+34
-25
@@ -388,10 +388,42 @@ namespace fakes {
|
||||
return ts.compareStringsCaseSensitive(ts.isString(a) ? a : a[0], ts.isString(b) ? b : b[0]);
|
||||
}
|
||||
|
||||
export function sanitizeBuildInfoProgram(buildInfo: ts.BuildInfo) {
|
||||
if (buildInfo.program) {
|
||||
// reference Map
|
||||
if (buildInfo.program.referencedMap) {
|
||||
const referencedMap: ts.MapLike<string[]> = {};
|
||||
for (const path of ts.getOwnKeys(buildInfo.program.referencedMap).sort()) {
|
||||
referencedMap[path] = buildInfo.program.referencedMap[path].sort();
|
||||
}
|
||||
buildInfo.program.referencedMap = referencedMap;
|
||||
}
|
||||
|
||||
// exportedModulesMap
|
||||
if (buildInfo.program.exportedModulesMap) {
|
||||
const exportedModulesMap: ts.MapLike<string[]> = {};
|
||||
for (const path of ts.getOwnKeys(buildInfo.program.exportedModulesMap).sort()) {
|
||||
exportedModulesMap[path] = buildInfo.program.exportedModulesMap[path].sort();
|
||||
}
|
||||
buildInfo.program.exportedModulesMap = exportedModulesMap;
|
||||
}
|
||||
|
||||
// semanticDiagnosticsPerFile
|
||||
if (buildInfo.program.semanticDiagnosticsPerFile) {
|
||||
buildInfo.program.semanticDiagnosticsPerFile.sort(compareProgramBuildInfoDiagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const version = "FakeTSVersion";
|
||||
|
||||
export class SolutionBuilderHost extends CompilerHost implements ts.SolutionBuilderHost<ts.BuilderProgram> {
|
||||
createProgram = ts.createEmitAndSemanticDiagnosticsBuilderProgram;
|
||||
createProgram: ts.CreateProgram<ts.BuilderProgram>;
|
||||
|
||||
constructor(sys: System | vfs.FileSystem, options?: ts.CompilerOptions, setParentNodes?: boolean, createProgram?: ts.CreateProgram<ts.BuilderProgram>) {
|
||||
super(sys, options, setParentNodes);
|
||||
this.createProgram = createProgram || ts.createEmitAndSemanticDiagnosticsBuilderProgram;
|
||||
}
|
||||
|
||||
readFile(path: string) {
|
||||
const value = super.readFile(path);
|
||||
@@ -405,30 +437,7 @@ namespace fakes {
|
||||
public writeFile(fileName: string, content: string, writeByteOrderMark: boolean) {
|
||||
if (!ts.isBuildInfoFile(fileName)) return super.writeFile(fileName, content, writeByteOrderMark);
|
||||
const buildInfo = ts.getBuildInfo(content);
|
||||
if (buildInfo.program) {
|
||||
// reference Map
|
||||
if (buildInfo.program.referencedMap) {
|
||||
const referencedMap: ts.MapLike<string[]> = {};
|
||||
for (const path of ts.getOwnKeys(buildInfo.program.referencedMap).sort()) {
|
||||
referencedMap[path] = buildInfo.program.referencedMap[path].sort();
|
||||
}
|
||||
buildInfo.program.referencedMap = referencedMap;
|
||||
}
|
||||
|
||||
// exportedModulesMap
|
||||
if (buildInfo.program.exportedModulesMap) {
|
||||
const exportedModulesMap: ts.MapLike<string[]> = {};
|
||||
for (const path of ts.getOwnKeys(buildInfo.program.exportedModulesMap).sort()) {
|
||||
exportedModulesMap[path] = buildInfo.program.exportedModulesMap[path].sort();
|
||||
}
|
||||
buildInfo.program.exportedModulesMap = exportedModulesMap;
|
||||
}
|
||||
|
||||
// semanticDiagnosticsPerFile
|
||||
if (buildInfo.program.semanticDiagnosticsPerFile) {
|
||||
buildInfo.program.semanticDiagnosticsPerFile.sort(compareProgramBuildInfoDiagnostic);
|
||||
}
|
||||
}
|
||||
sanitizeBuildInfoProgram(buildInfo);
|
||||
buildInfo.version = version;
|
||||
super.writeFile(fileName, ts.getBuildInfoText(buildInfo), writeByteOrderMark);
|
||||
}
|
||||
|
||||
@@ -1218,7 +1218,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
}
|
||||
|
||||
public verifySignatureHelpPresence(expectPresent: boolean, triggerReason: ts.SignatureHelpTriggerReason | undefined, markers: ReadonlyArray<string>) {
|
||||
public verifySignatureHelpPresence(expectPresent: boolean, triggerReason: ts.SignatureHelpTriggerReason | undefined, markers: ReadonlyArray<string | Marker>) {
|
||||
if (markers.length) {
|
||||
for (const marker of markers) {
|
||||
this.goToMarker(marker);
|
||||
@@ -3786,15 +3786,15 @@ namespace FourSlashInterface {
|
||||
assert(ranges.length !== 0, "Array of ranges is expected to be non-empty");
|
||||
}
|
||||
|
||||
public noSignatureHelp(...markers: string[]): void {
|
||||
public noSignatureHelp(...markers: (string | FourSlash.Marker)[]): void {
|
||||
this.state.verifySignatureHelpPresence(/*expectPresent*/ false, /*triggerReason*/ undefined, markers);
|
||||
}
|
||||
|
||||
public noSignatureHelpForTriggerReason(reason: ts.SignatureHelpTriggerReason, ...markers: string[]): void {
|
||||
public noSignatureHelpForTriggerReason(reason: ts.SignatureHelpTriggerReason, ...markers: (string | FourSlash.Marker)[]): void {
|
||||
this.state.verifySignatureHelpPresence(/*expectPresent*/ false, reason, markers);
|
||||
}
|
||||
|
||||
public signatureHelpPresentForTriggerReason(reason: ts.SignatureHelpTriggerReason, ...markers: string[]): void {
|
||||
public signatureHelpPresentForTriggerReason(reason: ts.SignatureHelpTriggerReason, ...markers: (string | FourSlash.Marker)[]): void {
|
||||
this.state.verifySignatureHelpPresence(/*expectPresent*/ true, reason, markers);
|
||||
}
|
||||
|
||||
@@ -5142,7 +5142,7 @@ namespace FourSlashInterface {
|
||||
}
|
||||
|
||||
export interface VerifySignatureHelpOptions {
|
||||
readonly marker?: ArrayOrSingle<string>;
|
||||
readonly marker?: ArrayOrSingle<string | FourSlash.Marker>;
|
||||
/** @default 1 */
|
||||
readonly overloadsCount?: number;
|
||||
/** @default undefined */
|
||||
|
||||
@@ -2881,7 +2881,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Default export of the module has or is using private name '{0}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[모듈의 기본 내보내기에서 전용 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[모듈의 기본 내보내기에서 프라이빗 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3667,7 +3667,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Exported type alias '{0}' has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 형식 별칭 '{0}'은(는) '{1}' 전용 이름을 포함하거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 형식 별칭 '{0}'은(는) '{1}' 프라이빗 이름을 포함하거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3685,7 +3685,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Exported variable '{0}' has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 변수 '{0}'이(가) 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 변수 '{0}'이(가) 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3694,7 +3694,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Exported variable '{0}' has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -4369,7 +4369,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Implements clause of exported class '{0}' has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스 '{0}'의 Implements 절이 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스 '{0}'의 Implements 절이 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -4399,7 +4399,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import declaration '{0}' is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[가져오기 선언 '{0}'이(가) 전용 이름 '{1}'을(를) 사용하고 있습니다.]]></Val>
|
||||
<Val><![CDATA[가져오기 선언 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 사용하고 있습니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -5242,7 +5242,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Method '{0}' of exported interface has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스의 '{0}' 메서드가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스의 '{0}' 메서드가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -5251,7 +5251,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Method '{0}' of exported interface has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스의 '{0}' 메서드가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스의 '{0}' 메서드가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -5935,7 +5935,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Overload signatures must all be public, private or protected.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[오버로드 시그니처는 모두 공용, 전용 또는 보호된 상태여야 합니다.]]></Val>
|
||||
<Val><![CDATA[오버로드 시그니처는 모두 퍼블릭, 프라이빗 또는 보호된 상태여야 합니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -5971,7 +5971,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' of call signature from exported interface has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 호출 시그니처의 '{0}' 매개 변수가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 호출 시그니처의 '{0}' 매개 변수가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -5980,7 +5980,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' of call signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 호출 시그니처의 '{0}' 매개 변수가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 호출 시그니처의 '{0}' 매개 변수가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -5998,7 +5998,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' of constructor from exported class has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 생성자의 '{0}' 매개 변수가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 생성자의 '{0}' 매개 변수가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6007,7 +6007,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' of constructor from exported class has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 생성자의 '{0}' 매개 변수가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 생성자의 '{0}' 매개 변수가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6016,7 +6016,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' of constructor signature from exported interface has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 생성자 시그니처의 '{0}' 매개 변수가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 생성자 시그니처의 '{0}' 매개 변수가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6025,7 +6025,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 생성자 시그니처의 '{0}' 매개 변수가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 생성자 시그니처의 '{0}' 매개 변수가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6043,7 +6043,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' of exported function has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 함수의 '{0}' 매개 변수가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 함수의 '{0}' 매개 변수가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6052,7 +6052,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' of exported function has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 함수의 '{0}' 매개 변수가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 함수의 '{0}' 매개 변수가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6061,7 +6061,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' of index signature from exported interface has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 인덱스 시그니처의 '{0}' 매개 변수가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 인덱스 시그니처의 '{0}' 매개 변수가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6070,7 +6070,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' of index signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 인덱스 시그니처의 '{0}' 매개 변수가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 인덱스 시그니처의 '{0}' 매개 변수가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6079,7 +6079,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' of method from exported interface has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 메서드의 '{0}' 매개 변수가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 메서드의 '{0}' 매개 변수가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6088,7 +6088,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' of method from exported interface has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 메서드의 '{0}' 매개 변수가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 메서드의 '{0}' 매개 변수가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6106,7 +6106,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' of public method from exported class has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 메서드의 '{0}' 매개 변수가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 메서드의 '{0}' 매개 변수가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6115,7 +6115,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' of public method from exported class has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 메서드의 '{0}' 매개 변수가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 메서드의 '{0}' 매개 변수가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6133,7 +6133,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' of public static method from exported class has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 메서드의 '{0}' 매개 변수가 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 메서드의 '{0}' 매개 변수가 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6142,7 +6142,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter '{0}' of public static method from exported class has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 메서드의 '{0}' 매개 변수가 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 메서드의 '{0}' 매개 변수가 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6169,7 +6169,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter type of public setter '{0}' from exported class has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 setter '{0}'의 매개 변수 형식이 전용 모듈 '{2}'의 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 setter '{0}'의 매개 변수 형식이 프라이빗 모듈 '{2}'의 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6178,7 +6178,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter type of public setter '{0}' from exported class has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 setter '{0}'의 매개 변수 형식이 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 setter '{0}'의 매개 변수 형식이 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6187,7 +6187,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter type of public static setter '{0}' from exported class has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 setter '{0}'의 매개 변수 형식이 전용 모듈 '{2}'의 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 setter '{0}'의 매개 변수 형식이 프라이빗 모듈 '{2}'의 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6196,7 +6196,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Parameter type of public static setter '{0}' from exported class has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 setter '{0}'의 매개 변수 형식이 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 setter '{0}'의 매개 변수 형식이 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6577,7 +6577,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Property '{0}' of exported class expression may not be private or protected.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스 식의 속성 '{0}'이(가) 비공개가 아니거나 보호되지 않을 수 있습니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스 식의 속성 '{0}'이(가) 프라이빗이 아니거나 보호되지 않을 수 있습니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6586,7 +6586,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Property '{0}' of exported interface has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스의 '{0}' 속성이 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스의 '{0}' 속성이 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6595,7 +6595,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Property '{0}' of exported interface has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스의 '{0}' 속성이 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스의 '{0}' 속성이 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6676,7 +6676,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public method '{0}' of exported class has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스의 공용 메서드 '{0}'이(가) 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스의 공용 메서드 '{0}'이(가) 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6685,7 +6685,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public method '{0}' of exported class has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스의 공용 메서드의 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스의 공용 메서드의 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6703,7 +6703,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public property '{0}' of exported class has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스의 공용 속성 '{0}'이(가) 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스의 공용 속성 '{0}'이(가) 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6712,7 +6712,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public property '{0}' of exported class has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스의 공용 속성 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스의 공용 속성 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6730,7 +6730,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public static method '{0}' of exported class has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 메서드 '{0}'이(가) 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 메서드 '{0}'이(가) 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6739,7 +6739,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public static method '{0}' of exported class has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스의 공용 정적 메서드 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스의 공용 정적 메서드 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6757,7 +6757,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public static property '{0}' of exported class has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스의 공용 정적 속성 '{0}'이(가) 전용 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스의 공용 정적 속성 '{0}'이(가) 프라이빗 모듈 '{2}'의 '{1}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6766,7 +6766,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Public static property '{0}' of exported class has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스의 공용 정적 속성 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스의 공용 정적 속성 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7090,7 +7090,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of call signature from exported interface has or is using name '{0}' from private module '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 호출 시그니처의 반환 형식이 전용 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 호출 시그니처의 반환 형식이 프라이빗 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7099,7 +7099,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of call signature from exported interface has or is using private name '{0}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 호출 시그니처의 반환 형식이 전용 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 호출 시그니처의 반환 형식이 프라이빗 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7108,7 +7108,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of constructor signature from exported interface has or is using name '{0}' from private module '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 생성자 시그니처의 반환 형식이 전용 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 생성자 시그니처의 반환 형식이 프라이빗 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7117,7 +7117,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of constructor signature from exported interface has or is using private name '{0}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 생성자 시그니처의 반환 형식이 전용 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 생성자 시그니처의 반환 형식이 프라이빗 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7147,7 +7147,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of exported function has or is using name '{0}' from private module '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 함수의 반환 형식이 전용 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 함수의 반환 형식이 프라이빗 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7156,7 +7156,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of exported function has or is using private name '{0}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 함수의 반환 형식이 전용 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 함수의 반환 형식이 프라이빗 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7165,7 +7165,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of index signature from exported interface has or is using name '{0}' from private module '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 인덱스 시그니처의 반환 형식이 전용 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 인덱스 시그니처의 반환 형식이 프라이빗 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7174,7 +7174,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of index signature from exported interface has or is using private name '{0}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 인덱스 시그니처의 반환 형식이 전용 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 인덱스 시그니처의 반환 형식이 프라이빗 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7183,7 +7183,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of method from exported interface has or is using name '{0}' from private module '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 메서드의 반환 형식이 전용 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 메서드의 반환 형식이 프라이빗 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7192,7 +7192,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of method from exported interface has or is using private name '{0}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 메서드의 반환 형식이 전용 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 메서드의 반환 형식이 프라이빗 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7210,7 +7210,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of public getter '{0}' from exported class has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 getter '{0}'의 반환 형식이 전용 모듈 '{2}'의 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 getter '{0}'의 반환 형식이 프라이빗 모듈 '{2}'의 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7219,7 +7219,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of public getter '{0}' from exported class has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 getter '{0}'의 반환 형식이 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 getter '{0}'의 반환 형식이 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7237,7 +7237,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of public method from exported class has or is using name '{0}' from private module '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 메서드의 반환 형식이 전용 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 메서드의 반환 형식이 프라이빗 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7246,7 +7246,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of public method from exported class has or is using private name '{0}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 메서드의 반환 형식이 전용 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 메서드의 반환 형식이 프라이빗 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7264,7 +7264,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of public static getter '{0}' from exported class has or is using name '{1}' from private module '{2}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 getter '{0}'의 반환 형식이 전용 모듈 '{2}'의 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 getter '{0}'의 반환 형식이 프라이빗 모듈 '{2}'의 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7273,7 +7273,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of public static getter '{0}' from exported class has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 getter '{0}'의 반환 형식이 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 getter '{0}'의 반환 형식이 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7291,7 +7291,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of public static method from exported class has or is using name '{0}' from private module '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 메서드의 반환 형식이 전용 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 메서드의 반환 형식이 프라이빗 모듈 '{1}'의 '{0}' 이름을 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7300,7 +7300,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Return type of public static method from exported class has or is using private name '{0}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 메서드의 반환 형식이 전용 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 메서드의 반환 형식이 프라이빗 이름 '{0}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -8692,7 +8692,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 호출 시그니처의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 호출 시그니처의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -8701,7 +8701,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 생성자 시그니처의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 생성자 시그니처의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -8710,7 +8710,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of exported class has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -8719,7 +8719,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of exported function has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 함수의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 함수의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -8728,7 +8728,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of exported interface has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -8737,7 +8737,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of exported type alias has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 형식 별칭의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 형식 별칭의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -8746,7 +8746,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of method from exported interface has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 메서드의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스에 있는 메서드의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -8755,7 +8755,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of public method from exported class has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 메서드의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 메서드의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -8764,7 +8764,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of public static method from exported class has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 메서드의 형식 매개 변수 '{0}'이(가) 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스에 있는 공용 정적 메서드의 형식 매개 변수 '{0}'이(가) 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -8839,7 +8839,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Types have separate declarations of a private property '{0}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[형식에 별도의 전용 속성 '{0}' 선언이 있습니다.]]></Val>
|
||||
<Val><![CDATA[형식에 별도의 프라이빗 속성 '{0}' 선언이 있습니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -9676,7 +9676,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['extends' clause of exported class '{0}' has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 클래스 '{0}'의 Extends 절이 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 클래스 '{0}'의 Extends 절이 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -9685,7 +9685,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['extends' clause of exported interface '{0}' has or is using private name '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[내보낸 인터페이스 '{0}'의 Extends 절이 전용 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
<Val><![CDATA[내보낸 인터페이스 '{0}'의 Extends 절이 프라이빗 이름 '{1}'을(를) 가지고 있거나 사용 중입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -1003,6 +1003,12 @@ namespace ts.server {
|
||||
fileOrDirectory => {
|
||||
const fileOrDirectoryPath = this.toPath(fileOrDirectory);
|
||||
project.getCachedDirectoryStructureHost().addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
|
||||
|
||||
// don't trigger callback on open, existing files
|
||||
if (project.fileIsOpen(fileOrDirectoryPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isPathIgnored(fileOrDirectoryPath)) return;
|
||||
const configFilename = project.getConfigFilePath();
|
||||
|
||||
|
||||
+12
-7
@@ -198,13 +198,13 @@ namespace ts.server {
|
||||
return hasOneOrMoreJsAndNoTsFiles(this);
|
||||
}
|
||||
|
||||
public static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {} | undefined {
|
||||
public static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void, logErrors?: (message: string) => void): {} | undefined {
|
||||
const resolvedPath = normalizeSlashes(host.resolvePath(combinePaths(initialDir, "node_modules")));
|
||||
log(`Loading ${moduleName} from ${initialDir} (resolved to ${resolvedPath})`);
|
||||
const result = host.require!(resolvedPath, moduleName); // TODO: GH#18217
|
||||
if (result.error) {
|
||||
const err = result.error.stack || result.error.message || JSON.stringify(result.error);
|
||||
log(`Failed to load module '${moduleName}': ${err}`);
|
||||
(logErrors || log)(`Failed to load module '${moduleName}' from ${resolvedPath}: ${err}`);
|
||||
return undefined;
|
||||
}
|
||||
return result.module;
|
||||
@@ -457,6 +457,11 @@ namespace ts.server {
|
||||
return this.getTypeAcquisition().enable ? this.projectService.typingsInstaller.globalTypingsCacheLocation : undefined;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
fileIsOpen(filePath: Path) {
|
||||
return this.projectService.openFiles.has(filePath);
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
writeLog(s: string) {
|
||||
this.projectService.logger.info(s);
|
||||
@@ -1142,12 +1147,11 @@ namespace ts.server {
|
||||
protected enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[], pluginConfigOverrides: Map<any> | undefined) {
|
||||
this.projectService.logger.info(`Enabling plugin ${pluginConfigEntry.name} from candidate paths: ${searchPaths.join(",")}`);
|
||||
|
||||
const log = (message: string) => {
|
||||
this.projectService.logger.info(message);
|
||||
};
|
||||
|
||||
const log = (message: string) => this.projectService.logger.info(message);
|
||||
let errorLogs: string[] | undefined;
|
||||
const logError = (message: string) => { (errorLogs || (errorLogs = [])).push(message); };
|
||||
const resolvedModule = firstDefined(searchPaths, searchPath =>
|
||||
<PluginModuleFactory | undefined>Project.resolveModule(pluginConfigEntry.name, searchPath, this.projectService.host, log));
|
||||
<PluginModuleFactory | undefined>Project.resolveModule(pluginConfigEntry.name, searchPath, this.projectService.host, log, logError));
|
||||
if (resolvedModule) {
|
||||
const configurationOverride = pluginConfigOverrides && pluginConfigOverrides.get(pluginConfigEntry.name);
|
||||
if (configurationOverride) {
|
||||
@@ -1160,6 +1164,7 @@ namespace ts.server {
|
||||
this.enableProxy(resolvedModule, pluginConfigEntry);
|
||||
}
|
||||
else {
|
||||
forEach(errorLogs, log);
|
||||
this.projectService.logger.info(`Couldn't find ${pluginConfigEntry.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,9 @@ namespace ts.Completions {
|
||||
const compilerOptions = program.getCompilerOptions();
|
||||
|
||||
const contextToken = findPrecedingToken(position, sourceFile);
|
||||
if (triggerCharacter && !isValidTrigger(sourceFile, triggerCharacter, contextToken, position)) return undefined;
|
||||
if (triggerCharacter && !isInString(sourceFile, position, contextToken) && !isValidTrigger(sourceFile, triggerCharacter, contextToken, position)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const stringCompletions = StringCompletions.getStringLiteralCompletions(sourceFile, position, contextToken, typeChecker, compilerOptions, host, log, preferences);
|
||||
if (stringCompletions) {
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace ts.OrganizeImports {
|
||||
const usedImports: ImportDeclaration[] = [];
|
||||
|
||||
for (const importDecl of oldImports) {
|
||||
const {importClause} = importDecl;
|
||||
const { importClause, moduleSpecifier } = importDecl;
|
||||
|
||||
if (!importClause) {
|
||||
// Imports without import clauses are assumed to be included for their side effects and are not removed.
|
||||
@@ -125,6 +125,23 @@ namespace ts.OrganizeImports {
|
||||
if (name || namedBindings) {
|
||||
usedImports.push(updateImportDeclarationAndClause(importDecl, name, namedBindings));
|
||||
}
|
||||
// If a module is imported to be augmented, it’s used
|
||||
else if (hasModuleDeclarationMatchingSpecifier(sourceFile, moduleSpecifier)) {
|
||||
// If we’re in a declaration file, it’s safe to remove the import clause from it
|
||||
if (sourceFile.isDeclarationFile) {
|
||||
usedImports.push(createImportDeclaration(
|
||||
importDecl.decorators,
|
||||
importDecl.modifiers,
|
||||
/*importClause*/ undefined,
|
||||
moduleSpecifier));
|
||||
}
|
||||
// If we’re not in a declaration file, we can’t remove the import clause even though
|
||||
// the imported symbols are unused, because removing them makes it look like the import
|
||||
// declaration has side effects, which will cause it to be preserved in the JS emit.
|
||||
else {
|
||||
usedImports.push(importDecl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return usedImports;
|
||||
@@ -135,6 +152,13 @@ namespace ts.OrganizeImports {
|
||||
}
|
||||
}
|
||||
|
||||
function hasModuleDeclarationMatchingSpecifier(sourceFile: SourceFile, moduleSpecifier: Expression) {
|
||||
const moduleSpecifierText = isStringLiteral(moduleSpecifier) && moduleSpecifier.text;
|
||||
return isString(moduleSpecifierText) && some(sourceFile.moduleAugmentations, moduleName =>
|
||||
isStringLiteral(moduleName)
|
||||
&& moduleName.text === moduleSpecifierText);
|
||||
}
|
||||
|
||||
function getExternalModuleName(specifier: Expression) {
|
||||
return specifier !== undefined && isStringLiteralLike(specifier)
|
||||
? specifier.text
|
||||
|
||||
@@ -133,11 +133,21 @@ namespace ts.SignatureHelp {
|
||||
}
|
||||
|
||||
function containsPrecedingToken(startingToken: Node, sourceFile: SourceFile, container: Node) {
|
||||
const precedingToken = Debug.assertDefined(
|
||||
findPrecedingToken(startingToken.getFullStart(), sourceFile, startingToken.parent, /*excludeJsdoc*/ true)
|
||||
);
|
||||
|
||||
return rangeContainsRange(container, precedingToken);
|
||||
const pos = startingToken.getFullStart();
|
||||
// There’s a possibility that `startingToken.parent` contains only `startingToken` and
|
||||
// missing nodes, none of which are valid to be returned by `findPrecedingToken`. In that
|
||||
// case, the preceding token we want is actually higher up the tree—almost definitely the
|
||||
// next parent, but theoretically the situation with missing nodes might be happening on
|
||||
// multiple nested levels.
|
||||
let currentParent: Node | undefined = startingToken.parent;
|
||||
while (currentParent) {
|
||||
const precedingToken = findPrecedingToken(pos, sourceFile, currentParent, /*excludeJsdoc*/ true);
|
||||
if (precedingToken) {
|
||||
return rangeContainsRange(container, precedingToken);
|
||||
}
|
||||
currentParent = currentParent.parent;
|
||||
}
|
||||
return Debug.fail("Could not find preceding token");
|
||||
}
|
||||
|
||||
export interface ArgumentInfoForCompletions {
|
||||
|
||||
@@ -325,7 +325,7 @@ namespace ts {
|
||||
};
|
||||
testProjectReferences(spec, "/alpha/tsconfig.json", (program, host) => {
|
||||
program.emit();
|
||||
assert.deepEqual(host.outputs.map(e => e.file).sort(), ["/alpha/bin/src/a.d.ts", "/alpha/bin/src/a.js"]);
|
||||
assert.deepEqual(host.outputs.map(e => e.file).sort(), ["/alpha/bin/src/a.d.ts", "/alpha/bin/src/a.js", "/alpha/bin/tsconfig.tsbuildinfo"]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
namespace ts {
|
||||
describe("unittests:: services:: Organize imports", () => {
|
||||
describe("unittests:: services:: organizeImports", () => {
|
||||
describe("Sort imports", () => {
|
||||
it("Sort - non-relative vs non-relative", () => {
|
||||
assertSortsBefore(
|
||||
@@ -343,6 +343,36 @@ import { } from "lib";
|
||||
},
|
||||
libFile);
|
||||
|
||||
testOrganizeImports("Unused_false_positive_module_augmentation",
|
||||
{
|
||||
path: "/test.d.ts",
|
||||
content: `
|
||||
import foo from 'foo';
|
||||
import { Caseless } from 'caseless';
|
||||
|
||||
declare module 'foo' {}
|
||||
declare module 'caseless' {
|
||||
interface Caseless {
|
||||
test(name: KeyType): boolean;
|
||||
}
|
||||
}`
|
||||
});
|
||||
|
||||
testOrganizeImports("Unused_preserve_imports_for_module_augmentation_in_non_declaration_file",
|
||||
{
|
||||
path: "/test.ts",
|
||||
content: `
|
||||
import foo from 'foo';
|
||||
import { Caseless } from 'caseless';
|
||||
|
||||
declare module 'foo' {}
|
||||
declare module 'caseless' {
|
||||
interface Caseless {
|
||||
test(name: KeyType): boolean;
|
||||
}
|
||||
}`
|
||||
});
|
||||
|
||||
testOrganizeImports("Unused_false_positive_shorthand_assignment",
|
||||
{
|
||||
path: "/test.ts",
|
||||
|
||||
@@ -14,13 +14,11 @@ namespace ts {
|
||||
const builder = createSolutionBuilder(host, ["/src/no-references"], { dry: false, force: false, verbose: false });
|
||||
|
||||
host.clearDiagnostics();
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
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) {
|
||||
assert(!fs.existsSync(output), `Expect file ${output} to not exist`);
|
||||
}
|
||||
verifyOutputsAbsent(fs, allExpectedOutputs);
|
||||
});
|
||||
|
||||
it("does not have empty files diagnostic when files is empty and references are provided", () => {
|
||||
@@ -29,13 +27,11 @@ namespace ts {
|
||||
const builder = createSolutionBuilder(host, ["/src/with-references"], { dry: false, force: false, verbose: false });
|
||||
|
||||
host.clearDiagnostics();
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
|
||||
// Check for outputs to be written.
|
||||
for (const output of allExpectedOutputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
verifyOutputsPresent(fs, allExpectedOutputs);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,34 +22,32 @@ namespace ts {
|
||||
});
|
||||
|
||||
it("orders the graph correctly - specify two roots", () => {
|
||||
checkGraphOrdering(["A", "G"], ["A", "B", "C", "D", "E", "G"]);
|
||||
checkGraphOrdering(["A", "G"], ["D", "E", "C", "B", "A", "G"]);
|
||||
});
|
||||
|
||||
it("orders the graph correctly - multiple parts of the same graph in various orders", () => {
|
||||
checkGraphOrdering(["A"], ["A", "B", "C", "D", "E"]);
|
||||
checkGraphOrdering(["A", "C", "D"], ["A", "B", "C", "D", "E"]);
|
||||
checkGraphOrdering(["D", "C", "A"], ["A", "B", "C", "D", "E"]);
|
||||
checkGraphOrdering(["A"], ["D", "E", "C", "B", "A"]);
|
||||
checkGraphOrdering(["A", "C", "D"], ["D", "E", "C", "B", "A"]);
|
||||
checkGraphOrdering(["D", "C", "A"], ["D", "E", "C", "B", "A"]);
|
||||
});
|
||||
|
||||
it("orders the graph correctly - other orderings", () => {
|
||||
checkGraphOrdering(["F"], ["F", "E"]);
|
||||
checkGraphOrdering(["F"], ["E", "F"]);
|
||||
checkGraphOrdering(["E"], ["E"]);
|
||||
checkGraphOrdering(["F", "C", "A"], ["A", "B", "C", "D", "E", "F"]);
|
||||
checkGraphOrdering(["F", "C", "A"], ["E", "F", "D", "C", "B", "A"]);
|
||||
});
|
||||
|
||||
function checkGraphOrdering(rootNames: string[], expectedBuildSet: string[]) {
|
||||
const builder = createSolutionBuilder(host!, rootNames, { dry: true, force: false, verbose: false });
|
||||
const builder = createSolutionBuilder(host!, rootNames.map(getProjectFileName), { dry: true, force: false, verbose: false });
|
||||
const buildQueue = builder.getBuildOrder();
|
||||
|
||||
const projFileNames = rootNames.map(getProjectFileName);
|
||||
const graph = builder.getBuildGraph(projFileNames);
|
||||
|
||||
assert.sameMembers(graph.buildQueue, expectedBuildSet.map(getProjectFileName));
|
||||
assert.deepEqual(buildQueue, expectedBuildSet.map(getProjectFileName));
|
||||
|
||||
for (const dep of deps) {
|
||||
const child = getProjectFileName(dep[0]);
|
||||
if (graph.buildQueue.indexOf(child) < 0) continue;
|
||||
if (buildQueue.indexOf(child) < 0) continue;
|
||||
const parent = getProjectFileName(dep[1]);
|
||||
assert.isAbove(graph.buildQueue.indexOf(child), graph.buildQueue.indexOf(parent), `Expecting child ${child} to be built after parent ${parent}`);
|
||||
assert.isAbove(buildQueue.indexOf(child), buildQueue.indexOf(parent), `Expecting child ${child} to be built after parent ${parent}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,6 +82,18 @@ declare const console: { log(msg: any): void; };`;
|
||||
return fs;
|
||||
}
|
||||
|
||||
export function verifyOutputsPresent(fs: vfs.FileSystem, outputs: readonly string[]) {
|
||||
for (const output of outputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
}
|
||||
|
||||
export function verifyOutputsAbsent(fs: vfs.FileSystem, outputs: readonly string[]) {
|
||||
for (const output of outputs) {
|
||||
assert.isFalse(fs.existsSync(output), `Expect file ${output} to not exist`);
|
||||
}
|
||||
}
|
||||
|
||||
function generateSourceMapBaselineFiles(fs: vfs.FileSystem, mapFileNames: ReadonlyArray<string>) {
|
||||
for (const mapFile of mapFileNames) {
|
||||
if (!fs.existsSync(mapFile)) continue;
|
||||
@@ -172,7 +184,7 @@ declare const console: { log(msg: any): void; };`;
|
||||
}
|
||||
return originalReadFile.call(host, path);
|
||||
};
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
generateSourceMapBaselineFiles(fs, expectedMapFileNames);
|
||||
generateBuildInfoSectionBaselineFiles(fs, expectedBuildInfoFilesForSectionBaselines || emptyArray);
|
||||
fs.makeReadonly();
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace ts {
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tsconfig.json"], {});
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
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", "[\"**/*\"]", "[]"],
|
||||
|
||||
@@ -363,21 +363,17 @@ namespace ts {
|
||||
];
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host);
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(...initialExpectedDiagnostics);
|
||||
// Verify they exist
|
||||
for (const output of expectedOutputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
verifyOutputsPresent(fs, expectedOutputs);
|
||||
host.clearDiagnostics();
|
||||
builder.cleanAllProjects();
|
||||
builder.clean();
|
||||
host.assertDiagnosticMessages(/*none*/);
|
||||
// Verify they are gone
|
||||
for (const output of expectedOutputs) {
|
||||
assert(!fs.existsSync(output), `Expect file ${output} to not exist`);
|
||||
}
|
||||
verifyOutputsAbsent(fs, expectedOutputs);
|
||||
// Subsequent clean shouldn't throw / etc
|
||||
builder.cleanAllProjects();
|
||||
builder.clean();
|
||||
});
|
||||
|
||||
it("verify buildInfo absence results in new build", () => {
|
||||
@@ -388,18 +384,16 @@ namespace ts {
|
||||
...outputFiles[project.third]
|
||||
];
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host);
|
||||
builder.buildAllProjects();
|
||||
let builder = createSolutionBuilder(host);
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(...initialExpectedDiagnostics);
|
||||
// Verify they exist
|
||||
for (const output of expectedOutputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
verifyOutputsPresent(fs, expectedOutputs);
|
||||
// Delete bundle info
|
||||
host.clearDiagnostics();
|
||||
host.deleteFile(outputFiles[project.first][ext.buildinfo]);
|
||||
builder.resetBuildContext();
|
||||
builder.buildAllProjects();
|
||||
builder = createSolutionBuilder(host);
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild(relSources[project.first][source.config], relSources[project.second][source.config], relSources[project.third][source.config]),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, relSources[project.first][source.config], relOutputFiles[project.first][ext.buildinfo]],
|
||||
@@ -416,25 +410,23 @@ namespace ts {
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
replaceText(fs, sources[project.third][source.config], `"composite": true,`, "");
|
||||
const builder = createSolutionBuilder(host);
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(...initialExpectedDiagnostics);
|
||||
// Verify they exist - without tsbuildinfo for third project
|
||||
for (const output of expectedOutputFiles.slice(0, expectedOutputFiles.length - 2)) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
assert.isFalse(fs.existsSync(outputFiles[project.third][ext.buildinfo]), `Expect file ${outputFiles[project.third][ext.buildinfo]} to not exist`);
|
||||
verifyOutputsPresent(fs, expectedOutputFiles.slice(0, expectedOutputFiles.length - 2));
|
||||
verifyOutputsAbsent(fs, [outputFiles[project.third][ext.buildinfo]]);
|
||||
});
|
||||
|
||||
it("rebuilds completely when version in tsbuildinfo doesnt match ts version", () => {
|
||||
const fs = outFileFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host);
|
||||
builder.buildAllProjects();
|
||||
let builder = createSolutionBuilder(host);
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(...initialExpectedDiagnostics);
|
||||
host.clearDiagnostics();
|
||||
builder.resetBuildContext();
|
||||
builder = createSolutionBuilder(host);
|
||||
changeCompilerVersion(host);
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild(relSources[project.first][source.config], relSources[project.second][source.config], relSources[project.third][source.config]),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2, relSources[project.first][source.config], fakes.version, version],
|
||||
@@ -453,16 +445,16 @@ namespace ts {
|
||||
|
||||
// Build with command line incremental
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, { incremental: true });
|
||||
builder.buildAllProjects();
|
||||
let builder = createSolutionBuilder(host, { incremental: true });
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(...initialExpectedDiagnostics);
|
||||
host.clearDiagnostics();
|
||||
tick();
|
||||
|
||||
// Make non incremental build with change in file that doesnt affect dts
|
||||
appendText(fs, relSources[project.first][source.ts][part.one], "console.log(s);");
|
||||
builder.resetBuildContext({ verbose: true });
|
||||
builder.buildAllProjects();
|
||||
builder = createSolutionBuilder(host, { verbose: true });
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(getExpectedDiagnosticForProjectsInBuild(relSources[project.first][source.config], relSources[project.second][source.config], relSources[project.third][source.config]),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, relSources[project.first][source.config], relOutputFiles[project.first][ext.js], relSources[project.first][source.ts][part.one]],
|
||||
[Diagnostics.Building_project_0, sources[project.first][source.config]],
|
||||
@@ -475,8 +467,8 @@ namespace ts {
|
||||
|
||||
// Make incremental build with change in file that doesnt affect dts
|
||||
appendText(fs, relSources[project.first][source.ts][part.one], "console.log(s);");
|
||||
builder.resetBuildContext({ verbose: true, incremental: true });
|
||||
builder.buildAllProjects();
|
||||
builder = createSolutionBuilder(host, { verbose: true, incremental: true });
|
||||
builder.build();
|
||||
// Builds completely because tsbuildinfo is old.
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild(relSources[project.first][source.config], relSources[project.second][source.config], relSources[project.third][source.config]),
|
||||
@@ -489,6 +481,33 @@ namespace ts {
|
||||
host.clearDiagnostics();
|
||||
});
|
||||
|
||||
it("builds till project specified", () => {
|
||||
const fs = outFileFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, { verbose: false });
|
||||
const result = builder.build(sources[project.second][source.config]);
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
// First and Third is not built
|
||||
verifyOutputsAbsent(fs, [...outputFiles[project.first], ...outputFiles[project.third]]);
|
||||
// second is built
|
||||
verifyOutputsPresent(fs, outputFiles[project.second]);
|
||||
assert.equal(result, ExitStatus.Success);
|
||||
});
|
||||
|
||||
it("cleans till project specified", () => {
|
||||
const fs = outFileFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, { verbose: false });
|
||||
builder.build();
|
||||
const result = builder.clean(sources[project.second][source.config]);
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
// First and Third output for present
|
||||
verifyOutputsPresent(fs, [...outputFiles[project.first], ...outputFiles[project.third]]);
|
||||
// second is cleaned
|
||||
verifyOutputsAbsent(fs, outputFiles[project.second]);
|
||||
assert.equal(result, ExitStatus.Success);
|
||||
});
|
||||
|
||||
describe("Prepend output with .tsbuildinfo", () => {
|
||||
// Prologues
|
||||
describe("Prologues", () => {
|
||||
@@ -904,7 +923,7 @@ ${internal} enum internalEnum { a, b, c }`);
|
||||
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host);
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild(relSources[project.first][source.config], relSources[project.second][source.config], relSources[project.third][source.config]),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, relSources[project.first][source.config], "src/first/first_PART1.js"],
|
||||
@@ -923,9 +942,7 @@ ${internal} enum internalEnum { a, b, c }`);
|
||||
removeFileExtension(f) + Extension.Dts + ".map",
|
||||
])
|
||||
]);
|
||||
for (const output of expectedOutputFiles) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
verifyOutputsPresent(fs, expectedOutputFiles);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,11 +19,9 @@ namespace ts {
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/src/main", "/src/src/other"], {});
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
for (const output of allExpectedOutputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
verifyOutputsPresent(fs, allExpectedOutputs);
|
||||
});
|
||||
|
||||
it("verify that it reports error for same .tsbuildinfo file because no rootDir in the base", () => {
|
||||
@@ -39,7 +37,7 @@ namespace ts {
|
||||
replaceText(fs, "/src/tsconfig.base.json", `"rootDir": "./src/",`, "");
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/src/main"], { verbose: true });
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild("src/src/other/tsconfig.json", "src/src/main/tsconfig.json"),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/src/other/tsconfig.json", "src/dist/other.js"],
|
||||
@@ -48,12 +46,8 @@ namespace ts {
|
||||
[Diagnostics.Building_project_0, "/src/src/main/tsconfig.json"],
|
||||
[Diagnostics.Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1, "/src/dist/tsconfig.tsbuildinfo", "/src/src/other"]
|
||||
);
|
||||
for (const output of allExpectedOutputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
for (const output of missingOutputs) {
|
||||
assert.isFalse(fs.existsSync(output), `Expect file ${output} to not exist`);
|
||||
}
|
||||
verifyOutputsPresent(fs, allExpectedOutputs);
|
||||
verifyOutputsAbsent(fs, missingOutputs);
|
||||
});
|
||||
|
||||
it("verify that it reports error for same .tsbuildinfo file", () => {
|
||||
@@ -75,7 +69,7 @@ namespace ts {
|
||||
}));
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/src/main"], { verbose: true });
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild("src/src/other/tsconfig.json", "src/src/main/tsconfig.json"),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/src/other/tsconfig.json", "src/dist/other.js"],
|
||||
@@ -84,12 +78,8 @@ namespace ts {
|
||||
[Diagnostics.Building_project_0, "/src/src/main/tsconfig.json"],
|
||||
[Diagnostics.Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1, "/src/dist/tsconfig.tsbuildinfo", "/src/src/other"]
|
||||
);
|
||||
for (const output of allExpectedOutputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
for (const output of missingOutputs) {
|
||||
assert.isFalse(fs.existsSync(output), `Expect file ${output} to not exist`);
|
||||
}
|
||||
verifyOutputsPresent(fs, allExpectedOutputs);
|
||||
verifyOutputsAbsent(fs, missingOutputs);
|
||||
});
|
||||
|
||||
it("verify that it reports no error when .tsbuildinfo differ", () => {
|
||||
@@ -112,7 +102,7 @@ namespace ts {
|
||||
}));
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/src/main/tsconfig.main.json"], { verbose: true });
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild("src/src/other/tsconfig.other.json", "src/src/main/tsconfig.main.json"),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/src/other/tsconfig.other.json", "src/dist/other.js"],
|
||||
@@ -120,9 +110,7 @@ namespace ts {
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/src/main/tsconfig.main.json", "src/dist/a.js"],
|
||||
[Diagnostics.Building_project_0, "/src/src/main/tsconfig.main.json"]
|
||||
);
|
||||
for (const output of allExpectedOutputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
verifyOutputsPresent(fs, allExpectedOutputs);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,13 +19,11 @@ namespace ts {
|
||||
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();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(...expectedDiagnosticMessages);
|
||||
if (!expectedDiagnosticMessages.length) {
|
||||
// Check for outputs. Not an exhaustive list
|
||||
for (const output of allExpectedOutputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
verifyOutputsPresent(fs, allExpectedOutputs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,20 +62,18 @@ export default hello.hello`);
|
||||
const configFile = "src/tsconfig_withFiles.json";
|
||||
replaceText(fs, configFile, `"composite": true,`, `"composite": true, "sourceMap": true,`);
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, [configFile], { verbose: true });
|
||||
builder.buildAllProjects();
|
||||
let builder = createSolutionBuilder(host, [configFile], { verbose: true });
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild(configFile),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, configFile, "src/dist/src/index.js"],
|
||||
[Diagnostics.Building_project_0, `/${configFile}`]
|
||||
);
|
||||
for (const output of [...allExpectedOutputs, "/src/dist/src/index.js.map"]) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
verifyOutputsPresent(fs, [...allExpectedOutputs, "/src/dist/src/index.js.map"]);
|
||||
host.clearDiagnostics();
|
||||
builder.resetBuildContext();
|
||||
builder = createSolutionBuilder(host, [configFile], { verbose: true });
|
||||
tick();
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild(configFile),
|
||||
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, configFile, "src/src/index.ts", "src/dist/src/index.js"]
|
||||
@@ -89,20 +85,18 @@ export default hello.hello`);
|
||||
const configFile = "src/tsconfig_withFiles.json";
|
||||
replaceText(fs, configFile, `"outDir": "dist",`, "");
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, [configFile], { verbose: true });
|
||||
builder.buildAllProjects();
|
||||
let builder = createSolutionBuilder(host, [configFile], { verbose: true });
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild(configFile),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, configFile, "src/src/index.js"],
|
||||
[Diagnostics.Building_project_0, `/${configFile}`]
|
||||
);
|
||||
for (const output of ["/src/src/index.js", "/src/src/index.d.ts"]) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
verifyOutputsPresent(fs, ["/src/src/index.js", "/src/src/index.d.ts"]);
|
||||
host.clearDiagnostics();
|
||||
builder.resetBuildContext();
|
||||
builder = createSolutionBuilder(host, [configFile], { verbose: true });
|
||||
tick();
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild(configFile),
|
||||
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, configFile, "src/src/index.ts", "src/src/index.js"]
|
||||
@@ -128,8 +122,8 @@ export default hello.hello`);
|
||||
const stringsConfigFile = "src/strings/tsconfig.json";
|
||||
const mainConfigFile = "src/main/tsconfig.json";
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, [configFile], { verbose: true });
|
||||
builder.buildAllProjects();
|
||||
let builder = createSolutionBuilder(host, [configFile], { verbose: true });
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild(stringsConfigFile, mainConfigFile, configFile),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, stringsConfigFile, "src/strings/tsconfig.tsbuildinfo"],
|
||||
@@ -137,11 +131,11 @@ export default hello.hello`);
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, mainConfigFile, "src/main/index.js"],
|
||||
[Diagnostics.Building_project_0, `/${mainConfigFile}`],
|
||||
);
|
||||
assert(fs.existsSync(expectedOutput), `Expect file ${expectedOutput} to exist`);
|
||||
verifyOutputsPresent(fs, [expectedOutput]);
|
||||
host.clearDiagnostics();
|
||||
builder.resetBuildContext();
|
||||
builder = createSolutionBuilder(host, [configFile], { verbose: true });
|
||||
tick();
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild(stringsConfigFile, mainConfigFile, configFile),
|
||||
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, stringsConfigFile, "src/strings/foo.json", "src/strings/tsconfig.tsbuildinfo"],
|
||||
|
||||
@@ -2,9 +2,10 @@ namespace ts {
|
||||
describe("unittests:: tsbuild:: on 'sample1' project", () => {
|
||||
let projFs: vfs.FileSystem;
|
||||
const { time, tick } = getTime();
|
||||
const allExpectedOutputs = ["/src/tests/index.js",
|
||||
"/src/core/index.js", "/src/core/index.d.ts", "/src/core/index.d.ts.map",
|
||||
"/src/logic/index.js", "/src/logic/index.js.map", "/src/logic/index.d.ts"];
|
||||
const testsOutputs = ["/src/tests/index.js", "/src/tests/index.d.ts", "/src/tests/tsconfig.tsbuildinfo"];
|
||||
const logicOutputs = ["/src/logic/index.js", "/src/logic/index.js.map", "/src/logic/index.d.ts", "/src/logic/tsconfig.tsbuildinfo"];
|
||||
const coreOutputs = ["/src/core/index.js", "/src/core/index.d.ts", "/src/core/index.d.ts.map", "/src/core/tsconfig.tsbuildinfo"];
|
||||
const allExpectedOutputs = [...testsOutputs, ...logicOutputs, ...coreOutputs];
|
||||
|
||||
before(() => {
|
||||
projFs = loadProjectFromDisk("tests/projects/sample1", time);
|
||||
@@ -21,13 +22,11 @@ namespace ts {
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: false, verbose: false });
|
||||
|
||||
host.clearDiagnostics();
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
|
||||
// Check for outputs. Not an exhaustive list
|
||||
for (const output of allExpectedOutputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
verifyOutputsPresent(fs, allExpectedOutputs);
|
||||
});
|
||||
|
||||
it("builds correctly when outDir is specified", () => {
|
||||
@@ -39,13 +38,11 @@ namespace ts {
|
||||
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], {});
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
const expectedOutputs = allExpectedOutputs.map(f => f.replace("/logic/", "/logic/outDir/"));
|
||||
// Check for outputs. Not an exhaustive list
|
||||
for (const output of expectedOutputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
verifyOutputsPresent(fs, expectedOutputs);
|
||||
});
|
||||
|
||||
it("builds correctly when declarationDir is specified", () => {
|
||||
@@ -57,13 +54,11 @@ namespace ts {
|
||||
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], {});
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
const expectedOutputs = allExpectedOutputs.map(f => f.replace("/logic/index.d.ts", "/logic/out/decls/index.d.ts"));
|
||||
// Check for outputs. Not an exhaustive list
|
||||
for (const output of expectedOutputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
verifyOutputsPresent(fs, expectedOutputs);
|
||||
});
|
||||
|
||||
it("builds correctly when project is not composite or doesnt have any references", () => {
|
||||
@@ -71,15 +66,13 @@ namespace ts {
|
||||
replaceText(fs, "/src/core/tsconfig.json", `"composite": true,`, "");
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/core"], { verbose: true });
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild("src/core/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"]
|
||||
);
|
||||
for (const output of ["/src/core/index.js", "/src/core/index.d.ts", "/src/core/index.d.ts.map"]) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
verifyOutputsPresent(fs, ["/src/core/index.js", "/src/core/index.d.ts", "/src/core/index.d.ts.map"]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -88,7 +81,7 @@ namespace ts {
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], { dry: true, force: false, verbose: false });
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
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"],
|
||||
@@ -96,9 +89,7 @@ namespace ts {
|
||||
);
|
||||
|
||||
// Check for outputs to not be written. Not an exhaustive list
|
||||
for (const output of allExpectedOutputs) {
|
||||
assert(!fs.existsSync(output), `Expect file ${output} to not exist`);
|
||||
}
|
||||
verifyOutputsAbsent(fs, allExpectedOutputs);
|
||||
});
|
||||
|
||||
it("indicates that it would skip builds during a dry build", () => {
|
||||
@@ -106,12 +97,12 @@ namespace ts {
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
|
||||
let builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: false, verbose: false });
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
tick();
|
||||
|
||||
host.clearDiagnostics();
|
||||
builder = createSolutionBuilder(host, ["/src/tests"], { dry: true, force: false, verbose: false });
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(
|
||||
[Diagnostics.Project_0_is_up_to_date, "/src/core/tsconfig.json"],
|
||||
[Diagnostics.Project_0_is_up_to_date, "/src/logic/tsconfig.json"],
|
||||
@@ -126,18 +117,44 @@ namespace ts {
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: false, verbose: false });
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
// Verify they exist
|
||||
for (const output of allExpectedOutputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
builder.cleanAllProjects();
|
||||
verifyOutputsPresent(fs, allExpectedOutputs);
|
||||
|
||||
builder.clean();
|
||||
// Verify they are gone
|
||||
for (const output of allExpectedOutputs) {
|
||||
assert(!fs.existsSync(output), `Expect file ${output} to not exist`);
|
||||
}
|
||||
verifyOutputsAbsent(fs, allExpectedOutputs);
|
||||
|
||||
// Subsequent clean shouldn't throw / etc
|
||||
builder.cleanAllProjects();
|
||||
builder.clean();
|
||||
verifyOutputsAbsent(fs, allExpectedOutputs);
|
||||
|
||||
builder.build();
|
||||
// Verify they exist
|
||||
verifyOutputsPresent(fs, allExpectedOutputs);
|
||||
});
|
||||
|
||||
it("cleans till project specified", () => {
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], {});
|
||||
builder.build();
|
||||
const result = builder.clean("/src/logic");
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
verifyOutputsPresent(fs, testsOutputs);
|
||||
verifyOutputsAbsent(fs, [...logicOutputs, ...coreOutputs]);
|
||||
assert.equal(result, ExitStatus.Success);
|
||||
});
|
||||
|
||||
it("cleaning project in not build order doesnt throw error", () => {
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], {});
|
||||
builder.build();
|
||||
const result = builder.clean("/src/logic2");
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
verifyOutputsPresent(fs, allExpectedOutputs);
|
||||
assert.equal(result, ExitStatus.InvalidProject_OutputsSkipped);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -146,15 +163,16 @@ namespace ts {
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: true, verbose: false });
|
||||
builder.buildAllProjects();
|
||||
let builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: true, verbose: false });
|
||||
builder.build();
|
||||
let currentTime = time();
|
||||
checkOutputTimestamps(currentTime);
|
||||
|
||||
tick();
|
||||
Debug.assert(time() !== currentTime, "Time moves on");
|
||||
currentTime = time();
|
||||
builder.buildAllProjects();
|
||||
builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: true, verbose: false });
|
||||
builder.build();
|
||||
checkOutputTimestamps(currentTime);
|
||||
|
||||
function checkOutputTimestamps(expected: number) {
|
||||
@@ -171,11 +189,11 @@ namespace ts {
|
||||
function initializeWithBuild(opts?: BuildOptions) {
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true });
|
||||
builder.buildAllProjects();
|
||||
let builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true });
|
||||
builder.build();
|
||||
host.clearDiagnostics();
|
||||
tick();
|
||||
builder.resetBuildContext(opts ? { ...opts, verbose: true } : undefined);
|
||||
builder = createSolutionBuilder(host, ["/src/tests"], { ...(opts || {}), verbose: true });
|
||||
return { fs, host, builder };
|
||||
}
|
||||
|
||||
@@ -183,8 +201,7 @@ namespace ts {
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true });
|
||||
builder.resetBuildContext();
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
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"],
|
||||
@@ -199,7 +216,7 @@ namespace ts {
|
||||
// All three projects are up to date
|
||||
it("Detects that all projects are up to date", () => {
|
||||
const { host, builder } = initializeWithBuild();
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
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"],
|
||||
@@ -212,7 +229,7 @@ namespace ts {
|
||||
it("Only builds the leaf node project", () => {
|
||||
const { fs, host, builder } = initializeWithBuild();
|
||||
fs.writeFileSync("/src/tests/index.ts", "const m = 10;");
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
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"],
|
||||
@@ -226,7 +243,7 @@ namespace ts {
|
||||
it("Detects type-only changes in upstream projects", () => {
|
||||
const { fs, host, builder } = initializeWithBuild();
|
||||
replaceText(fs, "/src/core/index.ts", "HELLO WORLD", "WELCOME PLANET");
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"),
|
||||
@@ -243,7 +260,7 @@ namespace ts {
|
||||
it("rebuilds completely when version in tsbuildinfo doesnt match ts version", () => {
|
||||
const { host, builder } = initializeWithBuild();
|
||||
changeCompilerVersion(host);
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"),
|
||||
[Diagnostics.Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2, "src/core/tsconfig.json", fakes.version, version],
|
||||
@@ -255,9 +272,38 @@ namespace ts {
|
||||
);
|
||||
});
|
||||
|
||||
it("does not rebuild if there is no program and bundle in the ts build info event if version doesnt match ts version", () => {
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs, /*options*/ undefined, /*setParentNodes*/ undefined, createAbstractBuilder);
|
||||
let builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true });
|
||||
builder.build();
|
||||
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"]
|
||||
);
|
||||
verifyOutputsPresent(fs, allExpectedOutputs);
|
||||
|
||||
host.clearDiagnostics();
|
||||
tick();
|
||||
builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true });
|
||||
changeCompilerVersion(host);
|
||||
builder.build();
|
||||
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"]
|
||||
);
|
||||
});
|
||||
|
||||
it("rebuilds from start if --f is passed", () => {
|
||||
const { host, builder } = initializeWithBuild({ force: true });
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
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"],
|
||||
@@ -272,7 +318,7 @@ namespace ts {
|
||||
it("rebuilds when tsconfig changes", () => {
|
||||
const { fs, host, builder } = initializeWithBuild();
|
||||
replaceText(fs, "/src/tests/tsconfig.json", `"composite": true`, `"composite": true, "target": "es3"`);
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
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"],
|
||||
@@ -287,8 +333,8 @@ namespace ts {
|
||||
fs.writeFileSync("/src/tests/tsconfig.base.json", JSON.stringify({ compilerOptions: { target: "es3" } }));
|
||||
replaceText(fs, "/src/tests/tsconfig.json", `"references": [`, `"extends": "./tsconfig.base.json", "references": [`);
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true });
|
||||
builder.buildAllProjects();
|
||||
let builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true });
|
||||
builder.build();
|
||||
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"],
|
||||
@@ -300,9 +346,9 @@ namespace ts {
|
||||
);
|
||||
host.clearDiagnostics();
|
||||
tick();
|
||||
builder.resetBuildContext();
|
||||
builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true });
|
||||
fs.writeFileSync("/src/tests/tsconfig.base.json", JSON.stringify({ compilerOptions: {} }));
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
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"],
|
||||
@@ -311,6 +357,82 @@ namespace ts {
|
||||
[Diagnostics.Building_project_0, "/src/tests/tsconfig.json"]
|
||||
);
|
||||
});
|
||||
|
||||
it("builds till project specified", () => {
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], {});
|
||||
const result = builder.build("/src/logic");
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
verifyOutputsAbsent(fs, testsOutputs);
|
||||
verifyOutputsPresent(fs, [...logicOutputs, ...coreOutputs]);
|
||||
assert.equal(result, ExitStatus.Success);
|
||||
});
|
||||
|
||||
it("building project in not build order doesnt throw error", () => {
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], {});
|
||||
const result = builder.build("/src/logic2");
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
verifyOutputsAbsent(fs, allExpectedOutputs);
|
||||
assert.equal(result, ExitStatus.InvalidProject_OutputsSkipped);
|
||||
});
|
||||
|
||||
it("building using getNextInvalidatedProject", () => {
|
||||
interface SolutionBuilderResult<T> {
|
||||
project: ResolvedConfigFileName;
|
||||
result: T;
|
||||
}
|
||||
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], {});
|
||||
verifyBuildNextResult({
|
||||
project: "/src/core/tsconfig.json" as ResolvedConfigFileName,
|
||||
result: ExitStatus.Success
|
||||
}, coreOutputs, [...logicOutputs, ...testsOutputs]);
|
||||
|
||||
verifyBuildNextResult({
|
||||
project: "/src/logic/tsconfig.json" as ResolvedConfigFileName,
|
||||
result: ExitStatus.Success
|
||||
}, [...coreOutputs, ...logicOutputs], testsOutputs);
|
||||
|
||||
verifyBuildNextResult({
|
||||
project: "/src/tests/tsconfig.json" as ResolvedConfigFileName,
|
||||
result: ExitStatus.Success
|
||||
}, allExpectedOutputs, emptyArray);
|
||||
|
||||
verifyBuildNextResult(/*expected*/ undefined, allExpectedOutputs, emptyArray);
|
||||
|
||||
function verifyBuildNextResult(
|
||||
expected: SolutionBuilderResult<ExitStatus> | undefined,
|
||||
presentOutputs: readonly string[],
|
||||
absentOutputs: readonly string[]
|
||||
) {
|
||||
const project = builder.getNextInvalidatedProject();
|
||||
const result = project && project.done();
|
||||
assert.deepEqual(project && { project: project.project, result }, expected);
|
||||
verifyOutputsPresent(fs, presentOutputs);
|
||||
verifyOutputsAbsent(fs, absentOutputs);
|
||||
}
|
||||
});
|
||||
|
||||
it("building using buildReferencedProject", () => {
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true });
|
||||
builder.buildReferences("/src/tests");
|
||||
host.assertDiagnosticMessages(
|
||||
getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/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"],
|
||||
);
|
||||
verifyOutputsPresent(fs, [...coreOutputs, ...logicOutputs]);
|
||||
verifyOutputsAbsent(fs, testsOutputs);
|
||||
});
|
||||
});
|
||||
|
||||
describe("downstream-blocked compilations", () => {
|
||||
@@ -321,7 +443,7 @@ namespace ts {
|
||||
|
||||
// Induce an error in the middle project
|
||||
replaceText(fs, "/src/logic/index.ts", "c.multiply(10, 15)", `c.muitply()`);
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
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"],
|
||||
@@ -341,7 +463,7 @@ namespace ts {
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: false, verbose: false });
|
||||
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
|
||||
// Update a timestamp in the middle project
|
||||
@@ -354,7 +476,7 @@ namespace ts {
|
||||
originalWriteFile.call(fs, path, data, encoding);
|
||||
};
|
||||
// Because we haven't reset the build context, the builder should assume there's nothing to do right now
|
||||
const status = builder.getUpToDateStatusOfFile(builder.resolveProjectName("/src/logic"));
|
||||
const status = builder.getUpToDateStatusOfProject("/src/logic");
|
||||
assert.equal(status.type, UpToDateStatusType.UpToDate, "Project should be assumed to be up-to-date");
|
||||
verifyInvalidation(/*expectedToWriteTests*/ false);
|
||||
|
||||
@@ -366,8 +488,8 @@ export class cNew {}`);
|
||||
function verifyInvalidation(expectedToWriteTests: boolean) {
|
||||
// Rebuild this project
|
||||
tick();
|
||||
builder.invalidateProject("/src/logic");
|
||||
builder.buildInvalidatedProject();
|
||||
builder.invalidateProject("/src/logic/tsconfig.json" as ResolvedConfigFilePath);
|
||||
builder.buildNextInvalidatedProject();
|
||||
// The file should be updated
|
||||
assert.isTrue(writtenFiles.has("/src/logic/index.js"), "JS file should have been rebuilt");
|
||||
assert.equal(fs.statSync("/src/logic/index.js").mtimeMs, time(), "JS file should have been rebuilt");
|
||||
@@ -377,7 +499,7 @@ export class cNew {}`);
|
||||
|
||||
// Build downstream projects should update 'tests', but not 'core'
|
||||
tick();
|
||||
builder.buildInvalidatedProject();
|
||||
builder.buildNextInvalidatedProject();
|
||||
if (expectedToWriteTests) {
|
||||
assert.isTrue(writtenFiles.has("/src/tests/index.js"), "Downstream JS file should have been rebuilt");
|
||||
}
|
||||
@@ -395,7 +517,7 @@ export class cNew {}`);
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], { listFiles: true });
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
assert.deepEqual(host.traces, [
|
||||
"/lib/lib.d.ts",
|
||||
"/src/core/anotherModule.ts",
|
||||
@@ -422,7 +544,7 @@ export class cNew {}`);
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], { listEmittedFiles: true });
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
assert.deepEqual(host.traces, [
|
||||
"TSFILE: /src/core/anotherModule.js",
|
||||
"TSFILE: /src/core/anotherModule.d.ts.map",
|
||||
|
||||
@@ -30,11 +30,9 @@ namespace ts {
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
modifyDiskLayout(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tsconfig.c.json"], { listFiles: true });
|
||||
builder.buildAllProjects();
|
||||
builder.build();
|
||||
host.assertDiagnosticMessages(...expectedDiagnostics);
|
||||
for (const output of allExpectedOutputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
verifyOutputsPresent(fs, allExpectedOutputs);
|
||||
assert.deepEqual(host.traces, expectedFileTraces);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,14 +17,14 @@ namespace ts.tscWatch {
|
||||
}
|
||||
|
||||
export function createSolutionBuilder(system: WatchedSystem, rootNames: ReadonlyArray<string>, defaultOptions?: BuildOptions) {
|
||||
const host = createSolutionBuilderWithWatchHost(system);
|
||||
return ts.createSolutionBuilder(host, rootNames, defaultOptions || { watch: true });
|
||||
const host = createSolutionBuilderHost(system);
|
||||
return ts.createSolutionBuilder(host, rootNames, defaultOptions || {});
|
||||
}
|
||||
|
||||
function createSolutionBuilderWithWatch(host: TsBuildWatchSystem, rootNames: ReadonlyArray<string>, defaultOptions?: BuildOptions) {
|
||||
const solutionBuilder = createSolutionBuilder(host, rootNames, defaultOptions);
|
||||
solutionBuilder.buildAllProjects();
|
||||
solutionBuilder.startWatching();
|
||||
function createSolutionBuilderWithWatch(system: TsBuildWatchSystem, rootNames: ReadonlyArray<string>, defaultOptions?: BuildOptions) {
|
||||
const host = createSolutionBuilderWithWatchHost(system);
|
||||
const solutionBuilder = ts.createSolutionBuilderWithWatch(host, rootNames, defaultOptions || { watch: true });
|
||||
solutionBuilder.build();
|
||||
return solutionBuilder;
|
||||
}
|
||||
|
||||
@@ -143,6 +143,28 @@ namespace ts.tscWatch {
|
||||
createSolutionInWatchMode(allFiles);
|
||||
});
|
||||
|
||||
it("verify building references watches only those projects", () => {
|
||||
const system = createTsBuildWatchSystem(allFiles, { currentDirectory: projectsLocation });
|
||||
const host = createSolutionBuilderWithWatchHost(system);
|
||||
const solutionBuilder = ts.createSolutionBuilderWithWatch(host, [`${project}/${SubProject.tests}`], { watch: true });
|
||||
solutionBuilder.buildReferences(`${project}/${SubProject.tests}`);
|
||||
|
||||
checkWatchedFiles(system, testProjectExpectedWatchedFiles.slice(0, testProjectExpectedWatchedFiles.length - tests.length));
|
||||
checkWatchedDirectories(system, emptyArray, /*recursive*/ false);
|
||||
checkWatchedDirectories(system, testProjectExpectedWatchedDirectoriesRecursive, /*recursive*/ true);
|
||||
|
||||
checkOutputErrorsInitial(system, emptyArray);
|
||||
const testOutput = getOutputStamps(system, SubProject.tests, "index");
|
||||
const outputFileStamps = getOutputFileStamps(system);
|
||||
for (const stamp of outputFileStamps.slice(0, outputFileStamps.length - testOutput.length)) {
|
||||
assert.isDefined(stamp[1], `${stamp[0]} expected to be present`);
|
||||
}
|
||||
for (const stamp of testOutput) {
|
||||
assert.isUndefined(stamp[1], `${stamp[0]} expected to be missing`);
|
||||
}
|
||||
return system;
|
||||
});
|
||||
|
||||
describe("validates the changes and watched files", () => {
|
||||
const newFileWithoutExtension = "newFile";
|
||||
const newFile: File = {
|
||||
@@ -607,7 +629,7 @@ let x: string = 10;`);
|
||||
// Build the composite project
|
||||
const host = createTsBuildWatchSystem(allFiles, { currentDirectory });
|
||||
const solutionBuilder = createSolutionBuilder(host, [solutionBuilderconfig], {});
|
||||
solutionBuilder.buildAllProjects();
|
||||
solutionBuilder.build();
|
||||
const outputFileStamps = getOutputFileStamps(host);
|
||||
for (const stamp of outputFileStamps) {
|
||||
assert.isDefined(stamp[1], `${stamp[0]} expected to be present`);
|
||||
@@ -676,7 +698,7 @@ let x: string = 10;`);
|
||||
}
|
||||
|
||||
function verifyScenario(
|
||||
edit: (host: TsBuildWatchSystem, solutionBuilder: SolutionBuilder) => void,
|
||||
edit: (host: TsBuildWatchSystem, solutionBuilder: SolutionBuilder<EmitAndSemanticDiagnosticsBuilderProgram>) => void,
|
||||
expectedFilesAfterEdit: ReadonlyArray<string>
|
||||
) {
|
||||
it("with tsc-watch", () => {
|
||||
@@ -721,8 +743,8 @@ let x: string = 10;`);
|
||||
host.writeFile(logic[1].path, `${logic[1].content}
|
||||
function foo() {
|
||||
}`);
|
||||
solutionBuilder.invalidateProject(`${project}/${SubProject.logic}`);
|
||||
solutionBuilder.buildInvalidatedProject();
|
||||
solutionBuilder.invalidateProject(logic[0].path.toLowerCase() as ResolvedConfigFilePath);
|
||||
solutionBuilder.buildNextInvalidatedProject();
|
||||
|
||||
// not ideal, but currently because of d.ts but no new file is written
|
||||
// There will be timeout queued even though file contents are same
|
||||
@@ -734,8 +756,8 @@ function foo() {
|
||||
host.writeFile(logic[1].path, `${logic[1].content}
|
||||
export function gfoo() {
|
||||
}`);
|
||||
solutionBuilder.invalidateProject(logic[0].path);
|
||||
solutionBuilder.buildInvalidatedProject();
|
||||
solutionBuilder.invalidateProject(logic[0].path.toLowerCase() as ResolvedConfigFilePath);
|
||||
solutionBuilder.buildNextInvalidatedProject();
|
||||
}, expectedProgramFiles);
|
||||
});
|
||||
|
||||
@@ -745,8 +767,8 @@ export function gfoo() {
|
||||
compilerOptions: { composite: true, declaration: true, declarationDir: "decls" },
|
||||
references: [{ path: "../core" }]
|
||||
}));
|
||||
solutionBuilder.invalidateProject(logic[0].path, ConfigFileProgramReloadLevel.Full);
|
||||
solutionBuilder.buildInvalidatedProject();
|
||||
solutionBuilder.invalidateProject(logic[0].path.toLowerCase() as ResolvedConfigFilePath, ConfigFileProgramReloadLevel.Full);
|
||||
solutionBuilder.buildNextInvalidatedProject();
|
||||
}, [tests[1].path, libFile.path, coreIndexDts, coreAnotherModuleDts, projectFilePath(SubProject.logic, "decls/index.d.ts")]);
|
||||
});
|
||||
});
|
||||
@@ -899,7 +921,7 @@ export function gfoo() {
|
||||
}
|
||||
|
||||
function verifyScenario(
|
||||
edit: (host: TsBuildWatchSystem, solutionBuilder: SolutionBuilder) => void,
|
||||
edit: (host: TsBuildWatchSystem, solutionBuilder: SolutionBuilder<EmitAndSemanticDiagnosticsBuilderProgram>) => void,
|
||||
expectedEditErrors: ReadonlyArray<string>,
|
||||
expectedProgramFiles: ReadonlyArray<string>,
|
||||
expectedWatchedFiles: ReadonlyArray<string>,
|
||||
@@ -965,8 +987,8 @@ export function gfoo() {
|
||||
host.writeFile(bTs.path, `${bTs.content}
|
||||
export function gfoo() {
|
||||
}`);
|
||||
solutionBuilder.invalidateProject(bTsconfig.path);
|
||||
solutionBuilder.buildInvalidatedProject();
|
||||
solutionBuilder.invalidateProject(bTsconfig.path.toLowerCase() as ResolvedConfigFilePath);
|
||||
solutionBuilder.buildNextInvalidatedProject();
|
||||
},
|
||||
emptyArray,
|
||||
expectedProgramFiles,
|
||||
@@ -1140,9 +1162,7 @@ export function gfoo() {
|
||||
|
||||
it("incremental updates in verbose mode", () => {
|
||||
const host = createTsBuildWatchSystem(allFiles, { currentDirectory: projectsLocation });
|
||||
const solutionBuilder = createSolutionBuilder(host, [`${project}/${SubProject.tests}`], { verbose: true, watch: true });
|
||||
solutionBuilder.buildAllProjects();
|
||||
solutionBuilder.startWatching();
|
||||
createSolutionBuilderWithWatch(host, [`${project}/${SubProject.tests}`], { verbose: true, watch: true });
|
||||
checkOutputErrorsInitial(host, emptyArray, /*disableConsoleClears*/ undefined, [
|
||||
`Projects in this build: \r\n * sample1/core/tsconfig.json\r\n * sample1/logic/tsconfig.json\r\n * sample1/tests/tsconfig.json\n\n`,
|
||||
`Project 'sample1/core/tsconfig.json' is out of date because output file 'sample1/core/anotherModule.js' does not exist\n\n`,
|
||||
|
||||
@@ -105,9 +105,23 @@ namespace ts.tscWatch {
|
||||
result.close();
|
||||
}
|
||||
|
||||
function sanitizeBuildInfo(content: string) {
|
||||
const buildInfo = getBuildInfo(content);
|
||||
fakes.sanitizeBuildInfoProgram(buildInfo);
|
||||
return getBuildInfoText(buildInfo);
|
||||
}
|
||||
|
||||
function checkFileEmit(actual: Map<string>, expected: ReadonlyArray<File>) {
|
||||
assert.equal(actual.size, expected.length, `Actual: ${JSON.stringify(arrayFrom(actual.entries()), /*replacer*/ undefined, " ")}\nExpected: ${JSON.stringify(expected, /*replacer*/ undefined, " ")}`);
|
||||
expected.forEach(file => assert.equal(actual.get(file.path), file.content, `Emit for ${file.path}`));
|
||||
expected.forEach(file => {
|
||||
let expectedContent = file.content;
|
||||
let actualContent = actual.get(file.path);
|
||||
if (isBuildInfoFile(file.path)) {
|
||||
actualContent = actualContent && sanitizeBuildInfo(actualContent);
|
||||
expectedContent = sanitizeBuildInfo(expectedContent);
|
||||
}
|
||||
assert.equal(actualContent, expectedContent, `Emit for ${file.path}`);
|
||||
});
|
||||
}
|
||||
|
||||
const libFileInfo: BuilderState.FileInfo = {
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace ts.projectSystem {
|
||||
|
||||
// ts build should succeed
|
||||
const solutionBuilder = tscWatch.createSolutionBuilder(host, rootNames, {});
|
||||
solutionBuilder.buildAllProjects();
|
||||
solutionBuilder.build();
|
||||
assert.equal(host.getOutput().length, 0);
|
||||
|
||||
return host;
|
||||
|
||||
@@ -1341,6 +1341,26 @@ var x = 10;`
|
||||
}
|
||||
});
|
||||
|
||||
it("no project structure update on directory watch invoke on open file save", () => {
|
||||
const projectRootPath = "/users/username/projects/project";
|
||||
const file1: File = {
|
||||
path: `${projectRootPath}/a.ts`,
|
||||
content: "export const a = 10;"
|
||||
};
|
||||
const config: File = {
|
||||
path: `${projectRootPath}/tsconfig.json`,
|
||||
content: "{}"
|
||||
};
|
||||
const files = [file1, config];
|
||||
const host = createServerHost(files);
|
||||
const service = createProjectService(host);
|
||||
service.openClientFile(file1.path);
|
||||
checkNumberOfProjects(service, { configuredProjects: 1 });
|
||||
|
||||
host.modifyFile(file1.path, file1.content, { invokeFileDeleteCreateAsPartInsteadOfChange: true });
|
||||
host.checkTimeoutQueueLength(0);
|
||||
});
|
||||
|
||||
it("handles delayed directory watch invoke on file creation", () => {
|
||||
const projectRootPath = "/users/username/projects/project";
|
||||
const fileB: File = {
|
||||
|
||||
@@ -975,5 +975,34 @@ export const x = 10;`
|
||||
host.checkTimeoutQueueLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("avoid unnecessary invalidation", () => {
|
||||
it("unnecessary lookup invalidation on save", () => {
|
||||
const expectedNonRelativeDirectories = [`${projectLocation}/node_modules`, `${projectLocation}/src`];
|
||||
const module1Name = "module1";
|
||||
const module2Name = "module2";
|
||||
const fileContent = `import { module1 } from "${module1Name}";import { module2 } from "${module2Name}";`;
|
||||
const file1: File = {
|
||||
path: `${projectLocation}/src/file1.ts`,
|
||||
content: fileContent
|
||||
};
|
||||
const { module1, module2 } = getModules(`${projectLocation}/src/node_modules/module1/index.ts`, `${projectLocation}/node_modules/module2/index.ts`);
|
||||
const files = [module1, module2, file1, configFile, libFile];
|
||||
const host = createServerHost(files);
|
||||
const resolutionTrace = createHostModuleResolutionTrace(host);
|
||||
const service = createProjectService(host);
|
||||
service.openClientFile(file1.path);
|
||||
const project = service.configuredProjects.get(configFile.path)!;
|
||||
(project as ResolutionCacheHost).maxNumberOfFilesToIterateForInvalidation = 1;
|
||||
const expectedTrace = getExpectedNonRelativeModuleResolutionTrace(host, file1, module1, module1Name);
|
||||
getExpectedNonRelativeModuleResolutionTrace(host, file1, module2, module2Name, expectedTrace);
|
||||
verifyTrace(resolutionTrace, expectedTrace);
|
||||
verifyWatchesWithConfigFile(host, files, file1, expectedNonRelativeDirectories);
|
||||
|
||||
// invoke callback to simulate saving
|
||||
host.modifyFile(file1.path, file1.content, { invokeFileDeleteCreateAsPartInsteadOfChange: true });
|
||||
host.checkTimeoutQueueLengthAndRun(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -60,13 +60,14 @@ describe("Test Suite 1", () => {
|
||||
|
||||
const navBarResultUnitTest1 = navBarFull(session, unitTest1);
|
||||
host.deleteFile(unitTest1.path);
|
||||
host.checkTimeoutQueueLengthAndRun(2);
|
||||
checkProjectActualFiles(project, expectedFilesWithoutUnitTest1);
|
||||
host.checkTimeoutQueueLengthAndRun(0);
|
||||
checkProjectActualFiles(project, expectedFilesWithUnitTest1);
|
||||
|
||||
session.executeCommandSeq<protocol.CloseRequest>({
|
||||
command: protocol.CommandTypes.Close,
|
||||
arguments: { file: unitTest1.path }
|
||||
});
|
||||
host.checkTimeoutQueueLengthAndRun(2);
|
||||
checkProjectActualFiles(project, expectedFilesWithoutUnitTest1);
|
||||
|
||||
const unitTest1WithChangedContent: File = {
|
||||
|
||||
+14
-19
@@ -183,6 +183,9 @@ namespace ts {
|
||||
|
||||
function performBuild(args: string[]) {
|
||||
const { buildOptions, projects, errors } = parseBuildCommand(args);
|
||||
// Update to pretty if host supports it
|
||||
updateReportDiagnostic(buildOptions);
|
||||
|
||||
if (errors.length > 0) {
|
||||
errors.forEach(reportDiagnostic);
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
@@ -194,8 +197,6 @@ namespace ts {
|
||||
return sys.exit(ExitStatus.Success);
|
||||
}
|
||||
|
||||
// Update to pretty if host supports it
|
||||
updateReportDiagnostic(buildOptions);
|
||||
if (projects.length === 0) {
|
||||
printVersion();
|
||||
printHelp(buildOpts, "--build ");
|
||||
@@ -206,28 +207,22 @@ namespace ts {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--build"));
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
|
||||
if (buildOptions.watch) {
|
||||
reportWatchModeWithoutSysSupport();
|
||||
const buildHost = createSolutionBuilderWithWatchHost(sys, /*createProgram*/ undefined, reportDiagnostic, createBuilderStatusReporter(sys, shouldBePretty(buildOptions)), createWatchStatusReporter(buildOptions));
|
||||
updateCreateProgram(buildHost);
|
||||
buildHost.afterProgramEmitAndDiagnostics = program => reportStatistics(program.getProgram());
|
||||
const builder = createSolutionBuilderWithWatch(buildHost, projects, buildOptions);
|
||||
builder.build();
|
||||
return;
|
||||
}
|
||||
|
||||
// Use default createProgram
|
||||
const buildHost = buildOptions.watch ?
|
||||
createSolutionBuilderWithWatchHost(sys, /*createProgram*/ undefined, reportDiagnostic, createBuilderStatusReporter(sys, shouldBePretty(buildOptions)), createWatchStatusReporter(buildOptions)) :
|
||||
createSolutionBuilderHost(sys, /*createProgram*/ undefined, reportDiagnostic, createBuilderStatusReporter(sys, shouldBePretty(buildOptions)), createReportErrorSummary(buildOptions));
|
||||
const buildHost = createSolutionBuilderHost(sys, /*createProgram*/ undefined, reportDiagnostic, createBuilderStatusReporter(sys, shouldBePretty(buildOptions)), createReportErrorSummary(buildOptions));
|
||||
updateCreateProgram(buildHost);
|
||||
buildHost.afterProgramEmitAndDiagnostics = (program: BuilderProgram) => reportStatistics(program.getProgram());
|
||||
|
||||
buildHost.afterProgramEmitAndDiagnostics = program => reportStatistics(program.getProgram());
|
||||
const builder = createSolutionBuilder(buildHost, projects, buildOptions);
|
||||
if (buildOptions.clean) {
|
||||
return sys.exit(builder.cleanAllProjects());
|
||||
}
|
||||
|
||||
if (buildOptions.watch) {
|
||||
builder.buildAllProjects();
|
||||
return (builder as SolutionBuilderWithWatch).startWatching();
|
||||
}
|
||||
|
||||
return sys.exit(builder.buildAllProjects());
|
||||
return sys.exit(buildOptions.clean ? builder.clean() : builder.build());
|
||||
}
|
||||
|
||||
function createReportErrorSummary(options: CompilerOptions | BuildOptions): ReportEmitErrorSummary | undefined {
|
||||
@@ -251,7 +246,7 @@ namespace ts {
|
||||
configFileParsingDiagnostics
|
||||
};
|
||||
const program = createProgram(programOptions);
|
||||
const exitStatus = emitFilesAndReportErrors(
|
||||
const exitStatus = emitFilesAndReportErrorsAndGetExitStatus(
|
||||
program,
|
||||
reportDiagnostic,
|
||||
s => sys.write(s + sys.newLine),
|
||||
|
||||
+102
-4
@@ -14,7 +14,7 @@ and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "3.5";
|
||||
const versionMajorMinor = "3.6";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
@@ -1910,7 +1910,8 @@ declare namespace ts {
|
||||
enum ExitStatus {
|
||||
Success = 0,
|
||||
DiagnosticsPresent_OutputsSkipped = 1,
|
||||
DiagnosticsPresent_OutputsGenerated = 2
|
||||
DiagnosticsPresent_OutputsGenerated = 2,
|
||||
InvalidProject_OutputsSkipped = 3
|
||||
}
|
||||
interface EmitResult {
|
||||
emitSkipped: boolean;
|
||||
@@ -1969,6 +1970,7 @@ declare namespace ts {
|
||||
*/
|
||||
getExportSymbolOfSymbol(symbol: Symbol): Symbol;
|
||||
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined;
|
||||
getTypeOfAssignmentPattern(pattern: AssignmentPattern): Type;
|
||||
getTypeAtLocation(node: Node): Type;
|
||||
getTypeFromTypeNode(node: TypeNode): Type;
|
||||
signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string;
|
||||
@@ -4422,7 +4424,7 @@ declare namespace ts {
|
||||
* The builder that can handle the changes in program and iterate through changed file to emit the files
|
||||
* The semantic diagnostics are cached per file and managed by clearing for the changed/affected files
|
||||
*/
|
||||
interface EmitAndSemanticDiagnosticsBuilderProgram extends BuilderProgram {
|
||||
interface EmitAndSemanticDiagnosticsBuilderProgram extends SemanticDiagnosticsBuilderProgram {
|
||||
/**
|
||||
* Emits the next affected file's emit result (EmitResult and sourceFiles emitted) or returns undefined if iteration is complete
|
||||
* The first of writeFile if provided, writeFile of BuilderProgramHost if provided, writeFile of compiler host
|
||||
@@ -4448,6 +4450,17 @@ declare namespace ts {
|
||||
function createAbstractBuilder(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>): BuilderProgram;
|
||||
}
|
||||
declare namespace ts {
|
||||
function readBuilderProgram(compilerOptions: CompilerOptions, readFile: (path: string) => string | undefined): EmitAndSemanticDiagnosticsBuilderProgram | undefined;
|
||||
function createIncrementalCompilerHost(options: CompilerOptions, system?: System): CompilerHost;
|
||||
interface IncrementalProgramOptions<T extends BuilderProgram> {
|
||||
rootNames: ReadonlyArray<string>;
|
||||
options: CompilerOptions;
|
||||
configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>;
|
||||
projectReferences?: ReadonlyArray<ProjectReference>;
|
||||
host?: CompilerHost;
|
||||
createProgram?: CreateProgram<T>;
|
||||
}
|
||||
function createIncrementalProgram<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>({ rootNames, options, configFileParsingDiagnostics, projectReferences, host, createProgram }: IncrementalProgramOptions<T>): T;
|
||||
type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string, options: CompilerOptions) => void;
|
||||
/** Create the program with rootNames and options, if they are undefined, oldProgram and new configFile diagnostics create new program */
|
||||
type CreateProgram<T extends BuilderProgram> = (rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference> | undefined) => T;
|
||||
@@ -4561,6 +4574,91 @@ declare namespace ts {
|
||||
*/
|
||||
function createWatchProgram<T extends BuilderProgram>(host: WatchCompilerHostOfConfigFile<T>): WatchOfConfigFile<T>;
|
||||
}
|
||||
declare namespace ts {
|
||||
interface BuildOptions {
|
||||
dry?: boolean;
|
||||
force?: boolean;
|
||||
verbose?: boolean;
|
||||
incremental?: boolean;
|
||||
traceResolution?: boolean;
|
||||
[option: string]: CompilerOptionsValue | undefined;
|
||||
}
|
||||
type ReportEmitErrorSummary = (errorCount: number) => void;
|
||||
interface SolutionBuilderHostBase<T extends BuilderProgram> extends ProgramHost<T> {
|
||||
createDirectory?(path: string): void;
|
||||
/**
|
||||
* Should provide create directory and writeFile if done of invalidatedProjects is not invoked with
|
||||
* writeFileCallback
|
||||
*/
|
||||
writeFile?(path: string, data: string, writeByteOrderMark?: boolean): void;
|
||||
getModifiedTime(fileName: string): Date | undefined;
|
||||
setModifiedTime(fileName: string, date: Date): void;
|
||||
deleteFile(fileName: string): void;
|
||||
getParsedCommandLine?(fileName: string): ParsedCommandLine | undefined;
|
||||
reportDiagnostic: DiagnosticReporter;
|
||||
reportSolutionBuilderStatus: DiagnosticReporter;
|
||||
afterProgramEmitAndDiagnostics?(program: T): void;
|
||||
}
|
||||
interface SolutionBuilderHost<T extends BuilderProgram> extends SolutionBuilderHostBase<T> {
|
||||
reportErrorSummary?: ReportEmitErrorSummary;
|
||||
}
|
||||
interface SolutionBuilderWithWatchHost<T extends BuilderProgram> extends SolutionBuilderHostBase<T>, WatchHost {
|
||||
}
|
||||
interface SolutionBuilder<T extends BuilderProgram> {
|
||||
build(project?: string, cancellationToken?: CancellationToken): ExitStatus;
|
||||
clean(project?: string): ExitStatus;
|
||||
buildReferences(project: string, cancellationToken?: CancellationToken): ExitStatus;
|
||||
cleanReferences(project?: string): ExitStatus;
|
||||
getNextInvalidatedProject(cancellationToken?: CancellationToken): InvalidatedProject<T> | undefined;
|
||||
}
|
||||
/**
|
||||
* Create a function that reports watch status by writing to the system and handles the formating of the diagnostic
|
||||
*/
|
||||
function createBuilderStatusReporter(system: System, pretty?: boolean): DiagnosticReporter;
|
||||
function createSolutionBuilderHost<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>(system?: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter, reportErrorSummary?: ReportEmitErrorSummary): SolutionBuilderHost<T>;
|
||||
function createSolutionBuilderWithWatchHost<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>(system?: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): SolutionBuilderWithWatchHost<T>;
|
||||
function createSolutionBuilder<T extends BuilderProgram>(host: SolutionBuilderHost<T>, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions): SolutionBuilder<T>;
|
||||
function createSolutionBuilderWithWatch<T extends BuilderProgram>(host: SolutionBuilderWithWatchHost<T>, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions): SolutionBuilder<T>;
|
||||
enum InvalidatedProjectKind {
|
||||
Build = 0,
|
||||
UpdateBundle = 1,
|
||||
UpdateOutputFileStamps = 2
|
||||
}
|
||||
interface InvalidatedProjectBase {
|
||||
readonly kind: InvalidatedProjectKind;
|
||||
readonly project: ResolvedConfigFileName;
|
||||
/**
|
||||
* To dispose this project and ensure that all the necessary actions are taken and state is updated accordingly
|
||||
*/
|
||||
done(cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, customTransformers?: CustomTransformers): ExitStatus;
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
getCurrentDirectory(): string;
|
||||
}
|
||||
interface UpdateOutputFileStampsProject extends InvalidatedProjectBase {
|
||||
readonly kind: InvalidatedProjectKind.UpdateOutputFileStamps;
|
||||
updateOutputFileStatmps(): void;
|
||||
}
|
||||
interface BuildInvalidedProject<T extends BuilderProgram> extends InvalidatedProjectBase {
|
||||
readonly kind: InvalidatedProjectKind.Build;
|
||||
getBuilderProgram(): T | undefined;
|
||||
getProgram(): Program | undefined;
|
||||
getSourceFile(fileName: string): SourceFile | undefined;
|
||||
getSourceFiles(): ReadonlyArray<SourceFile>;
|
||||
getOptionsDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getConfigFileParsingDiagnostics(): ReadonlyArray<Diagnostic>;
|
||||
getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getAllDependencies(sourceFile: SourceFile): ReadonlyArray<string>;
|
||||
getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getSemanticDiagnosticsOfNextAffectedFile(cancellationToken?: CancellationToken, ignoreSourceFile?: (sourceFile: SourceFile) => boolean): AffectedFileResult<ReadonlyArray<Diagnostic>>;
|
||||
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult | undefined;
|
||||
}
|
||||
interface UpdateBundleProject<T extends BuilderProgram> extends InvalidatedProjectBase {
|
||||
readonly kind: InvalidatedProjectKind.UpdateBundle;
|
||||
emit(writeFile?: WriteFileCallback, customTransformers?: CustomTransformers): EmitResult | BuildInvalidedProject<T> | undefined;
|
||||
}
|
||||
type InvalidatedProject<T extends BuilderProgram> = UpdateOutputFileStampsProject | BuildInvalidedProject<T> | UpdateBundleProject<T>;
|
||||
}
|
||||
declare namespace ts.server {
|
||||
type ActionSet = "action::set";
|
||||
type ActionInvalidate = "action::invalidate";
|
||||
@@ -8333,7 +8431,7 @@ declare namespace ts.server {
|
||||
private readonly cancellationToken;
|
||||
isNonTsProject(): boolean;
|
||||
isJsOnlyProject(): boolean;
|
||||
static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {} | undefined;
|
||||
static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void, logErrors?: (message: string) => void): {} | undefined;
|
||||
isKnownTypesPackageName(name: string): boolean;
|
||||
installPackage(options: InstallPackageOptions): Promise<ApplyCodeActionCommandResult>;
|
||||
private readonly typingsCache;
|
||||
|
||||
+101
-3
@@ -14,7 +14,7 @@ and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "3.5";
|
||||
const versionMajorMinor = "3.6";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
@@ -1910,7 +1910,8 @@ declare namespace ts {
|
||||
enum ExitStatus {
|
||||
Success = 0,
|
||||
DiagnosticsPresent_OutputsSkipped = 1,
|
||||
DiagnosticsPresent_OutputsGenerated = 2
|
||||
DiagnosticsPresent_OutputsGenerated = 2,
|
||||
InvalidProject_OutputsSkipped = 3
|
||||
}
|
||||
interface EmitResult {
|
||||
emitSkipped: boolean;
|
||||
@@ -1969,6 +1970,7 @@ declare namespace ts {
|
||||
*/
|
||||
getExportSymbolOfSymbol(symbol: Symbol): Symbol;
|
||||
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined;
|
||||
getTypeOfAssignmentPattern(pattern: AssignmentPattern): Type;
|
||||
getTypeAtLocation(node: Node): Type;
|
||||
getTypeFromTypeNode(node: TypeNode): Type;
|
||||
signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string;
|
||||
@@ -4422,7 +4424,7 @@ declare namespace ts {
|
||||
* The builder that can handle the changes in program and iterate through changed file to emit the files
|
||||
* The semantic diagnostics are cached per file and managed by clearing for the changed/affected files
|
||||
*/
|
||||
interface EmitAndSemanticDiagnosticsBuilderProgram extends BuilderProgram {
|
||||
interface EmitAndSemanticDiagnosticsBuilderProgram extends SemanticDiagnosticsBuilderProgram {
|
||||
/**
|
||||
* Emits the next affected file's emit result (EmitResult and sourceFiles emitted) or returns undefined if iteration is complete
|
||||
* The first of writeFile if provided, writeFile of BuilderProgramHost if provided, writeFile of compiler host
|
||||
@@ -4448,6 +4450,17 @@ declare namespace ts {
|
||||
function createAbstractBuilder(rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference>): BuilderProgram;
|
||||
}
|
||||
declare namespace ts {
|
||||
function readBuilderProgram(compilerOptions: CompilerOptions, readFile: (path: string) => string | undefined): EmitAndSemanticDiagnosticsBuilderProgram | undefined;
|
||||
function createIncrementalCompilerHost(options: CompilerOptions, system?: System): CompilerHost;
|
||||
interface IncrementalProgramOptions<T extends BuilderProgram> {
|
||||
rootNames: ReadonlyArray<string>;
|
||||
options: CompilerOptions;
|
||||
configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>;
|
||||
projectReferences?: ReadonlyArray<ProjectReference>;
|
||||
host?: CompilerHost;
|
||||
createProgram?: CreateProgram<T>;
|
||||
}
|
||||
function createIncrementalProgram<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>({ rootNames, options, configFileParsingDiagnostics, projectReferences, host, createProgram }: IncrementalProgramOptions<T>): T;
|
||||
type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string, options: CompilerOptions) => void;
|
||||
/** Create the program with rootNames and options, if they are undefined, oldProgram and new configFile diagnostics create new program */
|
||||
type CreateProgram<T extends BuilderProgram> = (rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>, projectReferences?: ReadonlyArray<ProjectReference> | undefined) => T;
|
||||
@@ -4561,6 +4574,91 @@ declare namespace ts {
|
||||
*/
|
||||
function createWatchProgram<T extends BuilderProgram>(host: WatchCompilerHostOfConfigFile<T>): WatchOfConfigFile<T>;
|
||||
}
|
||||
declare namespace ts {
|
||||
interface BuildOptions {
|
||||
dry?: boolean;
|
||||
force?: boolean;
|
||||
verbose?: boolean;
|
||||
incremental?: boolean;
|
||||
traceResolution?: boolean;
|
||||
[option: string]: CompilerOptionsValue | undefined;
|
||||
}
|
||||
type ReportEmitErrorSummary = (errorCount: number) => void;
|
||||
interface SolutionBuilderHostBase<T extends BuilderProgram> extends ProgramHost<T> {
|
||||
createDirectory?(path: string): void;
|
||||
/**
|
||||
* Should provide create directory and writeFile if done of invalidatedProjects is not invoked with
|
||||
* writeFileCallback
|
||||
*/
|
||||
writeFile?(path: string, data: string, writeByteOrderMark?: boolean): void;
|
||||
getModifiedTime(fileName: string): Date | undefined;
|
||||
setModifiedTime(fileName: string, date: Date): void;
|
||||
deleteFile(fileName: string): void;
|
||||
getParsedCommandLine?(fileName: string): ParsedCommandLine | undefined;
|
||||
reportDiagnostic: DiagnosticReporter;
|
||||
reportSolutionBuilderStatus: DiagnosticReporter;
|
||||
afterProgramEmitAndDiagnostics?(program: T): void;
|
||||
}
|
||||
interface SolutionBuilderHost<T extends BuilderProgram> extends SolutionBuilderHostBase<T> {
|
||||
reportErrorSummary?: ReportEmitErrorSummary;
|
||||
}
|
||||
interface SolutionBuilderWithWatchHost<T extends BuilderProgram> extends SolutionBuilderHostBase<T>, WatchHost {
|
||||
}
|
||||
interface SolutionBuilder<T extends BuilderProgram> {
|
||||
build(project?: string, cancellationToken?: CancellationToken): ExitStatus;
|
||||
clean(project?: string): ExitStatus;
|
||||
buildReferences(project: string, cancellationToken?: CancellationToken): ExitStatus;
|
||||
cleanReferences(project?: string): ExitStatus;
|
||||
getNextInvalidatedProject(cancellationToken?: CancellationToken): InvalidatedProject<T> | undefined;
|
||||
}
|
||||
/**
|
||||
* Create a function that reports watch status by writing to the system and handles the formating of the diagnostic
|
||||
*/
|
||||
function createBuilderStatusReporter(system: System, pretty?: boolean): DiagnosticReporter;
|
||||
function createSolutionBuilderHost<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>(system?: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter, reportErrorSummary?: ReportEmitErrorSummary): SolutionBuilderHost<T>;
|
||||
function createSolutionBuilderWithWatchHost<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>(system?: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): SolutionBuilderWithWatchHost<T>;
|
||||
function createSolutionBuilder<T extends BuilderProgram>(host: SolutionBuilderHost<T>, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions): SolutionBuilder<T>;
|
||||
function createSolutionBuilderWithWatch<T extends BuilderProgram>(host: SolutionBuilderWithWatchHost<T>, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions): SolutionBuilder<T>;
|
||||
enum InvalidatedProjectKind {
|
||||
Build = 0,
|
||||
UpdateBundle = 1,
|
||||
UpdateOutputFileStamps = 2
|
||||
}
|
||||
interface InvalidatedProjectBase {
|
||||
readonly kind: InvalidatedProjectKind;
|
||||
readonly project: ResolvedConfigFileName;
|
||||
/**
|
||||
* To dispose this project and ensure that all the necessary actions are taken and state is updated accordingly
|
||||
*/
|
||||
done(cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, customTransformers?: CustomTransformers): ExitStatus;
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
getCurrentDirectory(): string;
|
||||
}
|
||||
interface UpdateOutputFileStampsProject extends InvalidatedProjectBase {
|
||||
readonly kind: InvalidatedProjectKind.UpdateOutputFileStamps;
|
||||
updateOutputFileStatmps(): void;
|
||||
}
|
||||
interface BuildInvalidedProject<T extends BuilderProgram> extends InvalidatedProjectBase {
|
||||
readonly kind: InvalidatedProjectKind.Build;
|
||||
getBuilderProgram(): T | undefined;
|
||||
getProgram(): Program | undefined;
|
||||
getSourceFile(fileName: string): SourceFile | undefined;
|
||||
getSourceFiles(): ReadonlyArray<SourceFile>;
|
||||
getOptionsDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getConfigFileParsingDiagnostics(): ReadonlyArray<Diagnostic>;
|
||||
getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getAllDependencies(sourceFile: SourceFile): ReadonlyArray<string>;
|
||||
getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getSemanticDiagnosticsOfNextAffectedFile(cancellationToken?: CancellationToken, ignoreSourceFile?: (sourceFile: SourceFile) => boolean): AffectedFileResult<ReadonlyArray<Diagnostic>>;
|
||||
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult | undefined;
|
||||
}
|
||||
interface UpdateBundleProject<T extends BuilderProgram> extends InvalidatedProjectBase {
|
||||
readonly kind: InvalidatedProjectKind.UpdateBundle;
|
||||
emit(writeFile?: WriteFileCallback, customTransformers?: CustomTransformers): EmitResult | BuildInvalidedProject<T> | undefined;
|
||||
}
|
||||
type InvalidatedProject<T extends BuilderProgram> = UpdateOutputFileStampsProject | BuildInvalidedProject<T> | UpdateBundleProject<T>;
|
||||
}
|
||||
declare namespace ts.server {
|
||||
type ActionSet = "action::set";
|
||||
type ActionInvalidate = "action::invalidate";
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
//// [contravariantTypeAliasInference.ts]
|
||||
type Func1<T> = (x: T) => void;
|
||||
type Func2<T> = ((x: T) => void) | undefined;
|
||||
|
||||
declare let f1: Func1<string>;
|
||||
declare let f2: Func1<"a">;
|
||||
|
||||
declare function foo<T>(f1: Func1<T>, f2: Func1<T>): void;
|
||||
|
||||
foo(f1, f2);
|
||||
|
||||
declare let g1: Func2<string>;
|
||||
declare let g2: Func2<"a">;
|
||||
|
||||
declare function bar<T>(g1: Func2<T>, g2: Func2<T>): void;
|
||||
|
||||
bar(f1, f2);
|
||||
bar(g1, g2);
|
||||
|
||||
|
||||
//// [contravariantTypeAliasInference.js]
|
||||
"use strict";
|
||||
foo(f1, f2);
|
||||
bar(f1, f2);
|
||||
bar(g1, g2);
|
||||
@@ -0,0 +1,64 @@
|
||||
=== tests/cases/compiler/contravariantTypeAliasInference.ts ===
|
||||
type Func1<T> = (x: T) => void;
|
||||
>Func1 : Symbol(Func1, Decl(contravariantTypeAliasInference.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 0, 11))
|
||||
>x : Symbol(x, Decl(contravariantTypeAliasInference.ts, 0, 17))
|
||||
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 0, 11))
|
||||
|
||||
type Func2<T> = ((x: T) => void) | undefined;
|
||||
>Func2 : Symbol(Func2, Decl(contravariantTypeAliasInference.ts, 0, 31))
|
||||
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 1, 11))
|
||||
>x : Symbol(x, Decl(contravariantTypeAliasInference.ts, 1, 18))
|
||||
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 1, 11))
|
||||
|
||||
declare let f1: Func1<string>;
|
||||
>f1 : Symbol(f1, Decl(contravariantTypeAliasInference.ts, 3, 11))
|
||||
>Func1 : Symbol(Func1, Decl(contravariantTypeAliasInference.ts, 0, 0))
|
||||
|
||||
declare let f2: Func1<"a">;
|
||||
>f2 : Symbol(f2, Decl(contravariantTypeAliasInference.ts, 4, 11))
|
||||
>Func1 : Symbol(Func1, Decl(contravariantTypeAliasInference.ts, 0, 0))
|
||||
|
||||
declare function foo<T>(f1: Func1<T>, f2: Func1<T>): void;
|
||||
>foo : Symbol(foo, Decl(contravariantTypeAliasInference.ts, 4, 27))
|
||||
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 6, 21))
|
||||
>f1 : Symbol(f1, Decl(contravariantTypeAliasInference.ts, 6, 24))
|
||||
>Func1 : Symbol(Func1, Decl(contravariantTypeAliasInference.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 6, 21))
|
||||
>f2 : Symbol(f2, Decl(contravariantTypeAliasInference.ts, 6, 37))
|
||||
>Func1 : Symbol(Func1, Decl(contravariantTypeAliasInference.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 6, 21))
|
||||
|
||||
foo(f1, f2);
|
||||
>foo : Symbol(foo, Decl(contravariantTypeAliasInference.ts, 4, 27))
|
||||
>f1 : Symbol(f1, Decl(contravariantTypeAliasInference.ts, 3, 11))
|
||||
>f2 : Symbol(f2, Decl(contravariantTypeAliasInference.ts, 4, 11))
|
||||
|
||||
declare let g1: Func2<string>;
|
||||
>g1 : Symbol(g1, Decl(contravariantTypeAliasInference.ts, 10, 11))
|
||||
>Func2 : Symbol(Func2, Decl(contravariantTypeAliasInference.ts, 0, 31))
|
||||
|
||||
declare let g2: Func2<"a">;
|
||||
>g2 : Symbol(g2, Decl(contravariantTypeAliasInference.ts, 11, 11))
|
||||
>Func2 : Symbol(Func2, Decl(contravariantTypeAliasInference.ts, 0, 31))
|
||||
|
||||
declare function bar<T>(g1: Func2<T>, g2: Func2<T>): void;
|
||||
>bar : Symbol(bar, Decl(contravariantTypeAliasInference.ts, 11, 27))
|
||||
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 13, 21))
|
||||
>g1 : Symbol(g1, Decl(contravariantTypeAliasInference.ts, 13, 24))
|
||||
>Func2 : Symbol(Func2, Decl(contravariantTypeAliasInference.ts, 0, 31))
|
||||
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 13, 21))
|
||||
>g2 : Symbol(g2, Decl(contravariantTypeAliasInference.ts, 13, 37))
|
||||
>Func2 : Symbol(Func2, Decl(contravariantTypeAliasInference.ts, 0, 31))
|
||||
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 13, 21))
|
||||
|
||||
bar(f1, f2);
|
||||
>bar : Symbol(bar, Decl(contravariantTypeAliasInference.ts, 11, 27))
|
||||
>f1 : Symbol(f1, Decl(contravariantTypeAliasInference.ts, 3, 11))
|
||||
>f2 : Symbol(f2, Decl(contravariantTypeAliasInference.ts, 4, 11))
|
||||
|
||||
bar(g1, g2);
|
||||
>bar : Symbol(bar, Decl(contravariantTypeAliasInference.ts, 11, 27))
|
||||
>g1 : Symbol(g1, Decl(contravariantTypeAliasInference.ts, 10, 11))
|
||||
>g2 : Symbol(g2, Decl(contravariantTypeAliasInference.ts, 11, 11))
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
=== tests/cases/compiler/contravariantTypeAliasInference.ts ===
|
||||
type Func1<T> = (x: T) => void;
|
||||
>Func1 : Func1<T>
|
||||
>x : T
|
||||
|
||||
type Func2<T> = ((x: T) => void) | undefined;
|
||||
>Func2 : Func2<T>
|
||||
>x : T
|
||||
|
||||
declare let f1: Func1<string>;
|
||||
>f1 : Func1<string>
|
||||
|
||||
declare let f2: Func1<"a">;
|
||||
>f2 : Func1<"a">
|
||||
|
||||
declare function foo<T>(f1: Func1<T>, f2: Func1<T>): void;
|
||||
>foo : <T>(f1: Func1<T>, f2: Func1<T>) => void
|
||||
>f1 : Func1<T>
|
||||
>f2 : Func1<T>
|
||||
|
||||
foo(f1, f2);
|
||||
>foo(f1, f2) : void
|
||||
>foo : <T>(f1: Func1<T>, f2: Func1<T>) => void
|
||||
>f1 : Func1<string>
|
||||
>f2 : Func1<"a">
|
||||
|
||||
declare let g1: Func2<string>;
|
||||
>g1 : Func2<string>
|
||||
|
||||
declare let g2: Func2<"a">;
|
||||
>g2 : Func2<"a">
|
||||
|
||||
declare function bar<T>(g1: Func2<T>, g2: Func2<T>): void;
|
||||
>bar : <T>(g1: Func2<T>, g2: Func2<T>) => void
|
||||
>g1 : Func2<T>
|
||||
>g2 : Func2<T>
|
||||
|
||||
bar(f1, f2);
|
||||
>bar(f1, f2) : void
|
||||
>bar : <T>(g1: Func2<T>, g2: Func2<T>) => void
|
||||
>f1 : Func1<string>
|
||||
>f2 : Func1<"a">
|
||||
|
||||
bar(g1, g2);
|
||||
>bar(g1, g2) : void
|
||||
>bar : <T>(g1: Func2<T>, g2: Func2<T>) => void
|
||||
>g1 : Func2<string>
|
||||
>g2 : Func2<"a">
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
//// [tests/cases/compiler/declarationEmitForGlobalishSpecifierSymlink.ts] ////
|
||||
|
||||
//// [impl.d.ts]
|
||||
export function getA(): A;
|
||||
export enum A {
|
||||
Val
|
||||
}
|
||||
//// [index.d.ts]
|
||||
export * from "./src/impl";
|
||||
//// [package.json]
|
||||
{
|
||||
"name": "typescript-fsa",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
//// [impl.d.ts]
|
||||
export function getA(): A;
|
||||
export enum A {
|
||||
Val
|
||||
}
|
||||
//// [index.d.ts]
|
||||
export * from "./src/impl";
|
||||
//// [package.json]
|
||||
{
|
||||
"name": "typescript-fsa",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
//// [index.ts]
|
||||
import * as _whatever from "p2";
|
||||
import { getA } from "typescript-fsa";
|
||||
|
||||
export const a = getA();
|
||||
//// [index.d.ts]
|
||||
export const a: import("typescript-fsa").A;
|
||||
|
||||
|
||||
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var typescript_fsa_1 = require("typescript-fsa");
|
||||
exports.a = typescript_fsa_1.getA();
|
||||
|
||||
|
||||
//// [index.d.ts]
|
||||
export declare const a: import("typescript-fsa").A;
|
||||
@@ -0,0 +1,43 @@
|
||||
=== /p1/node_modules/typescript-fsa/src/impl.d.ts ===
|
||||
export function getA(): A;
|
||||
>getA : Symbol(getA, Decl(impl.d.ts, 0, 0))
|
||||
>A : Symbol(A, Decl(impl.d.ts, 0, 26))
|
||||
|
||||
export enum A {
|
||||
>A : Symbol(A, Decl(impl.d.ts, 0, 26))
|
||||
|
||||
Val
|
||||
>Val : Symbol(A.Val, Decl(impl.d.ts, 1, 15))
|
||||
}
|
||||
=== /p1/node_modules/typescript-fsa/index.d.ts ===
|
||||
export * from "./src/impl";
|
||||
No type information for this code.=== /p2/node_modules/typescript-fsa/src/impl.d.ts ===
|
||||
export function getA(): A;
|
||||
>getA : Symbol(getA, Decl(impl.d.ts, 0, 0))
|
||||
>A : Symbol(A, Decl(impl.d.ts, 0, 26))
|
||||
|
||||
export enum A {
|
||||
>A : Symbol(A, Decl(impl.d.ts, 0, 26))
|
||||
|
||||
Val
|
||||
>Val : Symbol(A.Val, Decl(impl.d.ts, 1, 15))
|
||||
}
|
||||
=== /p2/node_modules/typescript-fsa/index.d.ts ===
|
||||
export * from "./src/impl";
|
||||
No type information for this code.=== /p1/index.ts ===
|
||||
import * as _whatever from "p2";
|
||||
>_whatever : Symbol(_whatever, Decl(index.ts, 0, 6))
|
||||
|
||||
import { getA } from "typescript-fsa";
|
||||
>getA : Symbol(getA, Decl(index.ts, 1, 8))
|
||||
|
||||
export const a = getA();
|
||||
>a : Symbol(a, Decl(index.ts, 3, 12))
|
||||
>getA : Symbol(getA, Decl(index.ts, 1, 8))
|
||||
|
||||
=== /p2/index.d.ts ===
|
||||
export const a: import("typescript-fsa").A;
|
||||
>a : Symbol(a, Decl(index.d.ts, 0, 12))
|
||||
>A : Symbol(A, Decl(impl.d.ts, 0, 26))
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
=== /p1/node_modules/typescript-fsa/src/impl.d.ts ===
|
||||
export function getA(): A;
|
||||
>getA : () => A
|
||||
|
||||
export enum A {
|
||||
>A : A
|
||||
|
||||
Val
|
||||
>Val : A
|
||||
}
|
||||
=== /p1/node_modules/typescript-fsa/index.d.ts ===
|
||||
export * from "./src/impl";
|
||||
No type information for this code.=== /p2/node_modules/typescript-fsa/src/impl.d.ts ===
|
||||
export function getA(): A;
|
||||
>getA : () => A
|
||||
|
||||
export enum A {
|
||||
>A : A
|
||||
|
||||
Val
|
||||
>Val : A
|
||||
}
|
||||
=== /p2/node_modules/typescript-fsa/index.d.ts ===
|
||||
export * from "./src/impl";
|
||||
No type information for this code.=== /p1/index.ts ===
|
||||
import * as _whatever from "p2";
|
||||
>_whatever : typeof _whatever
|
||||
|
||||
import { getA } from "typescript-fsa";
|
||||
>getA : () => import("/p1/node_modules/typescript-fsa/index").A
|
||||
|
||||
export const a = getA();
|
||||
>a : import("/p1/node_modules/typescript-fsa/index").A
|
||||
>getA() : import("/p1/node_modules/typescript-fsa/index").A
|
||||
>getA : () => import("/p1/node_modules/typescript-fsa/index").A
|
||||
|
||||
=== /p2/index.d.ts ===
|
||||
export const a: import("typescript-fsa").A;
|
||||
>a : import("/p2/node_modules/typescript-fsa/index").A
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
//// [tests/cases/compiler/declarationEmitForGlobalishSpecifierSymlink2.ts] ////
|
||||
|
||||
//// [impl.d.ts]
|
||||
export function getA(): A;
|
||||
export enum A {
|
||||
Val
|
||||
}
|
||||
//// [index.d.ts]
|
||||
export * from "./src/impl";
|
||||
//// [package.json]
|
||||
{
|
||||
"name": "typescript-fsa",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
//// [index.ts]
|
||||
import * as _whatever from "p2";
|
||||
import { getA } from "typescript-fsa";
|
||||
|
||||
export const a = getA();
|
||||
//// [index.d.ts]
|
||||
export const a: import("typescript-fsa").A;
|
||||
|
||||
|
||||
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var typescript_fsa_1 = require("typescript-fsa");
|
||||
exports.a = typescript_fsa_1.getA();
|
||||
|
||||
|
||||
//// [index.d.ts]
|
||||
export declare const a: import("typescript-fsa").A;
|
||||
@@ -0,0 +1,30 @@
|
||||
=== /cache/typescript-fsa/src/impl.d.ts ===
|
||||
export function getA(): A;
|
||||
>getA : Symbol(getA, Decl(impl.d.ts, 0, 0))
|
||||
>A : Symbol(A, Decl(impl.d.ts, 0, 26))
|
||||
|
||||
export enum A {
|
||||
>A : Symbol(A, Decl(impl.d.ts, 0, 26))
|
||||
|
||||
Val
|
||||
>Val : Symbol(A.Val, Decl(impl.d.ts, 1, 15))
|
||||
}
|
||||
=== /cache/typescript-fsa/index.d.ts ===
|
||||
export * from "./src/impl";
|
||||
No type information for this code.=== /p1/index.ts ===
|
||||
import * as _whatever from "p2";
|
||||
>_whatever : Symbol(_whatever, Decl(index.ts, 0, 6))
|
||||
|
||||
import { getA } from "typescript-fsa";
|
||||
>getA : Symbol(getA, Decl(index.ts, 1, 8))
|
||||
|
||||
export const a = getA();
|
||||
>a : Symbol(a, Decl(index.ts, 3, 12))
|
||||
>getA : Symbol(getA, Decl(index.ts, 1, 8))
|
||||
|
||||
=== /p2/index.d.ts ===
|
||||
export const a: import("typescript-fsa").A;
|
||||
>a : Symbol(a, Decl(index.d.ts, 0, 12))
|
||||
>A : Symbol(A, Decl(impl.d.ts, 0, 26))
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
=== /cache/typescript-fsa/src/impl.d.ts ===
|
||||
export function getA(): A;
|
||||
>getA : () => A
|
||||
|
||||
export enum A {
|
||||
>A : A
|
||||
|
||||
Val
|
||||
>Val : A
|
||||
}
|
||||
=== /cache/typescript-fsa/index.d.ts ===
|
||||
export * from "./src/impl";
|
||||
No type information for this code.=== /p1/index.ts ===
|
||||
import * as _whatever from "p2";
|
||||
>_whatever : typeof _whatever
|
||||
|
||||
import { getA } from "typescript-fsa";
|
||||
>getA : () => import("/cache/typescript-fsa/index").A
|
||||
|
||||
export const a = getA();
|
||||
>a : import("/cache/typescript-fsa/index").A
|
||||
>getA() : import("/cache/typescript-fsa/index").A
|
||||
>getA : () => import("/cache/typescript-fsa/index").A
|
||||
|
||||
=== /p2/index.d.ts ===
|
||||
export const a: import("typescript-fsa").A;
|
||||
>a : import("/cache/typescript-fsa/index").A
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ var C = /** @class */ (function () {
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
_a = a_1.x;
|
||||
exports.C = C;
|
||||
_a = a_1.x;
|
||||
//// [c.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
@@ -64,8 +64,8 @@ var D = /** @class */ (function (_super) {
|
||||
}
|
||||
return D;
|
||||
}(b_1.C));
|
||||
_a = a_1.x;
|
||||
exports.D = D;
|
||||
_a = a_1.x;
|
||||
|
||||
|
||||
//// [a.d.ts]
|
||||
|
||||
@@ -196,7 +196,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21;
|
||||
var _a, _b, _c, _d;
|
||||
var _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21;
|
||||
function x(o, k) { }
|
||||
let i = 0;
|
||||
function foo() { return ++i + ""; }
|
||||
@@ -209,11 +210,11 @@ class A {
|
||||
this[Symbol.iterator] = null;
|
||||
this["property4"] = 2;
|
||||
this[Symbol.match] = null;
|
||||
this[_b] = null;
|
||||
this[_d] = null;
|
||||
this[_f] = null;
|
||||
this[_h] = null;
|
||||
}
|
||||
}
|
||||
foo(), _a = foo(), _b = foo(), _c = fieldNameB, _d = fieldNameC;
|
||||
foo(), _e = foo(), _f = foo(), _g = fieldNameB, _h = fieldNameC;
|
||||
__decorate([
|
||||
x
|
||||
], A.prototype, "property", void 0);
|
||||
@@ -228,42 +229,42 @@ __decorate([
|
||||
], A.prototype, Symbol.iterator, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], A.prototype, _a, void 0);
|
||||
], A.prototype, _e, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], A.prototype, _b, void 0);
|
||||
], A.prototype, _f, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], A.prototype, _c, void 0);
|
||||
], A.prototype, _g, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], A.prototype, _d, void 0);
|
||||
void (_j = class B {
|
||||
], A.prototype, _h, void 0);
|
||||
void (_a = class B {
|
||||
constructor() {
|
||||
this["property2"] = 2;
|
||||
this[Symbol.iterator] = null;
|
||||
this["property4"] = 2;
|
||||
this[Symbol.match] = null;
|
||||
this[_f] = null;
|
||||
this[_h] = null;
|
||||
this[_k] = null;
|
||||
this[_m] = null;
|
||||
}
|
||||
},
|
||||
foo(),
|
||||
_e = foo(),
|
||||
_f = foo(),
|
||||
_g = fieldNameB,
|
||||
_h = fieldNameC,
|
||||
_j);
|
||||
_j = foo(),
|
||||
_k = foo(),
|
||||
_l = fieldNameB,
|
||||
_m = fieldNameC,
|
||||
_a);
|
||||
class C {
|
||||
constructor() {
|
||||
this["property2"] = 2;
|
||||
this[Symbol.iterator] = null;
|
||||
this["property4"] = 2;
|
||||
this[Symbol.match] = null;
|
||||
this[_l] = null;
|
||||
this[_o] = null;
|
||||
this[_p] = null;
|
||||
this[_r] = null;
|
||||
}
|
||||
[(foo(), _k = foo(), _l = foo(), _m = fieldNameB, _o = fieldNameC, "some" + "method")]() { }
|
||||
[(foo(), _o = foo(), _p = foo(), _q = fieldNameB, _r = fieldNameC, "some" + "method")]() { }
|
||||
}
|
||||
__decorate([
|
||||
x
|
||||
@@ -277,28 +278,28 @@ __decorate([
|
||||
__decorate([
|
||||
x
|
||||
], C.prototype, Symbol.iterator, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], C.prototype, _k, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], C.prototype, _l, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], C.prototype, _m, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], C.prototype, _o, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], C.prototype, _p, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], C.prototype, _q, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], C.prototype, _r, void 0);
|
||||
void class D {
|
||||
constructor() {
|
||||
this["property2"] = 2;
|
||||
this[Symbol.iterator] = null;
|
||||
this["property4"] = 2;
|
||||
this[Symbol.match] = null;
|
||||
this[_q] = null;
|
||||
this[_s] = null;
|
||||
this[_t] = null;
|
||||
this[_v] = null;
|
||||
}
|
||||
[(foo(), _p = foo(), _q = foo(), _r = fieldNameB, _s = fieldNameC, "some" + "method")]() { }
|
||||
[(foo(), _s = foo(), _t = foo(), _u = fieldNameB, _v = fieldNameC, "some" + "method")]() { }
|
||||
};
|
||||
class E {
|
||||
constructor() {
|
||||
@@ -306,12 +307,12 @@ class E {
|
||||
this[Symbol.iterator] = null;
|
||||
this["property4"] = 2;
|
||||
this[Symbol.match] = null;
|
||||
this[_u] = null;
|
||||
this[_w] = null;
|
||||
this[_x] = null;
|
||||
this[_z] = null;
|
||||
}
|
||||
[(foo(), _t = foo(), _u = foo(), "some" + "method")]() { }
|
||||
[(foo(), _w = foo(), _x = foo(), "some" + "method")]() { }
|
||||
}
|
||||
_v = fieldNameB, _w = fieldNameC;
|
||||
_y = fieldNameB, _z = fieldNameC;
|
||||
__decorate([
|
||||
x
|
||||
], E.prototype, "property", void 0);
|
||||
@@ -324,45 +325,45 @@ __decorate([
|
||||
__decorate([
|
||||
x
|
||||
], E.prototype, Symbol.iterator, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], E.prototype, _t, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], E.prototype, _u, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], E.prototype, _v, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], E.prototype, _w, void 0);
|
||||
void (_1 = class F {
|
||||
__decorate([
|
||||
x
|
||||
], E.prototype, _x, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], E.prototype, _y, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], E.prototype, _z, void 0);
|
||||
void (_b = class F {
|
||||
constructor() {
|
||||
this["property2"] = 2;
|
||||
this[Symbol.iterator] = null;
|
||||
this["property4"] = 2;
|
||||
this[Symbol.match] = null;
|
||||
this[_y] = null;
|
||||
this[_0] = null;
|
||||
this[_1] = null;
|
||||
this[_3] = null;
|
||||
}
|
||||
[(foo(), _x = foo(), _y = foo(), "some" + "method")]() { }
|
||||
[(foo(), _0 = foo(), _1 = foo(), "some" + "method")]() { }
|
||||
},
|
||||
_z = fieldNameB,
|
||||
_0 = fieldNameC,
|
||||
_1);
|
||||
_2 = fieldNameB,
|
||||
_3 = fieldNameC,
|
||||
_b);
|
||||
class G {
|
||||
constructor() {
|
||||
this["property2"] = 2;
|
||||
this[Symbol.iterator] = null;
|
||||
this["property4"] = 2;
|
||||
this[Symbol.match] = null;
|
||||
this[_3] = null;
|
||||
this[_5] = null;
|
||||
this[_7] = null;
|
||||
}
|
||||
[(foo(), _2 = foo(), _3 = foo(), "some" + "method")]() { }
|
||||
[(_4 = fieldNameB, "some" + "method2")]() { }
|
||||
[(foo(), _4 = foo(), _5 = foo(), "some" + "method")]() { }
|
||||
[(_6 = fieldNameB, "some" + "method2")]() { }
|
||||
}
|
||||
_5 = fieldNameC;
|
||||
_7 = fieldNameC;
|
||||
__decorate([
|
||||
x
|
||||
], G.prototype, "property", void 0);
|
||||
@@ -375,45 +376,45 @@ __decorate([
|
||||
__decorate([
|
||||
x
|
||||
], G.prototype, Symbol.iterator, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], G.prototype, _2, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], G.prototype, _3, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], G.prototype, _4, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], G.prototype, _5, void 0);
|
||||
void (_10 = class H {
|
||||
__decorate([
|
||||
x
|
||||
], G.prototype, _6, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], G.prototype, _7, void 0);
|
||||
void (_c = class H {
|
||||
constructor() {
|
||||
this["property2"] = 2;
|
||||
this[Symbol.iterator] = null;
|
||||
this["property4"] = 2;
|
||||
this[Symbol.match] = null;
|
||||
this[_7] = null;
|
||||
this[_9] = null;
|
||||
this[_11] = null;
|
||||
}
|
||||
[(foo(), _6 = foo(), _7 = foo(), "some" + "method")]() { }
|
||||
[(_8 = fieldNameB, "some" + "method2")]() { }
|
||||
[(foo(), _8 = foo(), _9 = foo(), "some" + "method")]() { }
|
||||
[(_10 = fieldNameB, "some" + "method2")]() { }
|
||||
},
|
||||
_9 = fieldNameC,
|
||||
_10);
|
||||
_11 = fieldNameC,
|
||||
_c);
|
||||
class I {
|
||||
constructor() {
|
||||
this["property2"] = 2;
|
||||
this[Symbol.iterator] = null;
|
||||
this["property4"] = 2;
|
||||
this[Symbol.match] = null;
|
||||
this[_12] = null;
|
||||
this[_15] = null;
|
||||
this[_13] = null;
|
||||
this[_16] = null;
|
||||
}
|
||||
[(foo(), _11 = foo(), _12 = foo(), _13 = "some" + "method")]() { }
|
||||
[(_14 = fieldNameB, "some" + "method2")]() { }
|
||||
[(foo(), _12 = foo(), _13 = foo(), _14 = "some" + "method")]() { }
|
||||
[(_15 = fieldNameB, "some" + "method2")]() { }
|
||||
}
|
||||
_15 = fieldNameC;
|
||||
_16 = fieldNameC;
|
||||
__decorate([
|
||||
x
|
||||
], I.prototype, "property", void 0);
|
||||
@@ -426,32 +427,32 @@ __decorate([
|
||||
__decorate([
|
||||
x
|
||||
], I.prototype, Symbol.iterator, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], I.prototype, _11, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], I.prototype, _12, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], I.prototype, _13, null);
|
||||
], I.prototype, _13, void 0);
|
||||
__decorate([
|
||||
x
|
||||
], I.prototype, _14, void 0);
|
||||
], I.prototype, _14, null);
|
||||
__decorate([
|
||||
x
|
||||
], I.prototype, _15, void 0);
|
||||
void (_21 = class J {
|
||||
__decorate([
|
||||
x
|
||||
], I.prototype, _16, void 0);
|
||||
void (_d = class J {
|
||||
constructor() {
|
||||
this["property2"] = 2;
|
||||
this[Symbol.iterator] = null;
|
||||
this["property4"] = 2;
|
||||
this[Symbol.match] = null;
|
||||
this[_17] = null;
|
||||
this[_20] = null;
|
||||
this[_18] = null;
|
||||
this[_21] = null;
|
||||
}
|
||||
[(foo(), _16 = foo(), _17 = foo(), _18 = "some" + "method")]() { }
|
||||
[(_19 = fieldNameB, "some" + "method2")]() { }
|
||||
[(foo(), _17 = foo(), _18 = foo(), _19 = "some" + "method")]() { }
|
||||
[(_20 = fieldNameB, "some" + "method2")]() { }
|
||||
},
|
||||
_20 = fieldNameC,
|
||||
_21);
|
||||
_21 = fieldNameC,
|
||||
_d);
|
||||
|
||||
@@ -2,6 +2,34 @@
|
||||
const a: { x?: number } = { };
|
||||
let x = 0;
|
||||
({x = 1} = a);
|
||||
|
||||
// Repro from #26235
|
||||
|
||||
function f1(options?: { color?: string, width?: number }) {
|
||||
let { color, width } = options || {};
|
||||
({ color, width } = options || {});
|
||||
let x1 = (options || {}).color;
|
||||
let x2 = (options || {})["color"];
|
||||
}
|
||||
|
||||
function f2(options?: [string?, number?]) {
|
||||
let [str, num] = options || [];
|
||||
[str, num] = options || [];
|
||||
let x1 = (options || {})[0];
|
||||
}
|
||||
|
||||
function f3(options?: { color: string, width: number }) {
|
||||
let { color, width } = options || {};
|
||||
({ color, width } = options || {});
|
||||
let x1 = (options || {}).color;
|
||||
let x2 = (options || {})["color"];
|
||||
}
|
||||
|
||||
function f4(options?: [string, number]) {
|
||||
let [str, num] = options || [];
|
||||
[str, num] = options || [];
|
||||
let x1 = (options || {})[0];
|
||||
}
|
||||
|
||||
|
||||
//// [destructuringAssignmentWithDefault.js]
|
||||
@@ -9,3 +37,30 @@ var _a;
|
||||
var a = {};
|
||||
var x = 0;
|
||||
(_a = a.x, x = _a === void 0 ? 1 : _a);
|
||||
// Repro from #26235
|
||||
function f1(options) {
|
||||
var _a;
|
||||
var _b = options || {}, color = _b.color, width = _b.width;
|
||||
(_a = options || {}, color = _a.color, width = _a.width);
|
||||
var x1 = (options || {}).color;
|
||||
var x2 = (options || {})["color"];
|
||||
}
|
||||
function f2(options) {
|
||||
var _a;
|
||||
var _b = options || [], str = _b[0], num = _b[1];
|
||||
_a = options || [], str = _a[0], num = _a[1];
|
||||
var x1 = (options || {})[0];
|
||||
}
|
||||
function f3(options) {
|
||||
var _a;
|
||||
var _b = options || {}, color = _b.color, width = _b.width;
|
||||
(_a = options || {}, color = _a.color, width = _a.width);
|
||||
var x1 = (options || {}).color;
|
||||
var x2 = (options || {})["color"];
|
||||
}
|
||||
function f4(options) {
|
||||
var _a;
|
||||
var _b = options || [], str = _b[0], num = _b[1];
|
||||
_a = options || [], str = _a[0], num = _a[1];
|
||||
var x1 = (options || {})[0];
|
||||
}
|
||||
|
||||
@@ -10,3 +10,101 @@ let x = 0;
|
||||
>x : Symbol(x, Decl(destructuringAssignmentWithDefault.ts, 2, 2))
|
||||
>a : Symbol(a, Decl(destructuringAssignmentWithDefault.ts, 0, 5))
|
||||
|
||||
// Repro from #26235
|
||||
|
||||
function f1(options?: { color?: string, width?: number }) {
|
||||
>f1 : Symbol(f1, Decl(destructuringAssignmentWithDefault.ts, 2, 14))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 6, 12))
|
||||
>color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 6, 23))
|
||||
>width : Symbol(width, Decl(destructuringAssignmentWithDefault.ts, 6, 39))
|
||||
|
||||
let { color, width } = options || {};
|
||||
>color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 7, 9))
|
||||
>width : Symbol(width, Decl(destructuringAssignmentWithDefault.ts, 7, 16))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 6, 12))
|
||||
|
||||
({ color, width } = options || {});
|
||||
>color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 8, 6))
|
||||
>width : Symbol(width, Decl(destructuringAssignmentWithDefault.ts, 8, 13))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 6, 12))
|
||||
|
||||
let x1 = (options || {}).color;
|
||||
>x1 : Symbol(x1, Decl(destructuringAssignmentWithDefault.ts, 9, 7))
|
||||
>(options || {}).color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 6, 23))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 6, 12))
|
||||
>color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 6, 23))
|
||||
|
||||
let x2 = (options || {})["color"];
|
||||
>x2 : Symbol(x2, Decl(destructuringAssignmentWithDefault.ts, 10, 7))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 6, 12))
|
||||
>"color" : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 6, 23))
|
||||
}
|
||||
|
||||
function f2(options?: [string?, number?]) {
|
||||
>f2 : Symbol(f2, Decl(destructuringAssignmentWithDefault.ts, 11, 1))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 13, 12))
|
||||
|
||||
let [str, num] = options || [];
|
||||
>str : Symbol(str, Decl(destructuringAssignmentWithDefault.ts, 14, 9))
|
||||
>num : Symbol(num, Decl(destructuringAssignmentWithDefault.ts, 14, 13))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 13, 12))
|
||||
|
||||
[str, num] = options || [];
|
||||
>str : Symbol(str, Decl(destructuringAssignmentWithDefault.ts, 14, 9))
|
||||
>num : Symbol(num, Decl(destructuringAssignmentWithDefault.ts, 14, 13))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 13, 12))
|
||||
|
||||
let x1 = (options || {})[0];
|
||||
>x1 : Symbol(x1, Decl(destructuringAssignmentWithDefault.ts, 16, 7))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 13, 12))
|
||||
>0 : Symbol(0)
|
||||
}
|
||||
|
||||
function f3(options?: { color: string, width: number }) {
|
||||
>f3 : Symbol(f3, Decl(destructuringAssignmentWithDefault.ts, 17, 1))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 19, 12))
|
||||
>color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 19, 23))
|
||||
>width : Symbol(width, Decl(destructuringAssignmentWithDefault.ts, 19, 38))
|
||||
|
||||
let { color, width } = options || {};
|
||||
>color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 20, 9))
|
||||
>width : Symbol(width, Decl(destructuringAssignmentWithDefault.ts, 20, 16))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 19, 12))
|
||||
|
||||
({ color, width } = options || {});
|
||||
>color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 21, 6))
|
||||
>width : Symbol(width, Decl(destructuringAssignmentWithDefault.ts, 21, 13))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 19, 12))
|
||||
|
||||
let x1 = (options || {}).color;
|
||||
>x1 : Symbol(x1, Decl(destructuringAssignmentWithDefault.ts, 22, 7))
|
||||
>(options || {}).color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 19, 23))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 19, 12))
|
||||
>color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 19, 23))
|
||||
|
||||
let x2 = (options || {})["color"];
|
||||
>x2 : Symbol(x2, Decl(destructuringAssignmentWithDefault.ts, 23, 7))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 19, 12))
|
||||
>"color" : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 19, 23))
|
||||
}
|
||||
|
||||
function f4(options?: [string, number]) {
|
||||
>f4 : Symbol(f4, Decl(destructuringAssignmentWithDefault.ts, 24, 1))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 26, 12))
|
||||
|
||||
let [str, num] = options || [];
|
||||
>str : Symbol(str, Decl(destructuringAssignmentWithDefault.ts, 27, 9))
|
||||
>num : Symbol(num, Decl(destructuringAssignmentWithDefault.ts, 27, 13))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 26, 12))
|
||||
|
||||
[str, num] = options || [];
|
||||
>str : Symbol(str, Decl(destructuringAssignmentWithDefault.ts, 27, 9))
|
||||
>num : Symbol(num, Decl(destructuringAssignmentWithDefault.ts, 27, 13))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 26, 12))
|
||||
|
||||
let x1 = (options || {})[0];
|
||||
>x1 : Symbol(x1, Decl(destructuringAssignmentWithDefault.ts, 29, 7))
|
||||
>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 26, 12))
|
||||
>0 : Symbol(0)
|
||||
}
|
||||
|
||||
|
||||
@@ -16,3 +16,149 @@ let x = 0;
|
||||
>1 : 1
|
||||
>a : { x?: number | undefined; }
|
||||
|
||||
// Repro from #26235
|
||||
|
||||
function f1(options?: { color?: string, width?: number }) {
|
||||
>f1 : (options?: { color?: string | undefined; width?: number | undefined; } | undefined) => void
|
||||
>options : { color?: string | undefined; width?: number | undefined; } | undefined
|
||||
>color : string | undefined
|
||||
>width : number | undefined
|
||||
|
||||
let { color, width } = options || {};
|
||||
>color : string | undefined
|
||||
>width : number | undefined
|
||||
>options || {} : { color?: string | undefined; width?: number | undefined; }
|
||||
>options : { color?: string | undefined; width?: number | undefined; } | undefined
|
||||
>{} : {}
|
||||
|
||||
({ color, width } = options || {});
|
||||
>({ color, width } = options || {}) : { color?: string | undefined; width?: number | undefined; }
|
||||
>{ color, width } = options || {} : { color?: string | undefined; width?: number | undefined; }
|
||||
>{ color, width } : { color: string | undefined; width: number | undefined; }
|
||||
>color : string | undefined
|
||||
>width : number | undefined
|
||||
>options || {} : { color?: string | undefined; width?: number | undefined; }
|
||||
>options : { color?: string | undefined; width?: number | undefined; } | undefined
|
||||
>{} : {}
|
||||
|
||||
let x1 = (options || {}).color;
|
||||
>x1 : string | undefined
|
||||
>(options || {}).color : string | undefined
|
||||
>(options || {}) : { color?: string | undefined; width?: number | undefined; }
|
||||
>options || {} : { color?: string | undefined; width?: number | undefined; }
|
||||
>options : { color?: string | undefined; width?: number | undefined; } | undefined
|
||||
>{} : {}
|
||||
>color : string | undefined
|
||||
|
||||
let x2 = (options || {})["color"];
|
||||
>x2 : string | undefined
|
||||
>(options || {})["color"] : string | undefined
|
||||
>(options || {}) : { color?: string | undefined; width?: number | undefined; }
|
||||
>options || {} : { color?: string | undefined; width?: number | undefined; }
|
||||
>options : { color?: string | undefined; width?: number | undefined; } | undefined
|
||||
>{} : {}
|
||||
>"color" : "color"
|
||||
}
|
||||
|
||||
function f2(options?: [string?, number?]) {
|
||||
>f2 : (options?: [(string | undefined)?, (number | undefined)?] | undefined) => void
|
||||
>options : [(string | undefined)?, (number | undefined)?] | undefined
|
||||
|
||||
let [str, num] = options || [];
|
||||
>str : string | undefined
|
||||
>num : number | undefined
|
||||
>options || [] : [(string | undefined)?, (number | undefined)?]
|
||||
>options : [(string | undefined)?, (number | undefined)?] | undefined
|
||||
>[] : []
|
||||
|
||||
[str, num] = options || [];
|
||||
>[str, num] = options || [] : [(string | undefined)?, (number | undefined)?]
|
||||
>[str, num] : [string | undefined, number | undefined]
|
||||
>str : string | undefined
|
||||
>num : number | undefined
|
||||
>options || [] : [(string | undefined)?, (number | undefined)?]
|
||||
>options : [(string | undefined)?, (number | undefined)?] | undefined
|
||||
>[] : []
|
||||
|
||||
let x1 = (options || {})[0];
|
||||
>x1 : string | undefined
|
||||
>(options || {})[0] : string | undefined
|
||||
>(options || {}) : [(string | undefined)?, (number | undefined)?] | {}
|
||||
>options || {} : [(string | undefined)?, (number | undefined)?] | {}
|
||||
>options : [(string | undefined)?, (number | undefined)?] | undefined
|
||||
>{} : {}
|
||||
>0 : 0
|
||||
}
|
||||
|
||||
function f3(options?: { color: string, width: number }) {
|
||||
>f3 : (options?: { color: string; width: number; } | undefined) => void
|
||||
>options : { color: string; width: number; } | undefined
|
||||
>color : string
|
||||
>width : number
|
||||
|
||||
let { color, width } = options || {};
|
||||
>color : string | undefined
|
||||
>width : number | undefined
|
||||
>options || {} : { color: string; width: number; } | {}
|
||||
>options : { color: string; width: number; } | undefined
|
||||
>{} : {}
|
||||
|
||||
({ color, width } = options || {});
|
||||
>({ color, width } = options || {}) : { color: string; width: number; } | {}
|
||||
>{ color, width } = options || {} : { color: string; width: number; } | {}
|
||||
>{ color, width } : { color: string | undefined; width: number | undefined; }
|
||||
>color : string | undefined
|
||||
>width : number | undefined
|
||||
>options || {} : { color: string; width: number; } | {}
|
||||
>options : { color: string; width: number; } | undefined
|
||||
>{} : {}
|
||||
|
||||
let x1 = (options || {}).color;
|
||||
>x1 : string | undefined
|
||||
>(options || {}).color : string | undefined
|
||||
>(options || {}) : { color: string; width: number; } | {}
|
||||
>options || {} : { color: string; width: number; } | {}
|
||||
>options : { color: string; width: number; } | undefined
|
||||
>{} : {}
|
||||
>color : string | undefined
|
||||
|
||||
let x2 = (options || {})["color"];
|
||||
>x2 : string | undefined
|
||||
>(options || {})["color"] : string | undefined
|
||||
>(options || {}) : { color: string; width: number; } | {}
|
||||
>options || {} : { color: string; width: number; } | {}
|
||||
>options : { color: string; width: number; } | undefined
|
||||
>{} : {}
|
||||
>"color" : "color"
|
||||
}
|
||||
|
||||
function f4(options?: [string, number]) {
|
||||
>f4 : (options?: [string, number] | undefined) => void
|
||||
>options : [string, number] | undefined
|
||||
|
||||
let [str, num] = options || [];
|
||||
>str : string | undefined
|
||||
>num : number | undefined
|
||||
>options || [] : [] | [string, number]
|
||||
>options : [string, number] | undefined
|
||||
>[] : []
|
||||
|
||||
[str, num] = options || [];
|
||||
>[str, num] = options || [] : [] | [string, number]
|
||||
>[str, num] : [string | undefined, number | undefined]
|
||||
>str : string | undefined
|
||||
>num : number | undefined
|
||||
>options || [] : [] | [string, number]
|
||||
>options : [string, number] | undefined
|
||||
>[] : []
|
||||
|
||||
let x1 = (options || {})[0];
|
||||
>x1 : string | undefined
|
||||
>(options || {})[0] : string | undefined
|
||||
>(options || {}) : [string, number] | {}
|
||||
>options || {} : [string, number] | {}
|
||||
>options : [string, number] | undefined
|
||||
>{} : {}
|
||||
>0 : 0
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ trans(([b,c]) => 'foo');
|
||||
|
||||
trans(({d: [e,f]}) => 'foo');
|
||||
>trans : Symbol(trans, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 0))
|
||||
>d : Symbol(d)
|
||||
>e : Symbol(e, Decl(fallbackToBindingPatternForTypeInference.ts, 3, 12))
|
||||
>f : Symbol(f, Decl(fallbackToBindingPatternForTypeInference.ts, 3, 14))
|
||||
|
||||
|
||||
@@ -2,8 +2,10 @@ tests/cases/conformance/es2019/globalThisUnknownNoImplicitAny.ts(4,5): error TS2
|
||||
tests/cases/conformance/es2019/globalThisUnknownNoImplicitAny.ts(5,6): error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
|
||||
tests/cases/conformance/es2019/globalThisUnknownNoImplicitAny.ts(6,12): error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
|
||||
tests/cases/conformance/es2019/globalThisUnknownNoImplicitAny.ts(8,5): error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
|
||||
tests/cases/conformance/es2019/globalThisUnknownNoImplicitAny.ts(9,1): error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
|
||||
tests/cases/conformance/es2019/globalThisUnknownNoImplicitAny.ts(10,1): error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
|
||||
tests/cases/conformance/es2019/globalThisUnknownNoImplicitAny.ts(9,1): error TS7053: Element implicitly has an 'any' type because expression of type '"hi"' can't be used to index type 'typeof globalThis'.
|
||||
Property 'hi' does not exist on type 'typeof globalThis'.
|
||||
tests/cases/conformance/es2019/globalThisUnknownNoImplicitAny.ts(10,1): error TS7053: Element implicitly has an 'any' type because expression of type '"hi"' can't be used to index type 'typeof globalThis'.
|
||||
Property 'hi' does not exist on type 'typeof globalThis'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es2019/globalThisUnknownNoImplicitAny.ts (6 errors) ====
|
||||
@@ -25,8 +27,10 @@ tests/cases/conformance/es2019/globalThisUnknownNoImplicitAny.ts(10,1): error TS
|
||||
!!! error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
|
||||
this['hi']
|
||||
~~~~~~~~~~
|
||||
!!! error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hi"' can't be used to index type 'typeof globalThis'.
|
||||
!!! error TS7053: Property 'hi' does not exist on type 'typeof globalThis'.
|
||||
globalThis['hi']
|
||||
~~~~~~~~~~~~~~~~
|
||||
!!! error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hi"' can't be used to index type 'typeof globalThis'.
|
||||
!!! error TS7053: Property 'hi' does not exist on type 'typeof globalThis'.
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
//// [identicalTypesNoDifferByCheckOrder.ts]
|
||||
interface SomeProps {
|
||||
x?: string;
|
||||
y?: number;
|
||||
renderAs?: FunctionComponent1<SomeProps>
|
||||
}
|
||||
|
||||
type SomePropsX = Required<Pick<SomeProps, "x">> & Omit<SomeProps, "x">;
|
||||
|
||||
interface SomePropsClone {
|
||||
x?: string;
|
||||
y?: number;
|
||||
renderAs?: FunctionComponent2<SomeProps>
|
||||
}
|
||||
|
||||
type SomePropsCloneX = Required<Pick<SomePropsClone, "x">> & Omit<SomePropsClone, "x">;
|
||||
|
||||
type Validator<T> = {(): boolean, opt?: T};
|
||||
type WeakValidationMap<T> = {[K in keyof T]?: null extends T[K] ? Validator<T[K] | null | undefined> : Validator<T[K]>};
|
||||
|
||||
interface FunctionComponent1<P> {
|
||||
(props: P & { children?: unknown }): void;
|
||||
propTypes?: WeakValidationMap<P>;
|
||||
}
|
||||
|
||||
interface FunctionComponent2<P> {
|
||||
(props: P & { children?: unknown }): void;
|
||||
propTypes?: WeakValidationMap<P>;
|
||||
}
|
||||
|
||||
function needsComponentOfSomeProps3(...x: SomePropsClone[]): void {}
|
||||
const comp3: FunctionComponent2<SomePropsCloneX> = null as any;
|
||||
needsComponentOfSomeProps3({ renderAs: comp3 });
|
||||
|
||||
function needsComponentOfSomeProps2(...x: SomeProps[]): void {}
|
||||
const comp2: FunctionComponent1<SomePropsX> = null as any;
|
||||
needsComponentOfSomeProps2({ renderAs: comp2 });
|
||||
|
||||
//// [identicalTypesNoDifferByCheckOrder.js]
|
||||
function needsComponentOfSomeProps3() {
|
||||
var x = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
x[_i] = arguments[_i];
|
||||
}
|
||||
}
|
||||
var comp3 = null;
|
||||
needsComponentOfSomeProps3({ renderAs: comp3 });
|
||||
function needsComponentOfSomeProps2() {
|
||||
var x = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
x[_i] = arguments[_i];
|
||||
}
|
||||
}
|
||||
var comp2 = null;
|
||||
needsComponentOfSomeProps2({ renderAs: comp2 });
|
||||
@@ -0,0 +1,127 @@
|
||||
=== tests/cases/compiler/identicalTypesNoDifferByCheckOrder.ts ===
|
||||
interface SomeProps {
|
||||
>SomeProps : Symbol(SomeProps, Decl(identicalTypesNoDifferByCheckOrder.ts, 0, 0))
|
||||
|
||||
x?: string;
|
||||
>x : Symbol(SomeProps.x, Decl(identicalTypesNoDifferByCheckOrder.ts, 0, 21))
|
||||
|
||||
y?: number;
|
||||
>y : Symbol(SomeProps.y, Decl(identicalTypesNoDifferByCheckOrder.ts, 1, 15))
|
||||
|
||||
renderAs?: FunctionComponent1<SomeProps>
|
||||
>renderAs : Symbol(SomeProps.renderAs, Decl(identicalTypesNoDifferByCheckOrder.ts, 2, 15))
|
||||
>FunctionComponent1 : Symbol(FunctionComponent1, Decl(identicalTypesNoDifferByCheckOrder.ts, 17, 120))
|
||||
>SomeProps : Symbol(SomeProps, Decl(identicalTypesNoDifferByCheckOrder.ts, 0, 0))
|
||||
}
|
||||
|
||||
type SomePropsX = Required<Pick<SomeProps, "x">> & Omit<SomeProps, "x">;
|
||||
>SomePropsX : Symbol(SomePropsX, Decl(identicalTypesNoDifferByCheckOrder.ts, 4, 1))
|
||||
>Required : Symbol(Required, Decl(lib.es5.d.ts, --, --))
|
||||
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
|
||||
>SomeProps : Symbol(SomeProps, Decl(identicalTypesNoDifferByCheckOrder.ts, 0, 0))
|
||||
>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --))
|
||||
>SomeProps : Symbol(SomeProps, Decl(identicalTypesNoDifferByCheckOrder.ts, 0, 0))
|
||||
|
||||
interface SomePropsClone {
|
||||
>SomePropsClone : Symbol(SomePropsClone, Decl(identicalTypesNoDifferByCheckOrder.ts, 6, 72))
|
||||
|
||||
x?: string;
|
||||
>x : Symbol(SomePropsClone.x, Decl(identicalTypesNoDifferByCheckOrder.ts, 8, 26))
|
||||
|
||||
y?: number;
|
||||
>y : Symbol(SomePropsClone.y, Decl(identicalTypesNoDifferByCheckOrder.ts, 9, 15))
|
||||
|
||||
renderAs?: FunctionComponent2<SomeProps>
|
||||
>renderAs : Symbol(SomePropsClone.renderAs, Decl(identicalTypesNoDifferByCheckOrder.ts, 10, 15))
|
||||
>FunctionComponent2 : Symbol(FunctionComponent2, Decl(identicalTypesNoDifferByCheckOrder.ts, 22, 1))
|
||||
>SomeProps : Symbol(SomeProps, Decl(identicalTypesNoDifferByCheckOrder.ts, 0, 0))
|
||||
}
|
||||
|
||||
type SomePropsCloneX = Required<Pick<SomePropsClone, "x">> & Omit<SomePropsClone, "x">;
|
||||
>SomePropsCloneX : Symbol(SomePropsCloneX, Decl(identicalTypesNoDifferByCheckOrder.ts, 12, 1))
|
||||
>Required : Symbol(Required, Decl(lib.es5.d.ts, --, --))
|
||||
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
|
||||
>SomePropsClone : Symbol(SomePropsClone, Decl(identicalTypesNoDifferByCheckOrder.ts, 6, 72))
|
||||
>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --))
|
||||
>SomePropsClone : Symbol(SomePropsClone, Decl(identicalTypesNoDifferByCheckOrder.ts, 6, 72))
|
||||
|
||||
type Validator<T> = {(): boolean, opt?: T};
|
||||
>Validator : Symbol(Validator, Decl(identicalTypesNoDifferByCheckOrder.ts, 14, 87))
|
||||
>T : Symbol(T, Decl(identicalTypesNoDifferByCheckOrder.ts, 16, 15))
|
||||
>opt : Symbol(opt, Decl(identicalTypesNoDifferByCheckOrder.ts, 16, 33))
|
||||
>T : Symbol(T, Decl(identicalTypesNoDifferByCheckOrder.ts, 16, 15))
|
||||
|
||||
type WeakValidationMap<T> = {[K in keyof T]?: null extends T[K] ? Validator<T[K] | null | undefined> : Validator<T[K]>};
|
||||
>WeakValidationMap : Symbol(WeakValidationMap, Decl(identicalTypesNoDifferByCheckOrder.ts, 16, 43))
|
||||
>T : Symbol(T, Decl(identicalTypesNoDifferByCheckOrder.ts, 17, 23))
|
||||
>K : Symbol(K, Decl(identicalTypesNoDifferByCheckOrder.ts, 17, 30))
|
||||
>T : Symbol(T, Decl(identicalTypesNoDifferByCheckOrder.ts, 17, 23))
|
||||
>T : Symbol(T, Decl(identicalTypesNoDifferByCheckOrder.ts, 17, 23))
|
||||
>K : Symbol(K, Decl(identicalTypesNoDifferByCheckOrder.ts, 17, 30))
|
||||
>Validator : Symbol(Validator, Decl(identicalTypesNoDifferByCheckOrder.ts, 14, 87))
|
||||
>T : Symbol(T, Decl(identicalTypesNoDifferByCheckOrder.ts, 17, 23))
|
||||
>K : Symbol(K, Decl(identicalTypesNoDifferByCheckOrder.ts, 17, 30))
|
||||
>Validator : Symbol(Validator, Decl(identicalTypesNoDifferByCheckOrder.ts, 14, 87))
|
||||
>T : Symbol(T, Decl(identicalTypesNoDifferByCheckOrder.ts, 17, 23))
|
||||
>K : Symbol(K, Decl(identicalTypesNoDifferByCheckOrder.ts, 17, 30))
|
||||
|
||||
interface FunctionComponent1<P> {
|
||||
>FunctionComponent1 : Symbol(FunctionComponent1, Decl(identicalTypesNoDifferByCheckOrder.ts, 17, 120))
|
||||
>P : Symbol(P, Decl(identicalTypesNoDifferByCheckOrder.ts, 19, 29))
|
||||
|
||||
(props: P & { children?: unknown }): void;
|
||||
>props : Symbol(props, Decl(identicalTypesNoDifferByCheckOrder.ts, 20, 5))
|
||||
>P : Symbol(P, Decl(identicalTypesNoDifferByCheckOrder.ts, 19, 29))
|
||||
>children : Symbol(children, Decl(identicalTypesNoDifferByCheckOrder.ts, 20, 17))
|
||||
|
||||
propTypes?: WeakValidationMap<P>;
|
||||
>propTypes : Symbol(FunctionComponent1.propTypes, Decl(identicalTypesNoDifferByCheckOrder.ts, 20, 46))
|
||||
>WeakValidationMap : Symbol(WeakValidationMap, Decl(identicalTypesNoDifferByCheckOrder.ts, 16, 43))
|
||||
>P : Symbol(P, Decl(identicalTypesNoDifferByCheckOrder.ts, 19, 29))
|
||||
}
|
||||
|
||||
interface FunctionComponent2<P> {
|
||||
>FunctionComponent2 : Symbol(FunctionComponent2, Decl(identicalTypesNoDifferByCheckOrder.ts, 22, 1))
|
||||
>P : Symbol(P, Decl(identicalTypesNoDifferByCheckOrder.ts, 24, 29))
|
||||
|
||||
(props: P & { children?: unknown }): void;
|
||||
>props : Symbol(props, Decl(identicalTypesNoDifferByCheckOrder.ts, 25, 5))
|
||||
>P : Symbol(P, Decl(identicalTypesNoDifferByCheckOrder.ts, 24, 29))
|
||||
>children : Symbol(children, Decl(identicalTypesNoDifferByCheckOrder.ts, 25, 17))
|
||||
|
||||
propTypes?: WeakValidationMap<P>;
|
||||
>propTypes : Symbol(FunctionComponent2.propTypes, Decl(identicalTypesNoDifferByCheckOrder.ts, 25, 46))
|
||||
>WeakValidationMap : Symbol(WeakValidationMap, Decl(identicalTypesNoDifferByCheckOrder.ts, 16, 43))
|
||||
>P : Symbol(P, Decl(identicalTypesNoDifferByCheckOrder.ts, 24, 29))
|
||||
}
|
||||
|
||||
function needsComponentOfSomeProps3(...x: SomePropsClone[]): void {}
|
||||
>needsComponentOfSomeProps3 : Symbol(needsComponentOfSomeProps3, Decl(identicalTypesNoDifferByCheckOrder.ts, 27, 1))
|
||||
>x : Symbol(x, Decl(identicalTypesNoDifferByCheckOrder.ts, 29, 36))
|
||||
>SomePropsClone : Symbol(SomePropsClone, Decl(identicalTypesNoDifferByCheckOrder.ts, 6, 72))
|
||||
|
||||
const comp3: FunctionComponent2<SomePropsCloneX> = null as any;
|
||||
>comp3 : Symbol(comp3, Decl(identicalTypesNoDifferByCheckOrder.ts, 30, 5))
|
||||
>FunctionComponent2 : Symbol(FunctionComponent2, Decl(identicalTypesNoDifferByCheckOrder.ts, 22, 1))
|
||||
>SomePropsCloneX : Symbol(SomePropsCloneX, Decl(identicalTypesNoDifferByCheckOrder.ts, 12, 1))
|
||||
|
||||
needsComponentOfSomeProps3({ renderAs: comp3 });
|
||||
>needsComponentOfSomeProps3 : Symbol(needsComponentOfSomeProps3, Decl(identicalTypesNoDifferByCheckOrder.ts, 27, 1))
|
||||
>renderAs : Symbol(renderAs, Decl(identicalTypesNoDifferByCheckOrder.ts, 31, 28))
|
||||
>comp3 : Symbol(comp3, Decl(identicalTypesNoDifferByCheckOrder.ts, 30, 5))
|
||||
|
||||
function needsComponentOfSomeProps2(...x: SomeProps[]): void {}
|
||||
>needsComponentOfSomeProps2 : Symbol(needsComponentOfSomeProps2, Decl(identicalTypesNoDifferByCheckOrder.ts, 31, 48))
|
||||
>x : Symbol(x, Decl(identicalTypesNoDifferByCheckOrder.ts, 33, 36))
|
||||
>SomeProps : Symbol(SomeProps, Decl(identicalTypesNoDifferByCheckOrder.ts, 0, 0))
|
||||
|
||||
const comp2: FunctionComponent1<SomePropsX> = null as any;
|
||||
>comp2 : Symbol(comp2, Decl(identicalTypesNoDifferByCheckOrder.ts, 34, 5))
|
||||
>FunctionComponent1 : Symbol(FunctionComponent1, Decl(identicalTypesNoDifferByCheckOrder.ts, 17, 120))
|
||||
>SomePropsX : Symbol(SomePropsX, Decl(identicalTypesNoDifferByCheckOrder.ts, 4, 1))
|
||||
|
||||
needsComponentOfSomeProps2({ renderAs: comp2 });
|
||||
>needsComponentOfSomeProps2 : Symbol(needsComponentOfSomeProps2, Decl(identicalTypesNoDifferByCheckOrder.ts, 31, 48))
|
||||
>renderAs : Symbol(renderAs, Decl(identicalTypesNoDifferByCheckOrder.ts, 35, 28))
|
||||
>comp2 : Symbol(comp2, Decl(identicalTypesNoDifferByCheckOrder.ts, 34, 5))
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
=== tests/cases/compiler/identicalTypesNoDifferByCheckOrder.ts ===
|
||||
interface SomeProps {
|
||||
x?: string;
|
||||
>x : string | undefined
|
||||
|
||||
y?: number;
|
||||
>y : number | undefined
|
||||
|
||||
renderAs?: FunctionComponent1<SomeProps>
|
||||
>renderAs : FunctionComponent1<SomeProps> | undefined
|
||||
}
|
||||
|
||||
type SomePropsX = Required<Pick<SomeProps, "x">> & Omit<SomeProps, "x">;
|
||||
>SomePropsX : SomePropsX
|
||||
|
||||
interface SomePropsClone {
|
||||
x?: string;
|
||||
>x : string | undefined
|
||||
|
||||
y?: number;
|
||||
>y : number | undefined
|
||||
|
||||
renderAs?: FunctionComponent2<SomeProps>
|
||||
>renderAs : FunctionComponent2<SomeProps> | undefined
|
||||
}
|
||||
|
||||
type SomePropsCloneX = Required<Pick<SomePropsClone, "x">> & Omit<SomePropsClone, "x">;
|
||||
>SomePropsCloneX : SomePropsCloneX
|
||||
|
||||
type Validator<T> = {(): boolean, opt?: T};
|
||||
>Validator : Validator<T>
|
||||
>opt : T | undefined
|
||||
|
||||
type WeakValidationMap<T> = {[K in keyof T]?: null extends T[K] ? Validator<T[K] | null | undefined> : Validator<T[K]>};
|
||||
>WeakValidationMap : WeakValidationMap<T>
|
||||
>null : null
|
||||
>null : null
|
||||
|
||||
interface FunctionComponent1<P> {
|
||||
(props: P & { children?: unknown }): void;
|
||||
>props : P & { children?: unknown; }
|
||||
>children : unknown
|
||||
|
||||
propTypes?: WeakValidationMap<P>;
|
||||
>propTypes : WeakValidationMap<P> | undefined
|
||||
}
|
||||
|
||||
interface FunctionComponent2<P> {
|
||||
(props: P & { children?: unknown }): void;
|
||||
>props : P & { children?: unknown; }
|
||||
>children : unknown
|
||||
|
||||
propTypes?: WeakValidationMap<P>;
|
||||
>propTypes : WeakValidationMap<P> | undefined
|
||||
}
|
||||
|
||||
function needsComponentOfSomeProps3(...x: SomePropsClone[]): void {}
|
||||
>needsComponentOfSomeProps3 : (...x: SomePropsClone[]) => void
|
||||
>x : SomePropsClone[]
|
||||
|
||||
const comp3: FunctionComponent2<SomePropsCloneX> = null as any;
|
||||
>comp3 : FunctionComponent2<SomePropsCloneX>
|
||||
>null as any : any
|
||||
>null : null
|
||||
|
||||
needsComponentOfSomeProps3({ renderAs: comp3 });
|
||||
>needsComponentOfSomeProps3({ renderAs: comp3 }) : void
|
||||
>needsComponentOfSomeProps3 : (...x: SomePropsClone[]) => void
|
||||
>{ renderAs: comp3 } : { renderAs: FunctionComponent2<SomePropsCloneX>; }
|
||||
>renderAs : FunctionComponent2<SomePropsCloneX>
|
||||
>comp3 : FunctionComponent2<SomePropsCloneX>
|
||||
|
||||
function needsComponentOfSomeProps2(...x: SomeProps[]): void {}
|
||||
>needsComponentOfSomeProps2 : (...x: SomeProps[]) => void
|
||||
>x : SomeProps[]
|
||||
|
||||
const comp2: FunctionComponent1<SomePropsX> = null as any;
|
||||
>comp2 : FunctionComponent1<SomePropsX>
|
||||
>null as any : any
|
||||
>null : null
|
||||
|
||||
needsComponentOfSomeProps2({ renderAs: comp2 });
|
||||
>needsComponentOfSomeProps2({ renderAs: comp2 }) : void
|
||||
>needsComponentOfSomeProps2 : (...x: SomeProps[]) => void
|
||||
>{ renderAs: comp2 } : { renderAs: FunctionComponent1<SomePropsX>; }
|
||||
>renderAs : FunctionComponent1<SomePropsX>
|
||||
>comp2 : FunctionComponent1<SomePropsX>
|
||||
|
||||
@@ -44,6 +44,18 @@ function f4() {
|
||||
const v3 = getNumberIndexValue(o1);
|
||||
const v4 = getNumberIndexValue(o2);
|
||||
}
|
||||
|
||||
function f5() {
|
||||
enum E1 { A, B }
|
||||
enum E2 { A = "A", B = "B" }
|
||||
enum E3 { A = 0, B = "B" }
|
||||
const v1 = getStringIndexValue(E1);
|
||||
const v2 = getStringIndexValue(E2);
|
||||
const v3 = getStringIndexValue(E3);
|
||||
const v4 = getNumberIndexValue(E1);
|
||||
const v5 = getNumberIndexValue(E2);
|
||||
const v6 = getNumberIndexValue(E3);
|
||||
}
|
||||
|
||||
|
||||
//// [implicitIndexSignatures.js]
|
||||
@@ -83,3 +95,26 @@ function f4() {
|
||||
var v3 = getNumberIndexValue(o1);
|
||||
var v4 = getNumberIndexValue(o2);
|
||||
}
|
||||
function f5() {
|
||||
var E1;
|
||||
(function (E1) {
|
||||
E1[E1["A"] = 0] = "A";
|
||||
E1[E1["B"] = 1] = "B";
|
||||
})(E1 || (E1 = {}));
|
||||
var E2;
|
||||
(function (E2) {
|
||||
E2["A"] = "A";
|
||||
E2["B"] = "B";
|
||||
})(E2 || (E2 = {}));
|
||||
var E3;
|
||||
(function (E3) {
|
||||
E3[E3["A"] = 0] = "A";
|
||||
E3["B"] = "B";
|
||||
})(E3 || (E3 = {}));
|
||||
var v1 = getStringIndexValue(E1);
|
||||
var v2 = getStringIndexValue(E2);
|
||||
var v3 = getStringIndexValue(E3);
|
||||
var v4 = getNumberIndexValue(E1);
|
||||
var v5 = getNumberIndexValue(E2);
|
||||
var v6 = getNumberIndexValue(E3);
|
||||
}
|
||||
|
||||
@@ -168,3 +168,52 @@ function f4() {
|
||||
>o2 : Symbol(o2, Decl(implicitIndexSignatures.ts, 39, 7))
|
||||
}
|
||||
|
||||
function f5() {
|
||||
>f5 : Symbol(f5, Decl(implicitIndexSignatures.ts, 44, 1))
|
||||
|
||||
enum E1 { A, B }
|
||||
>E1 : Symbol(E1, Decl(implicitIndexSignatures.ts, 46, 15))
|
||||
>A : Symbol(E1.A, Decl(implicitIndexSignatures.ts, 47, 13))
|
||||
>B : Symbol(E1.B, Decl(implicitIndexSignatures.ts, 47, 16))
|
||||
|
||||
enum E2 { A = "A", B = "B" }
|
||||
>E2 : Symbol(E2, Decl(implicitIndexSignatures.ts, 47, 20))
|
||||
>A : Symbol(E2.A, Decl(implicitIndexSignatures.ts, 48, 13))
|
||||
>B : Symbol(E2.B, Decl(implicitIndexSignatures.ts, 48, 22))
|
||||
|
||||
enum E3 { A = 0, B = "B" }
|
||||
>E3 : Symbol(E3, Decl(implicitIndexSignatures.ts, 48, 32))
|
||||
>A : Symbol(E3.A, Decl(implicitIndexSignatures.ts, 49, 13))
|
||||
>B : Symbol(E3.B, Decl(implicitIndexSignatures.ts, 49, 20))
|
||||
|
||||
const v1 = getStringIndexValue(E1);
|
||||
>v1 : Symbol(v1, Decl(implicitIndexSignatures.ts, 50, 9))
|
||||
>getStringIndexValue : Symbol(getStringIndexValue, Decl(implicitIndexSignatures.ts, 11, 13))
|
||||
>E1 : Symbol(E1, Decl(implicitIndexSignatures.ts, 46, 15))
|
||||
|
||||
const v2 = getStringIndexValue(E2);
|
||||
>v2 : Symbol(v2, Decl(implicitIndexSignatures.ts, 51, 9))
|
||||
>getStringIndexValue : Symbol(getStringIndexValue, Decl(implicitIndexSignatures.ts, 11, 13))
|
||||
>E2 : Symbol(E2, Decl(implicitIndexSignatures.ts, 47, 20))
|
||||
|
||||
const v3 = getStringIndexValue(E3);
|
||||
>v3 : Symbol(v3, Decl(implicitIndexSignatures.ts, 52, 9))
|
||||
>getStringIndexValue : Symbol(getStringIndexValue, Decl(implicitIndexSignatures.ts, 11, 13))
|
||||
>E3 : Symbol(E3, Decl(implicitIndexSignatures.ts, 48, 32))
|
||||
|
||||
const v4 = getNumberIndexValue(E1);
|
||||
>v4 : Symbol(v4, Decl(implicitIndexSignatures.ts, 53, 9))
|
||||
>getNumberIndexValue : Symbol(getNumberIndexValue, Decl(implicitIndexSignatures.ts, 13, 68))
|
||||
>E1 : Symbol(E1, Decl(implicitIndexSignatures.ts, 46, 15))
|
||||
|
||||
const v5 = getNumberIndexValue(E2);
|
||||
>v5 : Symbol(v5, Decl(implicitIndexSignatures.ts, 54, 9))
|
||||
>getNumberIndexValue : Symbol(getNumberIndexValue, Decl(implicitIndexSignatures.ts, 13, 68))
|
||||
>E2 : Symbol(E2, Decl(implicitIndexSignatures.ts, 47, 20))
|
||||
|
||||
const v6 = getNumberIndexValue(E3);
|
||||
>v6 : Symbol(v6, Decl(implicitIndexSignatures.ts, 55, 9))
|
||||
>getNumberIndexValue : Symbol(getNumberIndexValue, Decl(implicitIndexSignatures.ts, 13, 68))
|
||||
>E3 : Symbol(E3, Decl(implicitIndexSignatures.ts, 48, 32))
|
||||
}
|
||||
|
||||
|
||||
@@ -196,3 +196,62 @@ function f4() {
|
||||
>o2 : { 0: string; 1: string; count: number; }
|
||||
}
|
||||
|
||||
function f5() {
|
||||
>f5 : () => void
|
||||
|
||||
enum E1 { A, B }
|
||||
>E1 : E1
|
||||
>A : E1.A
|
||||
>B : E1.B
|
||||
|
||||
enum E2 { A = "A", B = "B" }
|
||||
>E2 : E2
|
||||
>A : E2.A
|
||||
>"A" : "A"
|
||||
>B : E2.B
|
||||
>"B" : "B"
|
||||
|
||||
enum E3 { A = 0, B = "B" }
|
||||
>E3 : E3
|
||||
>A : E3.A
|
||||
>0 : 0
|
||||
>B : E3.B
|
||||
>"B" : "B"
|
||||
|
||||
const v1 = getStringIndexValue(E1);
|
||||
>v1 : string | E1
|
||||
>getStringIndexValue(E1) : string | E1
|
||||
>getStringIndexValue : <T>(map: { [x: string]: T; }) => T
|
||||
>E1 : typeof E1
|
||||
|
||||
const v2 = getStringIndexValue(E2);
|
||||
>v2 : E2
|
||||
>getStringIndexValue(E2) : E2
|
||||
>getStringIndexValue : <T>(map: { [x: string]: T; }) => T
|
||||
>E2 : typeof E2
|
||||
|
||||
const v3 = getStringIndexValue(E3);
|
||||
>v3 : string | E3.A
|
||||
>getStringIndexValue(E3) : string | E3.A
|
||||
>getStringIndexValue : <T>(map: { [x: string]: T; }) => T
|
||||
>E3 : typeof E3
|
||||
|
||||
const v4 = getNumberIndexValue(E1);
|
||||
>v4 : string
|
||||
>getNumberIndexValue(E1) : string
|
||||
>getNumberIndexValue : <T>(map: { [x: number]: T; }) => T
|
||||
>E1 : typeof E1
|
||||
|
||||
const v5 = getNumberIndexValue(E2);
|
||||
>v5 : unknown
|
||||
>getNumberIndexValue(E2) : unknown
|
||||
>getNumberIndexValue : <T>(map: { [x: number]: T; }) => T
|
||||
>E2 : typeof E2
|
||||
|
||||
const v6 = getNumberIndexValue(E3);
|
||||
>v6 : string
|
||||
>getNumberIndexValue(E3) : string
|
||||
>getNumberIndexValue : <T>(map: { [x: number]: T; }) => T
|
||||
>E3 : typeof E3
|
||||
}
|
||||
|
||||
|
||||
@@ -200,4 +200,23 @@ tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts(180,26): error TS23
|
||||
!!! error TS2322: Types of property 'state' are incompatible.
|
||||
!!! error TS2322: Type 'State.B' is not assignable to type 'State.A'.
|
||||
!!! related TS6502 tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts:179:28: The expected type comes from the return type of this signature.
|
||||
|
||||
// Repros from #31443
|
||||
|
||||
enum Enum { A, B }
|
||||
|
||||
class ClassWithConvert<T> {
|
||||
constructor(val: T) { }
|
||||
convert(converter: { to: (v: T) => T; }) { }
|
||||
}
|
||||
|
||||
function fn<T>(arg: ClassWithConvert<T>, f: () => ClassWithConvert<T>) { }
|
||||
fn(new ClassWithConvert(Enum.A), () => new ClassWithConvert(Enum.A));
|
||||
|
||||
type Func<T> = (x: T) => T;
|
||||
|
||||
declare function makeFoo<T>(x: T): Func<T>;
|
||||
declare function baz<U>(x: Func<U>, y: Func<U>): void;
|
||||
|
||||
baz(makeFoo(Enum.A), makeFoo(Enum.A));
|
||||
|
||||
@@ -179,6 +179,25 @@ enum State { A, B }
|
||||
type Foo = { state: State }
|
||||
declare function bar<T>(f: () => T[]): T[];
|
||||
let x: Foo[] = bar(() => !!true ? [{ state: State.A }] : [{ state: State.B }]); // Error
|
||||
|
||||
// Repros from #31443
|
||||
|
||||
enum Enum { A, B }
|
||||
|
||||
class ClassWithConvert<T> {
|
||||
constructor(val: T) { }
|
||||
convert(converter: { to: (v: T) => T; }) { }
|
||||
}
|
||||
|
||||
function fn<T>(arg: ClassWithConvert<T>, f: () => ClassWithConvert<T>) { }
|
||||
fn(new ClassWithConvert(Enum.A), () => new ClassWithConvert(Enum.A));
|
||||
|
||||
type Func<T> = (x: T) => T;
|
||||
|
||||
declare function makeFoo<T>(x: T): Func<T>;
|
||||
declare function baz<U>(x: Func<U>, y: Func<U>): void;
|
||||
|
||||
baz(makeFoo(Enum.A), makeFoo(Enum.A));
|
||||
|
||||
|
||||
//// [inferFromGenericFunctionReturnTypes3.js]
|
||||
@@ -278,6 +297,19 @@ var State;
|
||||
State[State["B"] = 1] = "B";
|
||||
})(State || (State = {}));
|
||||
let x = bar(() => !!true ? [{ state: State.A }] : [{ state: State.B }]); // Error
|
||||
// Repros from #31443
|
||||
var Enum;
|
||||
(function (Enum) {
|
||||
Enum[Enum["A"] = 0] = "A";
|
||||
Enum[Enum["B"] = 1] = "B";
|
||||
})(Enum || (Enum = {}));
|
||||
class ClassWithConvert {
|
||||
constructor(val) { }
|
||||
convert(converter) { }
|
||||
}
|
||||
function fn(arg, f) { }
|
||||
fn(new ClassWithConvert(Enum.A), () => new ClassWithConvert(Enum.A));
|
||||
baz(makeFoo(Enum.A), makeFoo(Enum.A));
|
||||
|
||||
|
||||
//// [inferFromGenericFunctionReturnTypes3.d.ts]
|
||||
|
||||
@@ -459,3 +459,84 @@ let x: Foo[] = bar(() => !!true ? [{ state: State.A }] : [{ state: State.B }]);
|
||||
>State : Symbol(State, Decl(inferFromGenericFunctionReturnTypes3.ts, 174, 56))
|
||||
>B : Symbol(State.B, Decl(inferFromGenericFunctionReturnTypes3.ts, 176, 15))
|
||||
|
||||
// Repros from #31443
|
||||
|
||||
enum Enum { A, B }
|
||||
>Enum : Symbol(Enum, Decl(inferFromGenericFunctionReturnTypes3.ts, 179, 79))
|
||||
>A : Symbol(Enum.A, Decl(inferFromGenericFunctionReturnTypes3.ts, 183, 11))
|
||||
>B : Symbol(Enum.B, Decl(inferFromGenericFunctionReturnTypes3.ts, 183, 14))
|
||||
|
||||
class ClassWithConvert<T> {
|
||||
>ClassWithConvert : Symbol(ClassWithConvert, Decl(inferFromGenericFunctionReturnTypes3.ts, 183, 18))
|
||||
>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 185, 23))
|
||||
|
||||
constructor(val: T) { }
|
||||
>val : Symbol(val, Decl(inferFromGenericFunctionReturnTypes3.ts, 186, 14))
|
||||
>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 185, 23))
|
||||
|
||||
convert(converter: { to: (v: T) => T; }) { }
|
||||
>convert : Symbol(ClassWithConvert.convert, Decl(inferFromGenericFunctionReturnTypes3.ts, 186, 25))
|
||||
>converter : Symbol(converter, Decl(inferFromGenericFunctionReturnTypes3.ts, 187, 10))
|
||||
>to : Symbol(to, Decl(inferFromGenericFunctionReturnTypes3.ts, 187, 22))
|
||||
>v : Symbol(v, Decl(inferFromGenericFunctionReturnTypes3.ts, 187, 28))
|
||||
>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 185, 23))
|
||||
>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 185, 23))
|
||||
}
|
||||
|
||||
function fn<T>(arg: ClassWithConvert<T>, f: () => ClassWithConvert<T>) { }
|
||||
>fn : Symbol(fn, Decl(inferFromGenericFunctionReturnTypes3.ts, 188, 1))
|
||||
>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 190, 12))
|
||||
>arg : Symbol(arg, Decl(inferFromGenericFunctionReturnTypes3.ts, 190, 15))
|
||||
>ClassWithConvert : Symbol(ClassWithConvert, Decl(inferFromGenericFunctionReturnTypes3.ts, 183, 18))
|
||||
>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 190, 12))
|
||||
>f : Symbol(f, Decl(inferFromGenericFunctionReturnTypes3.ts, 190, 40))
|
||||
>ClassWithConvert : Symbol(ClassWithConvert, Decl(inferFromGenericFunctionReturnTypes3.ts, 183, 18))
|
||||
>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 190, 12))
|
||||
|
||||
fn(new ClassWithConvert(Enum.A), () => new ClassWithConvert(Enum.A));
|
||||
>fn : Symbol(fn, Decl(inferFromGenericFunctionReturnTypes3.ts, 188, 1))
|
||||
>ClassWithConvert : Symbol(ClassWithConvert, Decl(inferFromGenericFunctionReturnTypes3.ts, 183, 18))
|
||||
>Enum.A : Symbol(Enum.A, Decl(inferFromGenericFunctionReturnTypes3.ts, 183, 11))
|
||||
>Enum : Symbol(Enum, Decl(inferFromGenericFunctionReturnTypes3.ts, 179, 79))
|
||||
>A : Symbol(Enum.A, Decl(inferFromGenericFunctionReturnTypes3.ts, 183, 11))
|
||||
>ClassWithConvert : Symbol(ClassWithConvert, Decl(inferFromGenericFunctionReturnTypes3.ts, 183, 18))
|
||||
>Enum.A : Symbol(Enum.A, Decl(inferFromGenericFunctionReturnTypes3.ts, 183, 11))
|
||||
>Enum : Symbol(Enum, Decl(inferFromGenericFunctionReturnTypes3.ts, 179, 79))
|
||||
>A : Symbol(Enum.A, Decl(inferFromGenericFunctionReturnTypes3.ts, 183, 11))
|
||||
|
||||
type Func<T> = (x: T) => T;
|
||||
>Func : Symbol(Func, Decl(inferFromGenericFunctionReturnTypes3.ts, 191, 69))
|
||||
>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 193, 10))
|
||||
>x : Symbol(x, Decl(inferFromGenericFunctionReturnTypes3.ts, 193, 16))
|
||||
>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 193, 10))
|
||||
>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 193, 10))
|
||||
|
||||
declare function makeFoo<T>(x: T): Func<T>;
|
||||
>makeFoo : Symbol(makeFoo, Decl(inferFromGenericFunctionReturnTypes3.ts, 193, 27))
|
||||
>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 195, 25))
|
||||
>x : Symbol(x, Decl(inferFromGenericFunctionReturnTypes3.ts, 195, 28))
|
||||
>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 195, 25))
|
||||
>Func : Symbol(Func, Decl(inferFromGenericFunctionReturnTypes3.ts, 191, 69))
|
||||
>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 195, 25))
|
||||
|
||||
declare function baz<U>(x: Func<U>, y: Func<U>): void;
|
||||
>baz : Symbol(baz, Decl(inferFromGenericFunctionReturnTypes3.ts, 195, 43))
|
||||
>U : Symbol(U, Decl(inferFromGenericFunctionReturnTypes3.ts, 196, 21))
|
||||
>x : Symbol(x, Decl(inferFromGenericFunctionReturnTypes3.ts, 196, 24))
|
||||
>Func : Symbol(Func, Decl(inferFromGenericFunctionReturnTypes3.ts, 191, 69))
|
||||
>U : Symbol(U, Decl(inferFromGenericFunctionReturnTypes3.ts, 196, 21))
|
||||
>y : Symbol(y, Decl(inferFromGenericFunctionReturnTypes3.ts, 196, 35))
|
||||
>Func : Symbol(Func, Decl(inferFromGenericFunctionReturnTypes3.ts, 191, 69))
|
||||
>U : Symbol(U, Decl(inferFromGenericFunctionReturnTypes3.ts, 196, 21))
|
||||
|
||||
baz(makeFoo(Enum.A), makeFoo(Enum.A));
|
||||
>baz : Symbol(baz, Decl(inferFromGenericFunctionReturnTypes3.ts, 195, 43))
|
||||
>makeFoo : Symbol(makeFoo, Decl(inferFromGenericFunctionReturnTypes3.ts, 193, 27))
|
||||
>Enum.A : Symbol(Enum.A, Decl(inferFromGenericFunctionReturnTypes3.ts, 183, 11))
|
||||
>Enum : Symbol(Enum, Decl(inferFromGenericFunctionReturnTypes3.ts, 179, 79))
|
||||
>A : Symbol(Enum.A, Decl(inferFromGenericFunctionReturnTypes3.ts, 183, 11))
|
||||
>makeFoo : Symbol(makeFoo, Decl(inferFromGenericFunctionReturnTypes3.ts, 193, 27))
|
||||
>Enum.A : Symbol(Enum.A, Decl(inferFromGenericFunctionReturnTypes3.ts, 183, 11))
|
||||
>Enum : Symbol(Enum, Decl(inferFromGenericFunctionReturnTypes3.ts, 179, 79))
|
||||
>A : Symbol(Enum.A, Decl(inferFromGenericFunctionReturnTypes3.ts, 183, 11))
|
||||
|
||||
|
||||
@@ -506,3 +506,70 @@ let x: Foo[] = bar(() => !!true ? [{ state: State.A }] : [{ state: State.B }]);
|
||||
>State : typeof State
|
||||
>B : State.B
|
||||
|
||||
// Repros from #31443
|
||||
|
||||
enum Enum { A, B }
|
||||
>Enum : Enum
|
||||
>A : Enum.A
|
||||
>B : Enum.B
|
||||
|
||||
class ClassWithConvert<T> {
|
||||
>ClassWithConvert : ClassWithConvert<T>
|
||||
|
||||
constructor(val: T) { }
|
||||
>val : T
|
||||
|
||||
convert(converter: { to: (v: T) => T; }) { }
|
||||
>convert : (converter: { to: (v: T) => T; }) => void
|
||||
>converter : { to: (v: T) => T; }
|
||||
>to : (v: T) => T
|
||||
>v : T
|
||||
}
|
||||
|
||||
function fn<T>(arg: ClassWithConvert<T>, f: () => ClassWithConvert<T>) { }
|
||||
>fn : <T>(arg: ClassWithConvert<T>, f: () => ClassWithConvert<T>) => void
|
||||
>arg : ClassWithConvert<T>
|
||||
>f : () => ClassWithConvert<T>
|
||||
|
||||
fn(new ClassWithConvert(Enum.A), () => new ClassWithConvert(Enum.A));
|
||||
>fn(new ClassWithConvert(Enum.A), () => new ClassWithConvert(Enum.A)) : void
|
||||
>fn : <T>(arg: ClassWithConvert<T>, f: () => ClassWithConvert<T>) => void
|
||||
>new ClassWithConvert(Enum.A) : ClassWithConvert<Enum>
|
||||
>ClassWithConvert : typeof ClassWithConvert
|
||||
>Enum.A : Enum.A
|
||||
>Enum : typeof Enum
|
||||
>A : Enum.A
|
||||
>() => new ClassWithConvert(Enum.A) : () => ClassWithConvert<Enum>
|
||||
>new ClassWithConvert(Enum.A) : ClassWithConvert<Enum>
|
||||
>ClassWithConvert : typeof ClassWithConvert
|
||||
>Enum.A : Enum.A
|
||||
>Enum : typeof Enum
|
||||
>A : Enum.A
|
||||
|
||||
type Func<T> = (x: T) => T;
|
||||
>Func : Func<T>
|
||||
>x : T
|
||||
|
||||
declare function makeFoo<T>(x: T): Func<T>;
|
||||
>makeFoo : <T>(x: T) => Func<T>
|
||||
>x : T
|
||||
|
||||
declare function baz<U>(x: Func<U>, y: Func<U>): void;
|
||||
>baz : <U>(x: Func<U>, y: Func<U>) => void
|
||||
>x : Func<U>
|
||||
>y : Func<U>
|
||||
|
||||
baz(makeFoo(Enum.A), makeFoo(Enum.A));
|
||||
>baz(makeFoo(Enum.A), makeFoo(Enum.A)) : void
|
||||
>baz : <U>(x: Func<U>, y: Func<U>) => void
|
||||
>makeFoo(Enum.A) : Func<Enum>
|
||||
>makeFoo : <T>(x: T) => Func<T>
|
||||
>Enum.A : Enum.A
|
||||
>Enum : typeof Enum
|
||||
>A : Enum.A
|
||||
>makeFoo(Enum.A) : Func<Enum>
|
||||
>makeFoo : <T>(x: T) => Func<T>
|
||||
>Enum.A : Enum.A
|
||||
>Enum : typeof Enum
|
||||
>A : Enum.A
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
//// [inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts]
|
||||
class ClassA<TEntityClass> {
|
||||
constructor(private entity?: TEntityClass, public settings?: SettingsInterface<TEntityClass>) {
|
||||
|
||||
}
|
||||
}
|
||||
export interface ValueInterface<TValueClass> {
|
||||
func?: (row: TValueClass) => any;
|
||||
value?: string;
|
||||
}
|
||||
export interface SettingsInterface<TClass> {
|
||||
values?: (row: TClass) => ValueInterface<TClass>[],
|
||||
}
|
||||
class ConcreteClass {
|
||||
theName = 'myClass';
|
||||
}
|
||||
|
||||
var thisGetsTheFalseError = new ClassA(new ConcreteClass(), {
|
||||
values: o => [
|
||||
{
|
||||
value: o.theName,
|
||||
func: x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
var thisIsOk = new ClassA<ConcreteClass>(new ConcreteClass(), {
|
||||
values: o => [
|
||||
{
|
||||
value: o.theName,
|
||||
func: x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
//// [inferenceDoesntCompareAgainstUninstantiatedTypeParameter.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var ClassA = /** @class */ (function () {
|
||||
function ClassA(entity, settings) {
|
||||
this.entity = entity;
|
||||
this.settings = settings;
|
||||
}
|
||||
return ClassA;
|
||||
}());
|
||||
var ConcreteClass = /** @class */ (function () {
|
||||
function ConcreteClass() {
|
||||
this.theName = 'myClass';
|
||||
}
|
||||
return ConcreteClass;
|
||||
}());
|
||||
var thisGetsTheFalseError = new ClassA(new ConcreteClass(), {
|
||||
values: function (o) { return [
|
||||
{
|
||||
value: o.theName,
|
||||
func: function (x) { return 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj'; }
|
||||
}
|
||||
]; }
|
||||
});
|
||||
var thisIsOk = new ClassA(new ConcreteClass(), {
|
||||
values: function (o) { return [
|
||||
{
|
||||
value: o.theName,
|
||||
func: function (x) { return 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj'; }
|
||||
}
|
||||
]; }
|
||||
});
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
=== tests/cases/compiler/inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts ===
|
||||
class ClassA<TEntityClass> {
|
||||
>ClassA : Symbol(ClassA, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 0, 0))
|
||||
>TEntityClass : Symbol(TEntityClass, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 0, 13))
|
||||
|
||||
constructor(private entity?: TEntityClass, public settings?: SettingsInterface<TEntityClass>) {
|
||||
>entity : Symbol(ClassA.entity, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 1, 16))
|
||||
>TEntityClass : Symbol(TEntityClass, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 0, 13))
|
||||
>settings : Symbol(ClassA.settings, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 1, 46))
|
||||
>SettingsInterface : Symbol(SettingsInterface, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 8, 1))
|
||||
>TEntityClass : Symbol(TEntityClass, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 0, 13))
|
||||
|
||||
}
|
||||
}
|
||||
export interface ValueInterface<TValueClass> {
|
||||
>ValueInterface : Symbol(ValueInterface, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 4, 1))
|
||||
>TValueClass : Symbol(TValueClass, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 5, 32))
|
||||
|
||||
func?: (row: TValueClass) => any;
|
||||
>func : Symbol(ValueInterface.func, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 5, 46))
|
||||
>row : Symbol(row, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 6, 12))
|
||||
>TValueClass : Symbol(TValueClass, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 5, 32))
|
||||
|
||||
value?: string;
|
||||
>value : Symbol(ValueInterface.value, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 6, 37))
|
||||
}
|
||||
export interface SettingsInterface<TClass> {
|
||||
>SettingsInterface : Symbol(SettingsInterface, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 8, 1))
|
||||
>TClass : Symbol(TClass, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 9, 35))
|
||||
|
||||
values?: (row: TClass) => ValueInterface<TClass>[],
|
||||
>values : Symbol(SettingsInterface.values, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 9, 44))
|
||||
>row : Symbol(row, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 10, 14))
|
||||
>TClass : Symbol(TClass, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 9, 35))
|
||||
>ValueInterface : Symbol(ValueInterface, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 4, 1))
|
||||
>TClass : Symbol(TClass, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 9, 35))
|
||||
}
|
||||
class ConcreteClass {
|
||||
>ConcreteClass : Symbol(ConcreteClass, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 11, 1))
|
||||
|
||||
theName = 'myClass';
|
||||
>theName : Symbol(ConcreteClass.theName, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 12, 21))
|
||||
}
|
||||
|
||||
var thisGetsTheFalseError = new ClassA(new ConcreteClass(), {
|
||||
>thisGetsTheFalseError : Symbol(thisGetsTheFalseError, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 16, 3))
|
||||
>ClassA : Symbol(ClassA, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 0, 0))
|
||||
>ConcreteClass : Symbol(ConcreteClass, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 11, 1))
|
||||
|
||||
values: o => [
|
||||
>values : Symbol(values, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 16, 61))
|
||||
>o : Symbol(o, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 17, 11))
|
||||
{
|
||||
value: o.theName,
|
||||
>value : Symbol(value, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 18, 9))
|
||||
>o.theName : Symbol(ConcreteClass.theName, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 12, 21))
|
||||
>o : Symbol(o, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 17, 11))
|
||||
>theName : Symbol(ConcreteClass.theName, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 12, 21))
|
||||
|
||||
func: x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj'
|
||||
>func : Symbol(func, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 19, 29))
|
||||
>x : Symbol(x, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 20, 17))
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
var thisIsOk = new ClassA<ConcreteClass>(new ConcreteClass(), {
|
||||
>thisIsOk : Symbol(thisIsOk, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 25, 3))
|
||||
>ClassA : Symbol(ClassA, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 0, 0))
|
||||
>ConcreteClass : Symbol(ConcreteClass, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 11, 1))
|
||||
>ConcreteClass : Symbol(ConcreteClass, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 11, 1))
|
||||
|
||||
values: o => [
|
||||
>values : Symbol(values, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 25, 63))
|
||||
>o : Symbol(o, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 26, 11))
|
||||
{
|
||||
value: o.theName,
|
||||
>value : Symbol(value, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 27, 9))
|
||||
>o.theName : Symbol(ConcreteClass.theName, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 12, 21))
|
||||
>o : Symbol(o, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 26, 11))
|
||||
>theName : Symbol(ConcreteClass.theName, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 12, 21))
|
||||
|
||||
func: x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj'
|
||||
>func : Symbol(func, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 28, 29))
|
||||
>x : Symbol(x, Decl(inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts, 29, 17))
|
||||
}
|
||||
]
|
||||
});
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
=== tests/cases/compiler/inferenceDoesntCompareAgainstUninstantiatedTypeParameter.ts ===
|
||||
class ClassA<TEntityClass> {
|
||||
>ClassA : ClassA<TEntityClass>
|
||||
|
||||
constructor(private entity?: TEntityClass, public settings?: SettingsInterface<TEntityClass>) {
|
||||
>entity : TEntityClass
|
||||
>settings : SettingsInterface<TEntityClass>
|
||||
|
||||
}
|
||||
}
|
||||
export interface ValueInterface<TValueClass> {
|
||||
func?: (row: TValueClass) => any;
|
||||
>func : (row: TValueClass) => any
|
||||
>row : TValueClass
|
||||
|
||||
value?: string;
|
||||
>value : string
|
||||
}
|
||||
export interface SettingsInterface<TClass> {
|
||||
values?: (row: TClass) => ValueInterface<TClass>[],
|
||||
>values : (row: TClass) => ValueInterface<TClass>[]
|
||||
>row : TClass
|
||||
}
|
||||
class ConcreteClass {
|
||||
>ConcreteClass : ConcreteClass
|
||||
|
||||
theName = 'myClass';
|
||||
>theName : string
|
||||
>'myClass' : "myClass"
|
||||
}
|
||||
|
||||
var thisGetsTheFalseError = new ClassA(new ConcreteClass(), {
|
||||
>thisGetsTheFalseError : ClassA<ConcreteClass>
|
||||
>new ClassA(new ConcreteClass(), { values: o => [ { value: o.theName, func: x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj' } ]}) : ClassA<ConcreteClass>
|
||||
>ClassA : typeof ClassA
|
||||
>new ConcreteClass() : ConcreteClass
|
||||
>ConcreteClass : typeof ConcreteClass
|
||||
>{ values: o => [ { value: o.theName, func: x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj' } ]} : { values: (o: ConcreteClass) => { value: string; func: (x: ConcreteClass) => string; }[]; }
|
||||
|
||||
values: o => [
|
||||
>values : (o: ConcreteClass) => { value: string; func: (x: ConcreteClass) => string; }[]
|
||||
>o => [ { value: o.theName, func: x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj' } ] : (o: ConcreteClass) => { value: string; func: (x: ConcreteClass) => string; }[]
|
||||
>o : ConcreteClass
|
||||
>[ { value: o.theName, func: x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj' } ] : { value: string; func: (x: ConcreteClass) => string; }[]
|
||||
{
|
||||
>{ value: o.theName, func: x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj' } : { value: string; func: (x: ConcreteClass) => string; }
|
||||
|
||||
value: o.theName,
|
||||
>value : string
|
||||
>o.theName : string
|
||||
>o : ConcreteClass
|
||||
>theName : string
|
||||
|
||||
func: x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj'
|
||||
>func : (x: ConcreteClass) => string
|
||||
>x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj' : (x: ConcreteClass) => string
|
||||
>x : ConcreteClass
|
||||
>'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj' : "asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj"
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
var thisIsOk = new ClassA<ConcreteClass>(new ConcreteClass(), {
|
||||
>thisIsOk : ClassA<ConcreteClass>
|
||||
>new ClassA<ConcreteClass>(new ConcreteClass(), { values: o => [ { value: o.theName, func: x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj' } ]}) : ClassA<ConcreteClass>
|
||||
>ClassA : typeof ClassA
|
||||
>new ConcreteClass() : ConcreteClass
|
||||
>ConcreteClass : typeof ConcreteClass
|
||||
>{ values: o => [ { value: o.theName, func: x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj' } ]} : { values: (o: ConcreteClass) => { value: string; func: (x: ConcreteClass) => string; }[]; }
|
||||
|
||||
values: o => [
|
||||
>values : (o: ConcreteClass) => { value: string; func: (x: ConcreteClass) => string; }[]
|
||||
>o => [ { value: o.theName, func: x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj' } ] : (o: ConcreteClass) => { value: string; func: (x: ConcreteClass) => string; }[]
|
||||
>o : ConcreteClass
|
||||
>[ { value: o.theName, func: x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj' } ] : { value: string; func: (x: ConcreteClass) => string; }[]
|
||||
{
|
||||
>{ value: o.theName, func: x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj' } : { value: string; func: (x: ConcreteClass) => string; }
|
||||
|
||||
value: o.theName,
|
||||
>value : string
|
||||
>o.theName : string
|
||||
>o : ConcreteClass
|
||||
>theName : string
|
||||
|
||||
func: x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj'
|
||||
>func : (x: ConcreteClass) => string
|
||||
>x => 'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj' : (x: ConcreteClass) => string
|
||||
>x : ConcreteClass
|
||||
>'asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj' : "asdfkjhgfdfghjkjhgfdfghjklkjhgfdfghjklkjhgfghj"
|
||||
}
|
||||
]
|
||||
});
|
||||
@@ -9,7 +9,7 @@ const [, a = ''] = ''.match('') || [];
|
||||
>'' : ""
|
||||
>match : (regexp: string | RegExp) => RegExpMatchArray
|
||||
>'' : ""
|
||||
>[] : [undefined?, ""?]
|
||||
>[] : undefined[]
|
||||
|
||||
a.toFixed()
|
||||
>a.toFixed() : any
|
||||
|
||||
@@ -43,6 +43,28 @@ const de: D & E = {
|
||||
other: { g: 101 }
|
||||
}
|
||||
}
|
||||
|
||||
// Additional test case with >2 doubly nested members so fix for #31441 is tested w/ excess props
|
||||
interface F {
|
||||
nested: { doublyNested: { g: string; } }
|
||||
}
|
||||
|
||||
interface G {
|
||||
nested: { doublyNested: { h: string; } }
|
||||
}
|
||||
|
||||
const defg: D & E & F & G = {
|
||||
nested: {
|
||||
doublyNested: {
|
||||
d: 'yes',
|
||||
f: 'no',
|
||||
g: 'ok',
|
||||
h: 'affirmative'
|
||||
},
|
||||
different: { e: 12 },
|
||||
other: { g: 101 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [intersectionTypeMembers.js]
|
||||
@@ -69,3 +91,15 @@ var de = {
|
||||
other: { g: 101 }
|
||||
}
|
||||
};
|
||||
var defg = {
|
||||
nested: {
|
||||
doublyNested: {
|
||||
d: 'yes',
|
||||
f: 'no',
|
||||
g: 'ok',
|
||||
h: 'affirmative'
|
||||
},
|
||||
different: { e: 12 },
|
||||
other: { g: 101 }
|
||||
}
|
||||
};
|
||||
|
||||
@@ -146,3 +146,58 @@ const de: D & E = {
|
||||
}
|
||||
}
|
||||
|
||||
// Additional test case with >2 doubly nested members so fix for #31441 is tested w/ excess props
|
||||
interface F {
|
||||
>F : Symbol(F, Decl(intersectionTypeMembers.ts, 43, 1))
|
||||
|
||||
nested: { doublyNested: { g: string; } }
|
||||
>nested : Symbol(F.nested, Decl(intersectionTypeMembers.ts, 46, 13))
|
||||
>doublyNested : Symbol(doublyNested, Decl(intersectionTypeMembers.ts, 47, 13))
|
||||
>g : Symbol(g, Decl(intersectionTypeMembers.ts, 47, 29))
|
||||
}
|
||||
|
||||
interface G {
|
||||
>G : Symbol(G, Decl(intersectionTypeMembers.ts, 48, 1))
|
||||
|
||||
nested: { doublyNested: { h: string; } }
|
||||
>nested : Symbol(G.nested, Decl(intersectionTypeMembers.ts, 50, 13))
|
||||
>doublyNested : Symbol(doublyNested, Decl(intersectionTypeMembers.ts, 51, 13))
|
||||
>h : Symbol(h, Decl(intersectionTypeMembers.ts, 51, 29))
|
||||
}
|
||||
|
||||
const defg: D & E & F & G = {
|
||||
>defg : Symbol(defg, Decl(intersectionTypeMembers.ts, 54, 5))
|
||||
>D : Symbol(D, Decl(intersectionTypeMembers.ts, 26, 14))
|
||||
>E : Symbol(E, Decl(intersectionTypeMembers.ts, 30, 1))
|
||||
>F : Symbol(F, Decl(intersectionTypeMembers.ts, 43, 1))
|
||||
>G : Symbol(G, Decl(intersectionTypeMembers.ts, 48, 1))
|
||||
|
||||
nested: {
|
||||
>nested : Symbol(nested, Decl(intersectionTypeMembers.ts, 54, 29))
|
||||
|
||||
doublyNested: {
|
||||
>doublyNested : Symbol(doublyNested, Decl(intersectionTypeMembers.ts, 55, 13))
|
||||
|
||||
d: 'yes',
|
||||
>d : Symbol(d, Decl(intersectionTypeMembers.ts, 56, 23))
|
||||
|
||||
f: 'no',
|
||||
>f : Symbol(f, Decl(intersectionTypeMembers.ts, 57, 21))
|
||||
|
||||
g: 'ok',
|
||||
>g : Symbol(g, Decl(intersectionTypeMembers.ts, 58, 20))
|
||||
|
||||
h: 'affirmative'
|
||||
>h : Symbol(h, Decl(intersectionTypeMembers.ts, 59, 20))
|
||||
|
||||
},
|
||||
different: { e: 12 },
|
||||
>different : Symbol(different, Decl(intersectionTypeMembers.ts, 61, 10))
|
||||
>e : Symbol(e, Decl(intersectionTypeMembers.ts, 62, 20))
|
||||
|
||||
other: { g: 101 }
|
||||
>other : Symbol(other, Decl(intersectionTypeMembers.ts, 62, 29))
|
||||
>g : Symbol(g, Decl(intersectionTypeMembers.ts, 63, 16))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -148,3 +148,61 @@ const de: D & E = {
|
||||
}
|
||||
}
|
||||
|
||||
// Additional test case with >2 doubly nested members so fix for #31441 is tested w/ excess props
|
||||
interface F {
|
||||
nested: { doublyNested: { g: string; } }
|
||||
>nested : { doublyNested: { g: string; }; }
|
||||
>doublyNested : { g: string; }
|
||||
>g : string
|
||||
}
|
||||
|
||||
interface G {
|
||||
nested: { doublyNested: { h: string; } }
|
||||
>nested : { doublyNested: { h: string; }; }
|
||||
>doublyNested : { h: string; }
|
||||
>h : string
|
||||
}
|
||||
|
||||
const defg: D & E & F & G = {
|
||||
>defg : D & E & F & G
|
||||
>{ nested: { doublyNested: { d: 'yes', f: 'no', g: 'ok', h: 'affirmative' }, different: { e: 12 }, other: { g: 101 } }} : { nested: { doublyNested: { d: string; f: string; g: string; h: string; }; different: { e: number; }; other: { g: number; }; }; }
|
||||
|
||||
nested: {
|
||||
>nested : { doublyNested: { d: string; f: string; g: string; h: string; }; different: { e: number; }; other: { g: number; }; }
|
||||
>{ doublyNested: { d: 'yes', f: 'no', g: 'ok', h: 'affirmative' }, different: { e: 12 }, other: { g: 101 } } : { doublyNested: { d: string; f: string; g: string; h: string; }; different: { e: number; }; other: { g: number; }; }
|
||||
|
||||
doublyNested: {
|
||||
>doublyNested : { d: string; f: string; g: string; h: string; }
|
||||
>{ d: 'yes', f: 'no', g: 'ok', h: 'affirmative' } : { d: string; f: string; g: string; h: string; }
|
||||
|
||||
d: 'yes',
|
||||
>d : string
|
||||
>'yes' : "yes"
|
||||
|
||||
f: 'no',
|
||||
>f : string
|
||||
>'no' : "no"
|
||||
|
||||
g: 'ok',
|
||||
>g : string
|
||||
>'ok' : "ok"
|
||||
|
||||
h: 'affirmative'
|
||||
>h : string
|
||||
>'affirmative' : "affirmative"
|
||||
|
||||
},
|
||||
different: { e: 12 },
|
||||
>different : { e: number; }
|
||||
>{ e: 12 } : { e: number; }
|
||||
>e : number
|
||||
>12 : 12
|
||||
|
||||
other: { g: 101 }
|
||||
>other : { g: number; }
|
||||
>{ g: 101 } : { g: number; }
|
||||
>g : number
|
||||
>101 : 101
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(26,7): error TS233
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(27,5): error TS2322: Type '1' is not assignable to type 'T[keyof T]'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(31,5): error TS2322: Type '{ [key: string]: number; }' is not assignable to type '{ [P in K]: number; }'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(38,5): error TS2322: Type '{ [x: string]: number; }' is not assignable to type '{ [P in K]: number; }'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(50,3): error TS7017: Element implicitly has an 'any' type because type 'Item' has no index signature.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(50,3): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Item'.
|
||||
No index signature with a parameter of type 'string' was found on type 'Item'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(51,3): error TS2322: Type '123' is not assignable to type 'string & number'.
|
||||
Type '123' is not assignable to type 'string'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(52,3): error TS2322: Type '123' is not assignable to type 'T[keyof T]'.
|
||||
@@ -112,7 +113,8 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS23
|
||||
function f10<T extends Item, K extends keyof T>(obj: T, k1: string, k2: keyof Item, k3: keyof T, k4: K) {
|
||||
obj[k1] = 123; // Error
|
||||
~~~~~~~
|
||||
!!! error TS7017: Element implicitly has an 'any' type because type 'Item' has no index signature.
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Item'.
|
||||
!!! error TS7053: No index signature with a parameter of type 'string' was found on type 'Item'.
|
||||
obj[k2] = 123; // Error
|
||||
~~~~~~~
|
||||
!!! error TS2322: Type '123' is not assignable to type 'string & number'.
|
||||
@@ -220,11 +222,12 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS23
|
||||
let y: ReadonlyArray<string>[K] = 'abc';
|
||||
}
|
||||
|
||||
// Repro from #31439
|
||||
// Repro from #31439 and #31691
|
||||
|
||||
export class c {
|
||||
[x: string]: string;
|
||||
constructor() {
|
||||
this.a = "b";
|
||||
this["a"] = "b";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,11 +137,12 @@ function fn4<K extends number>() {
|
||||
let y: ReadonlyArray<string>[K] = 'abc';
|
||||
}
|
||||
|
||||
// Repro from #31439
|
||||
// Repro from #31439 and #31691
|
||||
|
||||
export class c {
|
||||
[x: string]: string;
|
||||
constructor() {
|
||||
this.a = "b";
|
||||
this["a"] = "b";
|
||||
}
|
||||
}
|
||||
@@ -245,9 +246,10 @@ function fn4() {
|
||||
let x = 'abc';
|
||||
let y = 'abc';
|
||||
}
|
||||
// Repro from #31439
|
||||
// Repro from #31439 and #31691
|
||||
export class c {
|
||||
constructor() {
|
||||
this.a = "b";
|
||||
this["a"] = "b";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -503,7 +503,7 @@ function fn4<K extends number>() {
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 133, 13))
|
||||
}
|
||||
|
||||
// Repro from #31439
|
||||
// Repro from #31439 and #31691
|
||||
|
||||
export class c {
|
||||
>c : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 136, 1))
|
||||
@@ -512,6 +512,9 @@ export class c {
|
||||
>x : Symbol(x, Decl(keyofAndIndexedAccess2.ts, 141, 3))
|
||||
|
||||
constructor() {
|
||||
this.a = "b";
|
||||
>this : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 136, 1))
|
||||
|
||||
this["a"] = "b";
|
||||
>this : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 136, 1))
|
||||
}
|
||||
@@ -520,44 +523,44 @@ export class c {
|
||||
// Repro from #31385
|
||||
|
||||
type Foo<T> = { [key: string]: { [K in keyof T]: K }[keyof T] };
|
||||
>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess2.ts, 145, 1))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 149, 9))
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccess2.ts, 149, 17))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 149, 34))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 149, 9))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 149, 34))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 149, 9))
|
||||
>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess2.ts, 146, 1))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 150, 9))
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccess2.ts, 150, 17))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 150, 34))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 150, 9))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 150, 34))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 150, 9))
|
||||
|
||||
type Bar<T> = { [key: string]: { [K in keyof T]: [K] }[keyof T] };
|
||||
>Bar : Symbol(Bar, Decl(keyofAndIndexedAccess2.ts, 149, 64))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 151, 9))
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccess2.ts, 151, 17))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 151, 34))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 151, 9))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 151, 34))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 151, 9))
|
||||
>Bar : Symbol(Bar, Decl(keyofAndIndexedAccess2.ts, 150, 64))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 152, 9))
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccess2.ts, 152, 17))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 152, 34))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 152, 9))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 152, 34))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 152, 9))
|
||||
|
||||
type Baz<T, Q extends Foo<T>> = { [K in keyof Q]: T[Q[K]] };
|
||||
>Baz : Symbol(Baz, Decl(keyofAndIndexedAccess2.ts, 151, 66))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 153, 9))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 153, 11))
|
||||
>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess2.ts, 145, 1))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 153, 9))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 153, 35))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 153, 11))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 153, 9))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 153, 11))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 153, 35))
|
||||
>Baz : Symbol(Baz, Decl(keyofAndIndexedAccess2.ts, 152, 66))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 154, 9))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 154, 11))
|
||||
>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess2.ts, 146, 1))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 154, 9))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 154, 35))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 154, 11))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 154, 9))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 154, 11))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 154, 35))
|
||||
|
||||
type Qux<T, Q extends Bar<T>> = { [K in keyof Q]: T[Q[K]["0"]] };
|
||||
>Qux : Symbol(Qux, Decl(keyofAndIndexedAccess2.ts, 153, 60))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 155, 9))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 155, 11))
|
||||
>Bar : Symbol(Bar, Decl(keyofAndIndexedAccess2.ts, 149, 64))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 155, 9))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 155, 35))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 155, 11))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 155, 9))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 155, 11))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 155, 35))
|
||||
>Qux : Symbol(Qux, Decl(keyofAndIndexedAccess2.ts, 154, 60))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 156, 9))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 156, 11))
|
||||
>Bar : Symbol(Bar, Decl(keyofAndIndexedAccess2.ts, 150, 64))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 156, 9))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 156, 35))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 156, 11))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 156, 9))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 156, 11))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 156, 35))
|
||||
|
||||
|
||||
@@ -499,7 +499,7 @@ function fn4<K extends number>() {
|
||||
>'abc' : "abc"
|
||||
}
|
||||
|
||||
// Repro from #31439
|
||||
// Repro from #31439 and #31691
|
||||
|
||||
export class c {
|
||||
>c : c
|
||||
@@ -508,6 +508,13 @@ export class c {
|
||||
>x : string
|
||||
|
||||
constructor() {
|
||||
this.a = "b";
|
||||
>this.a = "b" : "b"
|
||||
>this.a : string
|
||||
>this : this
|
||||
>a : string
|
||||
>"b" : "b"
|
||||
|
||||
this["a"] = "b";
|
||||
>this["a"] = "b" : "b"
|
||||
>this["a"] : string
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
tests/cases/compiler/noImplicitAnyForIn.ts(7,18): error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
|
||||
tests/cases/compiler/noImplicitAnyForIn.ts(14,18): error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
|
||||
tests/cases/compiler/noImplicitAnyForIn.ts(7,18): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
|
||||
No index signature with a parameter of type 'string' was found on type '{}'.
|
||||
tests/cases/compiler/noImplicitAnyForIn.ts(14,18): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
|
||||
No index signature with a parameter of type 'string' was found on type '{}'.
|
||||
tests/cases/compiler/noImplicitAnyForIn.ts(28,5): error TS7005: Variable 'n' implicitly has an 'any[][]' type.
|
||||
tests/cases/compiler/noImplicitAnyForIn.ts(30,6): error TS2405: The left-hand side of a 'for...in' statement must be of type 'string' or 'any'.
|
||||
|
||||
@@ -13,7 +15,8 @@ tests/cases/compiler/noImplicitAnyForIn.ts(30,6): error TS2405: The left-hand si
|
||||
//Should yield an implicit 'any' error
|
||||
var _j = x[i][j];
|
||||
~~~~~~~
|
||||
!!! error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
|
||||
!!! error TS7053: No index signature with a parameter of type 'string' was found on type '{}'.
|
||||
}
|
||||
|
||||
for (var k in x[0]) {
|
||||
@@ -22,7 +25,8 @@ tests/cases/compiler/noImplicitAnyForIn.ts(30,6): error TS2405: The left-hand si
|
||||
//Should yield an implicit 'any' error
|
||||
var k2 = k1[k];
|
||||
~~~~~
|
||||
!!! error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
|
||||
!!! error TS7053: No index signature with a parameter of type 'string' was found on type '{}'.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
tests/cases/compiler/noImplicitAnyIndexing.ts(12,37): error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
|
||||
tests/cases/compiler/noImplicitAnyIndexing.ts(19,9): error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
|
||||
tests/cases/compiler/noImplicitAnyIndexing.ts(22,9): error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
|
||||
tests/cases/compiler/noImplicitAnyIndexing.ts(30,10): error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
|
||||
tests/cases/compiler/noImplicitAnyIndexing.ts(19,9): error TS7053: Element implicitly has an 'any' type because expression of type '"hi"' can't be used to index type '{}'.
|
||||
Property 'hi' does not exist on type '{}'.
|
||||
tests/cases/compiler/noImplicitAnyIndexing.ts(22,9): error TS7053: Element implicitly has an 'any' type because expression of type '10' can't be used to index type '{}'.
|
||||
Property '10' does not exist on type '{}'.
|
||||
tests/cases/compiler/noImplicitAnyIndexing.ts(30,10): error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{}'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/noImplicitAnyIndexing.ts (4 errors) ====
|
||||
@@ -27,12 +29,14 @@ tests/cases/compiler/noImplicitAnyIndexing.ts(30,10): error TS7017: Element impl
|
||||
// Should report an implicit 'any'.
|
||||
var x = {}["hi"];
|
||||
~~~~~~~~
|
||||
!!! error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hi"' can't be used to index type '{}'.
|
||||
!!! error TS7053: Property 'hi' does not exist on type '{}'.
|
||||
|
||||
// Should report an implicit 'any'.
|
||||
var y = {}[10];
|
||||
~~~~~~
|
||||
!!! error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type '10' can't be used to index type '{}'.
|
||||
!!! error TS7053: Property '10' does not exist on type '{}'.
|
||||
|
||||
|
||||
var hi: any = "hi";
|
||||
@@ -42,7 +46,7 @@ tests/cases/compiler/noImplicitAnyIndexing.ts(30,10): error TS7017: Element impl
|
||||
// Should report an implicit 'any'.
|
||||
var z1 = emptyObj[hi];
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{}'.
|
||||
var z2 = (<any>emptyObj)[hi];
|
||||
|
||||
interface MyMap<T> {
|
||||
|
||||
@@ -1,16 +1,29 @@
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(1,9): error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(1,9): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{}'.
|
||||
Property 'hello' does not exist on type '{}'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(7,1): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'get' ?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(8,13): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'get' ?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(13,13): error TS7017: Element implicitly has an 'any' type because type '{ set: (key: string) => string; }' has no index signature.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(13,13): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: string) => string; }'.
|
||||
Property 'hello' does not exist on type '{ set: (key: string) => string; }'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(19,1): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(20,1): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(21,1): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(26,1): error TS7053: Element implicitly has an 'any' type because expression of type '"a" | "b" | "c"' can't be used to index type '{ a: number; }'.
|
||||
Property 'b' does not exist on type '{ a: number; }'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(30,1): error TS7053: Element implicitly has an 'any' type because expression of type '"c"' can't be used to index type '{ a: number; }'.
|
||||
Property 'c' does not exist on type '{ a: number; }'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(33,1): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type '{ a: number; }'.
|
||||
Property '[sym]' does not exist on type '{ a: number; }'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(37,1): error TS7053: Element implicitly has an 'any' type because expression of type 'NumEnum' can't be used to index type '{ a: number; }'.
|
||||
Property '[NumEnum.a]' does not exist on type '{ a: number; }'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,1): error TS7053: Element implicitly has an 'any' type because expression of type 'StrEnum' can't be used to index type '{ a: number; }'.
|
||||
Property '[StrEnum.b]' does not exist on type '{ a: number; }'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts (7 errors) ====
|
||||
==== tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts (12 errors) ====
|
||||
var a = {}["hello"];
|
||||
~~~~~~~~~~~
|
||||
!!! error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{}'.
|
||||
!!! error TS7053: Property 'hello' does not exist on type '{}'.
|
||||
var b: string = { '': 'foo' }[''];
|
||||
|
||||
var c = {
|
||||
@@ -28,7 +41,8 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(21,1): error TS7052:
|
||||
};
|
||||
const bar = d['hello'];
|
||||
~~~~~~~~~~
|
||||
!!! error TS7017: Element implicitly has an 'any' type because type '{ set: (key: string) => string; }' has no index signature.
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: string) => string; }'.
|
||||
!!! error TS7053: Property 'hello' does not exist on type '{ set: (key: string) => string; }'.
|
||||
|
||||
var e = {
|
||||
set: (key: string) => 'foobar',
|
||||
@@ -44,4 +58,39 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(21,1): error TS7052:
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ?
|
||||
|
||||
const o = { a: 0 };
|
||||
|
||||
declare const k: "a" | "b" | "c";
|
||||
o[k];
|
||||
~~~~
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type '"a" | "b" | "c"' can't be used to index type '{ a: number; }'.
|
||||
!!! error TS7053: Property 'b' does not exist on type '{ a: number; }'.
|
||||
|
||||
|
||||
declare const k2: "c";
|
||||
o[k2];
|
||||
~~~~~
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type '"c"' can't be used to index type '{ a: number; }'.
|
||||
!!! error TS7053: Property 'c' does not exist on type '{ a: number; }'.
|
||||
|
||||
declare const sym : unique symbol;
|
||||
o[sym];
|
||||
~~~~~~
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type '{ a: number; }'.
|
||||
!!! error TS7053: Property '[sym]' does not exist on type '{ a: number; }'.
|
||||
|
||||
enum NumEnum { a, b }
|
||||
let numEnumKey: NumEnum;
|
||||
o[numEnumKey];
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type 'NumEnum' can't be used to index type '{ a: number; }'.
|
||||
!!! error TS7053: Property '[NumEnum.a]' does not exist on type '{ a: number; }'.
|
||||
|
||||
|
||||
enum StrEnum { a = "a", b = "b" }
|
||||
let strEnumKey: StrEnum;
|
||||
o[strEnumKey];
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type 'StrEnum' can't be used to index type '{ a: number; }'.
|
||||
!!! error TS7053: Property '[StrEnum.b]' does not exist on type '{ a: number; }'.
|
||||
|
||||
@@ -21,6 +21,26 @@ e['hello'] = 'modified';
|
||||
e['hello'] += 1;
|
||||
e['hello'] ++;
|
||||
|
||||
const o = { a: 0 };
|
||||
|
||||
declare const k: "a" | "b" | "c";
|
||||
o[k];
|
||||
|
||||
|
||||
declare const k2: "c";
|
||||
o[k2];
|
||||
|
||||
declare const sym : unique symbol;
|
||||
o[sym];
|
||||
|
||||
enum NumEnum { a, b }
|
||||
let numEnumKey: NumEnum;
|
||||
o[numEnumKey];
|
||||
|
||||
|
||||
enum StrEnum { a = "a", b = "b" }
|
||||
let strEnumKey: StrEnum;
|
||||
o[strEnumKey];
|
||||
|
||||
|
||||
//// [noImplicitAnyStringIndexerOnObject.js]
|
||||
@@ -42,3 +62,21 @@ var e = {
|
||||
e['hello'] = 'modified';
|
||||
e['hello'] += 1;
|
||||
e['hello']++;
|
||||
var o = { a: 0 };
|
||||
o[k];
|
||||
o[k2];
|
||||
o[sym];
|
||||
var NumEnum;
|
||||
(function (NumEnum) {
|
||||
NumEnum[NumEnum["a"] = 0] = "a";
|
||||
NumEnum[NumEnum["b"] = 1] = "b";
|
||||
})(NumEnum || (NumEnum = {}));
|
||||
var numEnumKey;
|
||||
o[numEnumKey];
|
||||
var StrEnum;
|
||||
(function (StrEnum) {
|
||||
StrEnum["a"] = "a";
|
||||
StrEnum["b"] = "b";
|
||||
})(StrEnum || (StrEnum = {}));
|
||||
var strEnumKey;
|
||||
o[strEnumKey];
|
||||
|
||||
@@ -55,4 +55,56 @@ e['hello'] += 1;
|
||||
e['hello'] ++;
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 14, 3))
|
||||
|
||||
const o = { a: 0 };
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5))
|
||||
>a : Symbol(a, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 11))
|
||||
|
||||
declare const k: "a" | "b" | "c";
|
||||
>k : Symbol(k, Decl(noImplicitAnyStringIndexerOnObject.ts, 24, 13))
|
||||
|
||||
o[k];
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5))
|
||||
>k : Symbol(k, Decl(noImplicitAnyStringIndexerOnObject.ts, 24, 13))
|
||||
|
||||
|
||||
declare const k2: "c";
|
||||
>k2 : Symbol(k2, Decl(noImplicitAnyStringIndexerOnObject.ts, 28, 13))
|
||||
|
||||
o[k2];
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5))
|
||||
>k2 : Symbol(k2, Decl(noImplicitAnyStringIndexerOnObject.ts, 28, 13))
|
||||
|
||||
declare const sym : unique symbol;
|
||||
>sym : Symbol(sym, Decl(noImplicitAnyStringIndexerOnObject.ts, 31, 13))
|
||||
|
||||
o[sym];
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5))
|
||||
>sym : Symbol(sym, Decl(noImplicitAnyStringIndexerOnObject.ts, 31, 13))
|
||||
|
||||
enum NumEnum { a, b }
|
||||
>NumEnum : Symbol(NumEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 32, 7))
|
||||
>a : Symbol(NumEnum.a, Decl(noImplicitAnyStringIndexerOnObject.ts, 34, 14))
|
||||
>b : Symbol(NumEnum.b, Decl(noImplicitAnyStringIndexerOnObject.ts, 34, 17))
|
||||
|
||||
let numEnumKey: NumEnum;
|
||||
>numEnumKey : Symbol(numEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 35, 3))
|
||||
>NumEnum : Symbol(NumEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 32, 7))
|
||||
|
||||
o[numEnumKey];
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5))
|
||||
>numEnumKey : Symbol(numEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 35, 3))
|
||||
|
||||
|
||||
enum StrEnum { a = "a", b = "b" }
|
||||
>StrEnum : Symbol(StrEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 36, 14))
|
||||
>a : Symbol(StrEnum.a, Decl(noImplicitAnyStringIndexerOnObject.ts, 39, 14))
|
||||
>b : Symbol(StrEnum.b, Decl(noImplicitAnyStringIndexerOnObject.ts, 39, 23))
|
||||
|
||||
let strEnumKey: StrEnum;
|
||||
>strEnumKey : Symbol(strEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 40, 3))
|
||||
>StrEnum : Symbol(StrEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 36, 14))
|
||||
|
||||
o[strEnumKey];
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5))
|
||||
>strEnumKey : Symbol(strEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 40, 3))
|
||||
|
||||
|
||||
@@ -89,4 +89,63 @@ e['hello'] ++;
|
||||
>e : { set: (key: string) => string; get: (key: string) => string; }
|
||||
>'hello' : "hello"
|
||||
|
||||
const o = { a: 0 };
|
||||
>o : { a: number; }
|
||||
>{ a: 0 } : { a: number; }
|
||||
>a : number
|
||||
>0 : 0
|
||||
|
||||
declare const k: "a" | "b" | "c";
|
||||
>k : "a" | "b" | "c"
|
||||
|
||||
o[k];
|
||||
>o[k] : any
|
||||
>o : { a: number; }
|
||||
>k : "a" | "b" | "c"
|
||||
|
||||
|
||||
declare const k2: "c";
|
||||
>k2 : "c"
|
||||
|
||||
o[k2];
|
||||
>o[k2] : any
|
||||
>o : { a: number; }
|
||||
>k2 : "c"
|
||||
|
||||
declare const sym : unique symbol;
|
||||
>sym : unique symbol
|
||||
|
||||
o[sym];
|
||||
>o[sym] : any
|
||||
>o : { a: number; }
|
||||
>sym : unique symbol
|
||||
|
||||
enum NumEnum { a, b }
|
||||
>NumEnum : NumEnum
|
||||
>a : NumEnum.a
|
||||
>b : NumEnum.b
|
||||
|
||||
let numEnumKey: NumEnum;
|
||||
>numEnumKey : NumEnum
|
||||
|
||||
o[numEnumKey];
|
||||
>o[numEnumKey] : any
|
||||
>o : { a: number; }
|
||||
>numEnumKey : NumEnum
|
||||
|
||||
|
||||
enum StrEnum { a = "a", b = "b" }
|
||||
>StrEnum : StrEnum
|
||||
>a : StrEnum.a
|
||||
>"a" : "a"
|
||||
>b : StrEnum.b
|
||||
>"b" : "b"
|
||||
|
||||
let strEnumKey: StrEnum;
|
||||
>strEnumKey : StrEnum
|
||||
|
||||
o[strEnumKey];
|
||||
>o[strEnumKey] : any
|
||||
>o : { a: number; }
|
||||
>strEnumKey : StrEnum
|
||||
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
//// [noImplicitThisBigThis.ts]
|
||||
// https://github.com/microsoft/TypeScript/issues/29902
|
||||
|
||||
function createObj() {
|
||||
return {
|
||||
func1() {
|
||||
return this;
|
||||
},
|
||||
func2() {
|
||||
return this;
|
||||
},
|
||||
func3() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createObjNoCrash() {
|
||||
return {
|
||||
func1() {
|
||||
return this;
|
||||
},
|
||||
func2() {
|
||||
return this;
|
||||
},
|
||||
func3() {
|
||||
return this;
|
||||
},
|
||||
func4() {
|
||||
return this;
|
||||
},
|
||||
func5() {
|
||||
return this;
|
||||
},
|
||||
func6() {
|
||||
return this;
|
||||
},
|
||||
func7() {
|
||||
return this;
|
||||
},
|
||||
func8() {
|
||||
return this;
|
||||
},
|
||||
func9() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
//// [noImplicitThisBigThis.js]
|
||||
// https://github.com/microsoft/TypeScript/issues/29902
|
||||
function createObj() {
|
||||
return {
|
||||
func1: function () {
|
||||
return this;
|
||||
},
|
||||
func2: function () {
|
||||
return this;
|
||||
},
|
||||
func3: function () {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
function createObjNoCrash() {
|
||||
return {
|
||||
func1: function () {
|
||||
return this;
|
||||
},
|
||||
func2: function () {
|
||||
return this;
|
||||
},
|
||||
func3: function () {
|
||||
return this;
|
||||
},
|
||||
func4: function () {
|
||||
return this;
|
||||
},
|
||||
func5: function () {
|
||||
return this;
|
||||
},
|
||||
func6: function () {
|
||||
return this;
|
||||
},
|
||||
func7: function () {
|
||||
return this;
|
||||
},
|
||||
func8: function () {
|
||||
return this;
|
||||
},
|
||||
func9: function () {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
//// [noImplicitThisBigThis.d.ts]
|
||||
declare function createObj(): {
|
||||
func1(): any;
|
||||
func2(): any;
|
||||
func3(): any;
|
||||
};
|
||||
declare function createObjNoCrash(): {
|
||||
func1(): any;
|
||||
func2(): any;
|
||||
func3(): any;
|
||||
func4(): any;
|
||||
func5(): any;
|
||||
func6(): any;
|
||||
func7(): any;
|
||||
func8(): any;
|
||||
func9(): any;
|
||||
};
|
||||
@@ -0,0 +1,99 @@
|
||||
=== tests/cases/compiler/noImplicitThisBigThis.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/29902
|
||||
|
||||
function createObj() {
|
||||
>createObj : Symbol(createObj, Decl(noImplicitThisBigThis.ts, 0, 0))
|
||||
|
||||
return {
|
||||
func1() {
|
||||
>func1 : Symbol(func1, Decl(noImplicitThisBigThis.ts, 3, 12))
|
||||
|
||||
return this;
|
||||
>this : Symbol(__object, Decl(noImplicitThisBigThis.ts, 3, 10))
|
||||
|
||||
},
|
||||
func2() {
|
||||
>func2 : Symbol(func2, Decl(noImplicitThisBigThis.ts, 6, 10))
|
||||
|
||||
return this;
|
||||
>this : Symbol(__object, Decl(noImplicitThisBigThis.ts, 3, 10))
|
||||
|
||||
},
|
||||
func3() {
|
||||
>func3 : Symbol(func3, Decl(noImplicitThisBigThis.ts, 9, 10))
|
||||
|
||||
return this;
|
||||
>this : Symbol(__object, Decl(noImplicitThisBigThis.ts, 3, 10))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createObjNoCrash() {
|
||||
>createObjNoCrash : Symbol(createObjNoCrash, Decl(noImplicitThisBigThis.ts, 14, 1))
|
||||
|
||||
return {
|
||||
func1() {
|
||||
>func1 : Symbol(func1, Decl(noImplicitThisBigThis.ts, 17, 12))
|
||||
|
||||
return this;
|
||||
>this : Symbol(__object, Decl(noImplicitThisBigThis.ts, 17, 10))
|
||||
|
||||
},
|
||||
func2() {
|
||||
>func2 : Symbol(func2, Decl(noImplicitThisBigThis.ts, 20, 10))
|
||||
|
||||
return this;
|
||||
>this : Symbol(__object, Decl(noImplicitThisBigThis.ts, 17, 10))
|
||||
|
||||
},
|
||||
func3() {
|
||||
>func3 : Symbol(func3, Decl(noImplicitThisBigThis.ts, 23, 10))
|
||||
|
||||
return this;
|
||||
>this : Symbol(__object, Decl(noImplicitThisBigThis.ts, 17, 10))
|
||||
|
||||
},
|
||||
func4() {
|
||||
>func4 : Symbol(func4, Decl(noImplicitThisBigThis.ts, 26, 10))
|
||||
|
||||
return this;
|
||||
>this : Symbol(__object, Decl(noImplicitThisBigThis.ts, 17, 10))
|
||||
|
||||
},
|
||||
func5() {
|
||||
>func5 : Symbol(func5, Decl(noImplicitThisBigThis.ts, 29, 10))
|
||||
|
||||
return this;
|
||||
>this : Symbol(__object, Decl(noImplicitThisBigThis.ts, 17, 10))
|
||||
|
||||
},
|
||||
func6() {
|
||||
>func6 : Symbol(func6, Decl(noImplicitThisBigThis.ts, 32, 10))
|
||||
|
||||
return this;
|
||||
>this : Symbol(__object, Decl(noImplicitThisBigThis.ts, 17, 10))
|
||||
|
||||
},
|
||||
func7() {
|
||||
>func7 : Symbol(func7, Decl(noImplicitThisBigThis.ts, 35, 10))
|
||||
|
||||
return this;
|
||||
>this : Symbol(__object, Decl(noImplicitThisBigThis.ts, 17, 10))
|
||||
|
||||
},
|
||||
func8() {
|
||||
>func8 : Symbol(func8, Decl(noImplicitThisBigThis.ts, 38, 10))
|
||||
|
||||
return this;
|
||||
>this : Symbol(__object, Decl(noImplicitThisBigThis.ts, 17, 10))
|
||||
|
||||
},
|
||||
func9() {
|
||||
>func9 : Symbol(func9, Decl(noImplicitThisBigThis.ts, 41, 10))
|
||||
|
||||
return this;
|
||||
>this : Symbol(__object, Decl(noImplicitThisBigThis.ts, 17, 10))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
=== tests/cases/compiler/noImplicitThisBigThis.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/29902
|
||||
|
||||
function createObj() {
|
||||
>createObj : () => { func1(): any; func2(): any; func3(): any; }
|
||||
|
||||
return {
|
||||
>{ func1() { return this; }, func2() { return this; }, func3() { return this; } } : { func1(): { func1(): any; func2(): any; func3(): any; }; func2(): { func1(): any; func2(): any; func3(): any; }; func3(): { func1(): any; func2(): any; func3(): any; }; }
|
||||
|
||||
func1() {
|
||||
>func1 : () => { func1(): any; func2(): any; func3(): any; }
|
||||
|
||||
return this;
|
||||
>this : { func1(): { func1(): any; func2(): any; func3(): any; }; func2(): { func1(): any; func2(): any; func3(): any; }; func3(): { func1(): any; func2(): any; func3(): any; }; }
|
||||
|
||||
},
|
||||
func2() {
|
||||
>func2 : () => { func1(): any; func2(): any; func3(): any; }
|
||||
|
||||
return this;
|
||||
>this : { func1(): { func1(): any; func2(): any; func3(): any; }; func2(): { func1(): any; func2(): any; func3(): any; }; func3(): { func1(): any; func2(): any; func3(): any; }; }
|
||||
|
||||
},
|
||||
func3() {
|
||||
>func3 : () => { func1(): any; func2(): any; func3(): any; }
|
||||
|
||||
return this;
|
||||
>this : { func1(): { func1(): any; func2(): any; func3(): any; }; func2(): { func1(): any; func2(): any; func3(): any; }; func3(): { func1(): any; func2(): any; func3(): any; }; }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createObjNoCrash() {
|
||||
>createObjNoCrash : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
|
||||
|
||||
return {
|
||||
>{ func1() { return this; }, func2() { return this; }, func3() { return this; }, func4() { return this; }, func5() { return this; }, func6() { return this; }, func7() { return this; }, func8() { return this; }, func9() { return this; } } : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
|
||||
|
||||
func1() {
|
||||
>func1 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
|
||||
|
||||
return this;
|
||||
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
|
||||
|
||||
},
|
||||
func2() {
|
||||
>func2 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
|
||||
|
||||
return this;
|
||||
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
|
||||
|
||||
},
|
||||
func3() {
|
||||
>func3 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
|
||||
|
||||
return this;
|
||||
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
|
||||
|
||||
},
|
||||
func4() {
|
||||
>func4 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
|
||||
|
||||
return this;
|
||||
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
|
||||
|
||||
},
|
||||
func5() {
|
||||
>func5 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
|
||||
|
||||
return this;
|
||||
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
|
||||
|
||||
},
|
||||
func6() {
|
||||
>func6 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
|
||||
|
||||
return this;
|
||||
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
|
||||
|
||||
},
|
||||
func7() {
|
||||
>func7 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
|
||||
|
||||
return this;
|
||||
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
|
||||
|
||||
},
|
||||
func8() {
|
||||
>func8 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
|
||||
|
||||
return this;
|
||||
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
|
||||
|
||||
},
|
||||
func9() {
|
||||
>func9 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
|
||||
|
||||
return this;
|
||||
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInNoImplicitAny.ts(4,17): error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
|
||||
tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInNoImplicitAny.ts(4,17): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
|
||||
No index signature with a parameter of type 'string' was found on type '{}'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInNoImplicitAny.ts (1 errors) ====
|
||||
@@ -7,6 +8,7 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveIndexingWithForInNoImplic
|
||||
for (var key in a) {
|
||||
var value = a[key]; // error
|
||||
~~~~~~
|
||||
!!! error TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
|
||||
!!! error TS7053: No index signature with a parameter of type 'string' was found on type '{}'.
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user