mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'conditionalTypes' into inferTypes
# Conflicts: # src/compiler/checker.ts # tests/cases/fourslash/completionInJSDocFunctionNew.ts # tests/cases/fourslash/completionInJSDocFunctionThis.ts
This commit is contained in:
+1
-1
@@ -39,7 +39,7 @@ scripts/word2md.js
|
||||
scripts/buildProtocol.js
|
||||
scripts/ior.js
|
||||
scripts/authors.js
|
||||
scripts/configureNightly.js
|
||||
scripts/configurePrerelease.js
|
||||
scripts/processDiagnosticMessages.d.ts
|
||||
scripts/processDiagnosticMessages.js
|
||||
scripts/importDefinitelyTypedTests/importDefinitelyTypedTests.js
|
||||
|
||||
@@ -291,14 +291,13 @@ Zeeshan Ahmed <ziishaned@gmail.com>
|
||||
Orta <orta.therox+github@gmail.com> # Orta Therox
|
||||
IdeaHunter <admin@fckn.me> # @IdeaHunter
|
||||
kujon <jakub.korzeniowski@gmail.com> # Jakub Korzeniowski
|
||||
Matt <begincalendar@users.noreply.github.com> @begincalendar
|
||||
Matt <begincalendar@users.noreply.github.com> # @begincalendar
|
||||
meyer <github.com@meyer.fm> # @meyer
|
||||
micbou <contact@micbou.com> # @micbou
|
||||
Alan Agius <alan.agius4@gmail.com>
|
||||
Alex Khomchenko <akhomchenko@gmail.com>
|
||||
Oussama Ben Brahim <benbraou@gmail.com> benbraou <benbraou@users.noreply.github.com>
|
||||
Cameron Taggart <cameron.taggart@gmail.com>
|
||||
csigs <csigs@outlook.com> csigs <csigs@users.noreply.github.com>
|
||||
Eugene Timokhov <timocov@gmail.com>
|
||||
Kris Zyp <kriszyp@gmail.com>
|
||||
Jing Ma <mjingm87@qq.com>
|
||||
@@ -311,4 +310,10 @@ Sharon Rolel <sharonrolel@gmail.com>
|
||||
Stanislav Iliev <gigobest2@gmail.com>
|
||||
Wenlu Wang <805037171@163.com> wenlu.wang <805037171@163.com> kingwl <805037171@163.com>
|
||||
Wilson Hobbs <wilsonhobbs1@gmail.com>
|
||||
Yuval Greenfield <ubershmekel@gmail.com>
|
||||
Yuval Greenfield <ubershmekel@gmail.com>
|
||||
Daniel <nieltg@users.noreply.github.com> # @nieltg
|
||||
Adnan Chowdhury <bttf@users.noreply.github.com>
|
||||
Esakki Raj <esakkiraj.tce@gmail.com>
|
||||
Jack Williams <jw@jackw.io>
|
||||
Philippe Voinov <philippevoinov@gmail.com>
|
||||
Stephan Ginthör <26004708+Lazarus535@users.noreply.github.com>
|
||||
+2
-1
@@ -18,4 +18,5 @@ Jakefile.js
|
||||
.settings/
|
||||
.travis.yml
|
||||
.vscode/
|
||||
test.config
|
||||
test.config
|
||||
package-lock.json
|
||||
|
||||
+7
-2
@@ -3,6 +3,7 @@ TypeScript is authored by:
|
||||
* Abubaker Bashir
|
||||
* Adam Freidin
|
||||
* Adi Dahiya
|
||||
* Adnan Chowdhury
|
||||
* Adrian Leonhard
|
||||
* Ahmad Farid
|
||||
* Akshar Patel
|
||||
@@ -36,6 +37,7 @@ TypeScript is authored by:
|
||||
* Asad Saeeduddin
|
||||
* Avery Morin
|
||||
* Basarat Ali Syed
|
||||
* @begincalendar
|
||||
* Ben Duffield
|
||||
* Ben Mosher
|
||||
* Benjamin Bock
|
||||
@@ -59,7 +61,6 @@ TypeScript is authored by:
|
||||
* Colby Russell
|
||||
* Colin Snover
|
||||
* Cotton Hou
|
||||
* csigs
|
||||
* Cyrus Najmabadi
|
||||
* Dafrok Zhang
|
||||
* Dahan Gong
|
||||
@@ -87,6 +88,7 @@ TypeScript is authored by:
|
||||
* Eric Tsang
|
||||
* Erik Edrosa
|
||||
* Erik McClenney
|
||||
* Esakki Raj
|
||||
* Ethan Resnick
|
||||
* Ethan Rubio
|
||||
* Eugene Timokhov
|
||||
@@ -124,6 +126,7 @@ TypeScript is authored by:
|
||||
* Ivan Enderlin
|
||||
* Ivo Gabe de Wolff
|
||||
* Iwata Hidetaka
|
||||
* Jack Williams
|
||||
* Jakub Korzeniowski
|
||||
* Jakub Młokosiewicz
|
||||
* James Henry
|
||||
@@ -182,7 +185,6 @@ TypeScript is authored by:
|
||||
* Martin Hiller
|
||||
* Martin Vseticka
|
||||
* Masahiro Wakame
|
||||
* Matt
|
||||
* Matt Bierner
|
||||
* Matt McCutchen
|
||||
* Matt Mitchell
|
||||
@@ -205,6 +207,7 @@ TypeScript is authored by:
|
||||
* Nathan Shively-Sanders
|
||||
* Nathan Yee
|
||||
* Nicolas Henry
|
||||
* @nieltg
|
||||
* Nima Zahedi
|
||||
* Noah Chen
|
||||
* Noel Varanda
|
||||
@@ -223,6 +226,7 @@ TypeScript is authored by:
|
||||
* Perry Jiang
|
||||
* Peter Burns
|
||||
* Philip Bulley
|
||||
* Philippe Voinov
|
||||
* Piero Cangianiello
|
||||
* @piloopin
|
||||
* Prayag Verma
|
||||
@@ -260,6 +264,7 @@ TypeScript is authored by:
|
||||
* Stanislav Iliev
|
||||
* Stanislav Sysoev
|
||||
* Stas Vilchik
|
||||
* Stephan Ginthör
|
||||
* Steve Lucco
|
||||
* Sudheesh Singanamalla
|
||||
* Sébastien Arod
|
||||
|
||||
+1
-1
@@ -1115,7 +1115,7 @@ gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are:
|
||||
const fileMatcher = cmdLineOptions.files;
|
||||
const files = fileMatcher
|
||||
? `src/**/${fileMatcher}`
|
||||
: "Gulpfile.ts 'scripts/generateLocalizedDiagnosticMessages.ts' 'scripts/tslint/**/*.ts' 'src/**/*.ts' --exclude 'src/lib/*.d.ts'";
|
||||
: `Gulpfile.ts "scripts/generateLocalizedDiagnosticMessages.ts" "scripts/tslint/**/*.ts" "src/**/*.ts" --exclude "src/lib/*.d.ts"`;
|
||||
const cmd = `node node_modules/tslint/bin/tslint ${files} --formatters-dir ./built/local/tslint/formatters --format autolinkableStylish`;
|
||||
console.log("Linting: " + cmd);
|
||||
child_process.execSync(cmd, { stdio: [0, 1, 2] });
|
||||
|
||||
+24
-22
@@ -556,16 +556,16 @@ desc("Generates a diagnostic file in TypeScript based on an input JSON file");
|
||||
task("generate-diagnostics", [diagnosticInfoMapTs]);
|
||||
|
||||
// Publish nightly
|
||||
var configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js");
|
||||
var configureNightlyTs = path.join(scriptsDirectory, "configureNightly.ts");
|
||||
var configurePrereleaseJs = path.join(scriptsDirectory, "configurePrerelease.js");
|
||||
var configurePrereleaseTs = path.join(scriptsDirectory, "configurePrerelease.ts");
|
||||
var packageJson = "package.json";
|
||||
var versionFile = path.join(compilerDirectory, "core.ts");
|
||||
|
||||
file(configureNightlyTs);
|
||||
file(configurePrereleaseTs);
|
||||
|
||||
compileFile(/*outfile*/configureNightlyJs,
|
||||
/*sources*/[configureNightlyTs],
|
||||
/*prereqs*/[configureNightlyTs],
|
||||
compileFile(/*outfile*/configurePrereleaseJs,
|
||||
/*sources*/[configurePrereleaseTs],
|
||||
/*prereqs*/[configurePrereleaseTs],
|
||||
/*prefixes*/[],
|
||||
/*useBuiltCompiler*/ false,
|
||||
{ noOutFile: false, generateDeclarations: false, keepComments: false, noResolve: false, stripInternal: false });
|
||||
@@ -574,8 +574,8 @@ task("setDebugMode", function () {
|
||||
useDebugMode = true;
|
||||
});
|
||||
|
||||
task("configure-nightly", [configureNightlyJs], function () {
|
||||
var cmd = host + " " + configureNightlyJs + " " + packageJson + " " + versionFile;
|
||||
task("configure-nightly", [configurePrereleaseJs], function () {
|
||||
var cmd = host + " " + configurePrereleaseJs + " dev " + packageJson + " " + versionFile;
|
||||
console.log(cmd);
|
||||
exec(cmd);
|
||||
}, { async: true });
|
||||
@@ -587,6 +587,19 @@ task("publish-nightly", ["configure-nightly", "LKG", "clean", "setDebugMode", "r
|
||||
exec(cmd);
|
||||
});
|
||||
|
||||
task("configure-insiders", [configurePrereleaseJs], function () {
|
||||
var cmd = host + " " + configurePrereleaseJs + " insiders " + packageJson + " " + versionFile;
|
||||
console.log(cmd);
|
||||
exec(cmd);
|
||||
}, { async: true });
|
||||
|
||||
desc("Configure, build, test, and publish the insiders release.");
|
||||
task("publish-insiders", ["configure-insiders", "LKG", "clean", "setDebugMode", "runtests-parallel"], function () {
|
||||
var cmd = "npm publish --tag insiders";
|
||||
console.log(cmd);
|
||||
exec(cmd);
|
||||
});
|
||||
|
||||
var importDefinitelyTypedTestsDirectory = path.join(scriptsDirectory, "importDefinitelyTypedTests");
|
||||
var importDefinitelyTypedTestsJs = path.join(importDefinitelyTypedTestsDirectory, "importDefinitelyTypedTests.js");
|
||||
var importDefinitelyTypedTestsTs = path.join(importDefinitelyTypedTestsDirectory, "importDefinitelyTypedTests.ts");
|
||||
@@ -1199,23 +1212,12 @@ task("update-sublime", ["local", serverFile], function () {
|
||||
});
|
||||
|
||||
var tslintRuleDir = "scripts/tslint/rules";
|
||||
var tslintRules = [
|
||||
"booleanTriviaRule",
|
||||
"debugAssertRule",
|
||||
"nextLineRule",
|
||||
"noBomRule",
|
||||
"noDoubleSpaceRule",
|
||||
"noIncrementDecrementRule",
|
||||
"noInOperatorRule",
|
||||
"noTypeAssertionWhitespaceRule",
|
||||
"objectLiteralSurroundingSpaceRule",
|
||||
"typeOperatorSpacingRule",
|
||||
];
|
||||
var tslintRules = fs.readdirSync(tslintRuleDir);
|
||||
var tslintRulesFiles = tslintRules.map(function (p) {
|
||||
return path.join(tslintRuleDir, p + ".ts");
|
||||
return path.join(tslintRuleDir, p);
|
||||
});
|
||||
var tslintRulesOutFiles = tslintRules.map(function (p) {
|
||||
return path.join(builtLocalDirectory, "tslint/rules", p + ".js");
|
||||
return path.join(builtLocalDirectory, "tslint/rules", p.replace(".ts", ".js"));
|
||||
});
|
||||
var tslintFormattersDir = "scripts/tslint/formatters";
|
||||
var tslintFormatters = [
|
||||
|
||||
+30
-4
@@ -1,10 +1,34 @@
|
||||
<!-- BUGS: Please use this template. -->
|
||||
<!-- QUESTIONS: This is not a general support forum! Ask Qs at http://stackoverflow.com/questions/tagged/typescript -->
|
||||
<!-- SUGGESTIONS: See https://github.com/Microsoft/TypeScript-wiki/blob/master/Writing-Good-Design-Proposals.md -->
|
||||
<!-- 🚨 STOP 🚨 𝗦𝗧𝗢𝗣 🚨 𝑺𝑻𝑶𝑷 🚨 -->
|
||||
<!--
|
||||
Half of all issues filed here are duplicates, answered in the FAQ, or not appropriate for the bug tracker.
|
||||
|
||||
Please help us by doing the following steps before logging an issue:
|
||||
* Search: https://github.com/Microsoft/TypeScript/search?type=Issues
|
||||
* Read the CONTRIBUTING guidelines: https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md
|
||||
* Read the FAQ: https://github.com/Microsoft/TypeScript/wiki/FAQ
|
||||
-->
|
||||
|
||||
<!-- If you have a QUESTION:
|
||||
THIS IS NOT A FORUM FOR QUESTIONS.
|
||||
Ask questions at http://stackoverflow.com/questions/tagged/typescript
|
||||
or https://gitter.im/Microsoft/TypeScript
|
||||
-->
|
||||
|
||||
<!-- If you have a SUGGESTION:
|
||||
Most suggestion reports are duplicates, please search extra hard before logging a new suggestion.
|
||||
See https://github.com/Microsoft/TypeScript-wiki/blob/master/Writing-Good-Design-Proposals.md
|
||||
-->
|
||||
|
||||
<!-- If you have a BUG:
|
||||
Please fill in the *entire* template below.
|
||||
-->
|
||||
|
||||
<!-- Please try to reproduce the issue with `typescript@next`. It may have already been fixed. -->
|
||||
**TypeScript Version:** 2.7.0-dev.201xxxxx
|
||||
|
||||
<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
|
||||
**Search Terms:**
|
||||
|
||||
**Code**
|
||||
|
||||
```ts
|
||||
@@ -16,4 +40,6 @@
|
||||
|
||||
**Actual behavior:**
|
||||
|
||||
**Related:**
|
||||
**Playground Link:** <!-- A link to a TypeScript Playground "Share" link which demonstrates this behavior -->
|
||||
|
||||
**Related Issues:**
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"name": "typescript",
|
||||
"author": "Microsoft Corp.",
|
||||
"homepage": "http://typescriptlang.org/",
|
||||
"version": "2.7.0",
|
||||
"version": "2.8.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "TypeScript is a language for application scale JavaScript development",
|
||||
"keywords": [
|
||||
|
||||
+1
-1
@@ -164,7 +164,7 @@ namespace Commands {
|
||||
}
|
||||
});
|
||||
};
|
||||
listAuthors.description = "List known and unknown authors for a given spec";
|
||||
listAuthors.description = "List known and unknown authors for a given spec, e.g. 'node authors.js listAuthors origin/release-2.6..origin/release-2.7'";
|
||||
}
|
||||
|
||||
var args = process.argv.slice(2);
|
||||
|
||||
@@ -11,34 +11,39 @@ interface PackageJson {
|
||||
|
||||
function main(): void {
|
||||
const sys = ts.sys;
|
||||
if (sys.args.length < 2) {
|
||||
if (sys.args.length < 3) {
|
||||
sys.write("Usage:" + sys.newLine)
|
||||
sys.write("\tnode configureNightly.js <package.json location> <file containing version>" + sys.newLine);
|
||||
sys.write("\tnode configureNightly.js <dev|insiders> <package.json location> <file containing version>" + sys.newLine);
|
||||
return;
|
||||
}
|
||||
|
||||
const tag = sys.args[0];
|
||||
if (tag !== "dev" && tag !== "insiders") {
|
||||
throw new Error(`Unexpected tag name '${tag}'.`);
|
||||
}
|
||||
|
||||
// Acquire the version from the package.json file and modify it appropriately.
|
||||
const packageJsonFilePath = ts.normalizePath(sys.args[0]);
|
||||
const packageJsonFilePath = ts.normalizePath(sys.args[1]);
|
||||
const packageJsonValue: PackageJson = JSON.parse(sys.readFile(packageJsonFilePath));
|
||||
|
||||
const { majorMinor, patch } = parsePackageJsonVersion(packageJsonValue.version);
|
||||
const nightlyPatch = getNightlyPatch(patch);
|
||||
const prereleasePatch = getPrereleasePatch(tag, patch);
|
||||
|
||||
// Acquire and modify the source file that exposes the version string.
|
||||
const tsFilePath = ts.normalizePath(sys.args[1]);
|
||||
const tsFilePath = ts.normalizePath(sys.args[2]);
|
||||
const tsFileContents = ts.sys.readFile(tsFilePath);
|
||||
const modifiedTsFileContents = updateTsFile(tsFilePath, tsFileContents, majorMinor, patch, nightlyPatch);
|
||||
const modifiedTsFileContents = updateTsFile(tsFilePath, tsFileContents, majorMinor, patch, prereleasePatch);
|
||||
|
||||
// Ensure we are actually changing something - the user probably wants to know that the update failed.
|
||||
if (tsFileContents === modifiedTsFileContents) {
|
||||
let err = `\n '${tsFilePath}' was not updated while configuring for a nightly publish.\n `;
|
||||
let err = `\n '${tsFilePath}' was not updated while configuring for a prerelease publish for '${tag}'.\n `;
|
||||
err += `Ensure that you have not already run this script; otherwise, erase your changes using 'git checkout -- "${tsFilePath}"'.`;
|
||||
throw err + "\n";
|
||||
throw new Error(err + "\n");
|
||||
}
|
||||
|
||||
// Finally write the changes to disk.
|
||||
// Modify the package.json structure
|
||||
packageJsonValue.version = `${majorMinor}.${nightlyPatch}`;
|
||||
packageJsonValue.version = `${majorMinor}.${prereleasePatch}`;
|
||||
sys.writeFile(packageJsonFilePath, JSON.stringify(packageJsonValue, /*replacer:*/ undefined, /*space:*/ 4))
|
||||
sys.writeFile(tsFilePath, modifiedTsFileContents);
|
||||
}
|
||||
@@ -69,7 +74,7 @@ function parsePackageJsonVersion(versionString: string): { majorMinor: string, p
|
||||
}
|
||||
|
||||
/** e.g. 0-dev.20170707 */
|
||||
function getNightlyPatch(plainPatch: string): string {
|
||||
function getPrereleasePatch(tag: string, plainPatch: string): string {
|
||||
// We're going to append a representation of the current time at the end of the current version.
|
||||
// String.prototype.toISOString() returns a 24-character string formatted as 'YYYY-MM-DDTHH:mm:ss.sssZ',
|
||||
// but we'd prefer to just remove separators and limit ourselves to YYYYMMDD.
|
||||
@@ -77,7 +82,7 @@ function getNightlyPatch(plainPatch: string): string {
|
||||
const now = new Date();
|
||||
const timeStr = now.toISOString().replace(/:|T|\.|-/g, "").slice(0, 8);
|
||||
|
||||
return `${plainPatch}-dev.${timeStr}`;
|
||||
return `${plainPatch}-${tag}.${timeStr}`;
|
||||
}
|
||||
|
||||
main();
|
||||
+530
-460
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,384 @@
|
||||
/// <reference path="program.ts" />
|
||||
namespace ts {
|
||||
export interface EmitOutput {
|
||||
outputFiles: OutputFile[];
|
||||
emitSkipped: boolean;
|
||||
}
|
||||
|
||||
export interface OutputFile {
|
||||
name: string;
|
||||
writeByteOrderMark: boolean;
|
||||
text: string;
|
||||
}
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
export function getFileEmitOutput(program: Program, sourceFile: SourceFile, emitOnlyDtsFiles: boolean,
|
||||
cancellationToken?: CancellationToken, customTransformers?: CustomTransformers): EmitOutput {
|
||||
const outputFiles: OutputFile[] = [];
|
||||
const emitResult = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers);
|
||||
return { outputFiles, emitSkipped: emitResult.emitSkipped };
|
||||
|
||||
function writeFile(fileName: string, text: string, writeByteOrderMark: boolean) {
|
||||
outputFiles.push({ name: fileName, writeByteOrderMark, text });
|
||||
}
|
||||
}
|
||||
|
||||
export interface BuilderState {
|
||||
/**
|
||||
* Information of the file eg. its version, signature etc
|
||||
*/
|
||||
fileInfos: Map<BuilderState.FileInfo>;
|
||||
/**
|
||||
* Contains the map of ReferencedSet=Referenced files of the file if module emit is enabled
|
||||
* Otherwise undefined
|
||||
* Thus non undefined value indicates, module emit
|
||||
*/
|
||||
readonly referencedMap: ReadonlyMap<BuilderState.ReferencedSet> | undefined;
|
||||
/**
|
||||
* Map of files that have already called update signature.
|
||||
* That means hence forth these files are assumed to have
|
||||
* no change in their signature for this version of the program
|
||||
*/
|
||||
hasCalledUpdateShapeSignature: Map<true>;
|
||||
/**
|
||||
* Cache of all files excluding default library file for the current program
|
||||
*/
|
||||
allFilesExcludingDefaultLibraryFile: ReadonlyArray<SourceFile> | undefined;
|
||||
/**
|
||||
* Cache of all the file names
|
||||
*/
|
||||
allFileNames: ReadonlyArray<string> | undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
namespace ts.BuilderState {
|
||||
/**
|
||||
* Information about the source file: Its version and optional signature from last emit
|
||||
*/
|
||||
export interface FileInfo {
|
||||
readonly version: string;
|
||||
signature: string | undefined;
|
||||
}
|
||||
/**
|
||||
* Referenced files with values for the keys as referenced file's path to be true
|
||||
*/
|
||||
export type ReferencedSet = ReadonlyMap<true>;
|
||||
/**
|
||||
* Compute the hash to store the shape of the file
|
||||
*/
|
||||
export type ComputeHash = (data: string) => string;
|
||||
|
||||
/**
|
||||
* Gets the referenced files for a file from the program with values for the keys as referenced file's path to be true
|
||||
*/
|
||||
function getReferencedFiles(program: Program, sourceFile: SourceFile, getCanonicalFileName: GetCanonicalFileName): Map<true> | undefined {
|
||||
let referencedFiles: Map<true> | undefined;
|
||||
|
||||
// We need to use a set here since the code can contain the same import twice,
|
||||
// but that will only be one dependency.
|
||||
// To avoid invernal conversion, the key of the referencedFiles map must be of type Path
|
||||
if (sourceFile.imports && sourceFile.imports.length > 0) {
|
||||
const checker: TypeChecker = program.getTypeChecker();
|
||||
for (const importName of sourceFile.imports) {
|
||||
const symbol = checker.getSymbolAtLocation(importName);
|
||||
if (symbol && symbol.declarations && symbol.declarations[0]) {
|
||||
const declarationSourceFile = getSourceFileOfNode(symbol.declarations[0]);
|
||||
if (declarationSourceFile) {
|
||||
addReferencedFile(declarationSourceFile.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const sourceFileDirectory = getDirectoryPath(sourceFile.path);
|
||||
// Handle triple slash references
|
||||
if (sourceFile.referencedFiles && sourceFile.referencedFiles.length > 0) {
|
||||
for (const referencedFile of sourceFile.referencedFiles) {
|
||||
const referencedPath = toPath(referencedFile.fileName, sourceFileDirectory, getCanonicalFileName);
|
||||
addReferencedFile(referencedPath);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle type reference directives
|
||||
if (sourceFile.resolvedTypeReferenceDirectiveNames) {
|
||||
sourceFile.resolvedTypeReferenceDirectiveNames.forEach((resolvedTypeReferenceDirective) => {
|
||||
if (!resolvedTypeReferenceDirective) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fileName = resolvedTypeReferenceDirective.resolvedFileName;
|
||||
const typeFilePath = toPath(fileName, sourceFileDirectory, getCanonicalFileName);
|
||||
addReferencedFile(typeFilePath);
|
||||
});
|
||||
}
|
||||
|
||||
return referencedFiles;
|
||||
|
||||
function addReferencedFile(referencedPath: Path) {
|
||||
if (!referencedFiles) {
|
||||
referencedFiles = createMap<true>();
|
||||
}
|
||||
referencedFiles.set(referencedPath, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if oldState is reusable, that is the emitKind = module/non module has not changed
|
||||
*/
|
||||
export function canReuseOldState(newReferencedMap: ReadonlyMap<ReferencedSet>, oldState: Readonly<BuilderState> | undefined) {
|
||||
return oldState && !oldState.referencedMap === !newReferencedMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the state of file references and signature for the new program from oldState if it is safe
|
||||
*/
|
||||
export function create(newProgram: Program, getCanonicalFileName: GetCanonicalFileName, oldState?: Readonly<BuilderState>): BuilderState {
|
||||
const fileInfos = createMap<FileInfo>();
|
||||
const referencedMap = newProgram.getCompilerOptions().module !== ModuleKind.None ? createMap<ReferencedSet>() : undefined;
|
||||
const hasCalledUpdateShapeSignature = createMap<true>();
|
||||
const useOldState = canReuseOldState(referencedMap, oldState);
|
||||
|
||||
// Create the reference map, and set the file infos
|
||||
for (const sourceFile of newProgram.getSourceFiles()) {
|
||||
const version = sourceFile.version;
|
||||
const oldInfo = useOldState && oldState.fileInfos.get(sourceFile.path);
|
||||
if (referencedMap) {
|
||||
const newReferences = getReferencedFiles(newProgram, sourceFile, getCanonicalFileName);
|
||||
if (newReferences) {
|
||||
referencedMap.set(sourceFile.path, newReferences);
|
||||
}
|
||||
}
|
||||
fileInfos.set(sourceFile.path, { version, signature: oldInfo && oldInfo.signature });
|
||||
}
|
||||
|
||||
return {
|
||||
fileInfos,
|
||||
referencedMap,
|
||||
hasCalledUpdateShapeSignature,
|
||||
allFilesExcludingDefaultLibraryFile: undefined,
|
||||
allFileNames: undefined
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the files affected by the path from the program
|
||||
*/
|
||||
export function getFilesAffectedBy(state: BuilderState, programOfThisState: Program, path: Path, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, cacheToUpdateSignature?: Map<string>): ReadonlyArray<SourceFile> {
|
||||
// Since the operation could be cancelled, the signatures are always stored in the cache
|
||||
// They will be commited once it is safe to use them
|
||||
// eg when calling this api from tsserver, if there is no cancellation of the operation
|
||||
// In the other cases the affected files signatures are commited only after the iteration through the result is complete
|
||||
const signatureCache = cacheToUpdateSignature || createMap();
|
||||
const sourceFile = programOfThisState.getSourceFileByPath(path);
|
||||
if (!sourceFile) {
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
if (!updateShapeSignature(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash)) {
|
||||
return [sourceFile];
|
||||
}
|
||||
|
||||
const result = (state.referencedMap ? getFilesAffectedByUpdatedShapeWhenModuleEmit : getFilesAffectedByUpdatedShapeWhenNonModuleEmit)(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash);
|
||||
if (!cacheToUpdateSignature) {
|
||||
// Commit all the signatures in the signature cache
|
||||
updateSignaturesFromCache(state, signatureCache);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the signatures from the cache into state's fileinfo signatures
|
||||
* This should be called whenever it is safe to commit the state of the builder
|
||||
*/
|
||||
export function updateSignaturesFromCache(state: BuilderState, signatureCache: Map<string>) {
|
||||
signatureCache.forEach((signature, path) => {
|
||||
state.fileInfos.get(path).signature = signature;
|
||||
state.hasCalledUpdateShapeSignature.set(path, true);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the shape of the signature has changed since last emit
|
||||
*/
|
||||
function updateShapeSignature(state: Readonly<BuilderState>, programOfThisState: Program, sourceFile: SourceFile, cacheToUpdateSignature: Map<string>, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash) {
|
||||
Debug.assert(!!sourceFile);
|
||||
|
||||
// If we have cached the result for this file, that means hence forth we should assume file shape is uptodate
|
||||
if (state.hasCalledUpdateShapeSignature.has(sourceFile.path) || cacheToUpdateSignature.has(sourceFile.path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const info = state.fileInfos.get(sourceFile.path);
|
||||
Debug.assert(!!info);
|
||||
|
||||
const prevSignature = info.signature;
|
||||
let latestSignature: string;
|
||||
if (sourceFile.isDeclarationFile) {
|
||||
latestSignature = sourceFile.version;
|
||||
}
|
||||
else {
|
||||
const emitOutput = getFileEmitOutput(programOfThisState, sourceFile, /*emitOnlyDtsFiles*/ true, cancellationToken);
|
||||
if (emitOutput.outputFiles && emitOutput.outputFiles.length > 0) {
|
||||
latestSignature = computeHash(emitOutput.outputFiles[0].text);
|
||||
}
|
||||
else {
|
||||
latestSignature = prevSignature;
|
||||
}
|
||||
}
|
||||
cacheToUpdateSignature.set(sourceFile.path, latestSignature);
|
||||
|
||||
return !prevSignature || latestSignature !== prevSignature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the dependencies of the sourceFile
|
||||
*/
|
||||
export function getAllDependencies(state: BuilderState, programOfThisState: Program, sourceFile: SourceFile): ReadonlyArray<string> {
|
||||
const compilerOptions = programOfThisState.getCompilerOptions();
|
||||
// With --out or --outFile all outputs go into single file, all files depend on each other
|
||||
if (compilerOptions.outFile || compilerOptions.out) {
|
||||
return getAllFileNames(state, programOfThisState);
|
||||
}
|
||||
|
||||
// If this is non module emit, or its a global file, it depends on all the source files
|
||||
if (!state.referencedMap || (!isExternalModule(sourceFile) && !containsOnlyAmbientModules(sourceFile))) {
|
||||
return getAllFileNames(state, programOfThisState);
|
||||
}
|
||||
|
||||
// Get the references, traversing deep from the referenceMap
|
||||
const seenMap = createMap<true>();
|
||||
const queue = [sourceFile.path];
|
||||
while (queue.length) {
|
||||
const path = queue.pop();
|
||||
if (!seenMap.has(path)) {
|
||||
seenMap.set(path, true);
|
||||
const references = state.referencedMap.get(path);
|
||||
if (references) {
|
||||
const iterator = references.keys();
|
||||
for (let { value, done } = iterator.next(); !done; { value, done } = iterator.next()) {
|
||||
queue.push(value as Path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return arrayFrom(mapDefinedIterator(seenMap.keys(), path => {
|
||||
const file = programOfThisState.getSourceFileByPath(path as Path);
|
||||
return file ? file.fileName : path;
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the names of all files from the program
|
||||
*/
|
||||
function getAllFileNames(state: BuilderState, programOfThisState: Program): ReadonlyArray<string> {
|
||||
if (!state.allFileNames) {
|
||||
const sourceFiles = programOfThisState.getSourceFiles();
|
||||
state.allFileNames = sourceFiles === emptyArray ? emptyArray : sourceFiles.map(file => file.fileName);
|
||||
}
|
||||
return state.allFileNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the files referenced by the the file path
|
||||
*/
|
||||
function getReferencedByPaths(state: Readonly<BuilderState>, referencedFilePath: Path) {
|
||||
return arrayFrom(mapDefinedIterator(state.referencedMap.entries(), ([filePath, referencesInFile]) =>
|
||||
referencesInFile.has(referencedFilePath) ? filePath as Path : undefined
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* For script files that contains only ambient external modules, although they are not actually external module files,
|
||||
* they can only be consumed via importing elements from them. Regular script files cannot consume them. Therefore,
|
||||
* there are no point to rebuild all script files if these special files have changed. However, if any statement
|
||||
* in the file is not ambient external module, we treat it as a regular script file.
|
||||
*/
|
||||
function containsOnlyAmbientModules(sourceFile: SourceFile) {
|
||||
for (const statement of sourceFile.statements) {
|
||||
if (!isModuleWithStringLiteralName(statement)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all files of the program excluding the default library file
|
||||
*/
|
||||
function getAllFilesExcludingDefaultLibraryFile(state: BuilderState, programOfThisState: Program, firstSourceFile: SourceFile): ReadonlyArray<SourceFile> {
|
||||
// Use cached result
|
||||
if (state.allFilesExcludingDefaultLibraryFile) {
|
||||
return state.allFilesExcludingDefaultLibraryFile;
|
||||
}
|
||||
|
||||
let result: SourceFile[];
|
||||
addSourceFile(firstSourceFile);
|
||||
for (const sourceFile of programOfThisState.getSourceFiles()) {
|
||||
if (sourceFile !== firstSourceFile) {
|
||||
addSourceFile(sourceFile);
|
||||
}
|
||||
}
|
||||
state.allFilesExcludingDefaultLibraryFile = result || emptyArray;
|
||||
return state.allFilesExcludingDefaultLibraryFile;
|
||||
|
||||
function addSourceFile(sourceFile: SourceFile) {
|
||||
if (!programOfThisState.isSourceFileDefaultLibrary(sourceFile)) {
|
||||
(result || (result = [])).push(sourceFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When program emits non modular code, gets the files affected by the sourceFile whose shape has changed
|
||||
*/
|
||||
function getFilesAffectedByUpdatedShapeWhenNonModuleEmit(state: BuilderState, programOfThisState: Program, sourceFileWithUpdatedShape: SourceFile) {
|
||||
const compilerOptions = programOfThisState.getCompilerOptions();
|
||||
// If `--out` or `--outFile` is specified, any new emit will result in re-emitting the entire project,
|
||||
// so returning the file itself is good enough.
|
||||
if (compilerOptions && (compilerOptions.out || compilerOptions.outFile)) {
|
||||
return [sourceFileWithUpdatedShape];
|
||||
}
|
||||
return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape);
|
||||
}
|
||||
|
||||
/**
|
||||
* When program emits modular code, gets the files affected by the sourceFile whose shape has changed
|
||||
*/
|
||||
function getFilesAffectedByUpdatedShapeWhenModuleEmit(state: BuilderState, programOfThisState: Program, sourceFileWithUpdatedShape: SourceFile, cacheToUpdateSignature: Map<string>, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash | undefined) {
|
||||
if (!isExternalModule(sourceFileWithUpdatedShape) && !containsOnlyAmbientModules(sourceFileWithUpdatedShape)) {
|
||||
return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape);
|
||||
}
|
||||
|
||||
const compilerOptions = programOfThisState.getCompilerOptions();
|
||||
if (compilerOptions && (compilerOptions.isolatedModules || compilerOptions.out || compilerOptions.outFile)) {
|
||||
return [sourceFileWithUpdatedShape];
|
||||
}
|
||||
|
||||
// Now we need to if each file in the referencedBy list has a shape change as well.
|
||||
// Because if so, its own referencedBy files need to be saved as well to make the
|
||||
// emitting result consistent with files on disk.
|
||||
const seenFileNamesMap = createMap<SourceFile>();
|
||||
|
||||
// Start with the paths this file was referenced by
|
||||
seenFileNamesMap.set(sourceFileWithUpdatedShape.path, sourceFileWithUpdatedShape);
|
||||
const queue = getReferencedByPaths(state, sourceFileWithUpdatedShape.path);
|
||||
while (queue.length > 0) {
|
||||
const currentPath = queue.pop();
|
||||
if (!seenFileNamesMap.has(currentPath)) {
|
||||
const currentSourceFile = programOfThisState.getSourceFileByPath(currentPath);
|
||||
seenFileNamesMap.set(currentPath, currentSourceFile);
|
||||
if (currentSourceFile && updateShapeSignature(state, programOfThisState, currentSourceFile, cacheToUpdateSignature, cancellationToken, computeHash)) {
|
||||
queue.push(...getReferencedByPaths(state, currentPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return array of values that needs emit
|
||||
// Return array of values that needs emit
|
||||
return arrayFrom(mapDefinedIterator(seenFileNamesMap.values(), value => value));
|
||||
}
|
||||
}
|
||||
+112
-73
@@ -295,6 +295,10 @@ namespace ts {
|
||||
getAccessibleSymbolChain,
|
||||
getTypePredicateOfSignature,
|
||||
resolveExternalModuleSymbol,
|
||||
tryGetThisTypeAt: node => {
|
||||
node = getParseTreeNode(node);
|
||||
return node && tryGetThisTypeAt(node);
|
||||
},
|
||||
};
|
||||
|
||||
const tupleTypes: GenericType[] = [];
|
||||
@@ -747,10 +751,12 @@ namespace ts {
|
||||
return _jsxNamespace;
|
||||
}
|
||||
|
||||
function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken) {
|
||||
function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken, ignoreDiagnostics?: boolean) {
|
||||
// Ensure we have all the type information in place for this file so that all the
|
||||
// emitter questions of this resolver will return the right information.
|
||||
getDiagnostics(sourceFile, cancellationToken);
|
||||
if (!ignoreDiagnostics) {
|
||||
getDiagnostics(sourceFile, cancellationToken);
|
||||
}
|
||||
return emitResolver;
|
||||
}
|
||||
|
||||
@@ -2066,9 +2072,9 @@ namespace ts {
|
||||
error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName);
|
||||
}
|
||||
else if (noImplicitAny && moduleNotFoundError) {
|
||||
let errorInfo = !resolvedModule.isExternalLibraryImport ? undefined : chainDiagnosticMessages(/*details*/ undefined,
|
||||
let errorInfo = resolvedModule.packageId && chainDiagnosticMessages(/*details*/ undefined,
|
||||
Diagnostics.Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0,
|
||||
moduleReference);
|
||||
resolvedModule.packageId.name);
|
||||
errorInfo = chainDiagnosticMessages(errorInfo,
|
||||
Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type,
|
||||
moduleReference,
|
||||
@@ -2425,12 +2431,15 @@ namespace ts {
|
||||
const visitedSymbolTables: SymbolTable[] = [];
|
||||
return forEachSymbolTableInScope(enclosingDeclaration, getAccessibleSymbolChainFromSymbolTable);
|
||||
|
||||
function getAccessibleSymbolChainFromSymbolTable(symbols: SymbolTable): Symbol[] | undefined {
|
||||
/**
|
||||
* @param {ignoreQualification} boolean Set when a symbol is being looked for through the exports of another symbol (meaning we have a route to qualify it already)
|
||||
*/
|
||||
function getAccessibleSymbolChainFromSymbolTable(symbols: SymbolTable, ignoreQualification?: boolean): Symbol[] | undefined {
|
||||
if (!pushIfUnique(visitedSymbolTables, symbols)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const result = trySymbolTable(symbols);
|
||||
const result = trySymbolTable(symbols, ignoreQualification);
|
||||
visitedSymbolTables.pop();
|
||||
return result;
|
||||
}
|
||||
@@ -2442,22 +2451,22 @@ namespace ts {
|
||||
!!getAccessibleSymbolChain(symbolFromSymbolTable.parent, enclosingDeclaration, getQualifiedLeftMeaning(meaning), useOnlyExternalAliasing);
|
||||
}
|
||||
|
||||
function isAccessible(symbolFromSymbolTable: Symbol, resolvedAliasSymbol?: Symbol) {
|
||||
function isAccessible(symbolFromSymbolTable: Symbol, resolvedAliasSymbol?: Symbol, ignoreQualification?: boolean) {
|
||||
return symbol === (resolvedAliasSymbol || symbolFromSymbolTable) &&
|
||||
// if the symbolFromSymbolTable is not external module (it could be if it was determined as ambient external module and would be in globals table)
|
||||
// and if symbolFromSymbolTable or alias resolution matches the symbol,
|
||||
// check the symbol can be qualified, it is only then this symbol is accessible
|
||||
!some(symbolFromSymbolTable.declarations, hasExternalModuleSymbol) &&
|
||||
canQualifySymbol(symbolFromSymbolTable, meaning);
|
||||
(ignoreQualification || canQualifySymbol(symbolFromSymbolTable, meaning));
|
||||
}
|
||||
|
||||
function isUMDExportSymbol(symbol: Symbol) {
|
||||
return symbol && symbol.declarations && symbol.declarations[0] && isNamespaceExportDeclaration(symbol.declarations[0]);
|
||||
}
|
||||
|
||||
function trySymbolTable(symbols: SymbolTable) {
|
||||
function trySymbolTable(symbols: SymbolTable, ignoreQualification: boolean | undefined) {
|
||||
// If symbol is directly available by its name in the symbol table
|
||||
if (isAccessible(symbols.get(symbol.escapedName))) {
|
||||
if (isAccessible(symbols.get(symbol.escapedName), /*resolvedAliasSymbol*/ undefined, ignoreQualification)) {
|
||||
return [symbol];
|
||||
}
|
||||
|
||||
@@ -2470,14 +2479,14 @@ namespace ts {
|
||||
&& (!useOnlyExternalAliasing || some(symbolFromSymbolTable.declarations, isExternalModuleImportEqualsDeclaration))) {
|
||||
|
||||
const resolvedImportedSymbol = resolveAlias(symbolFromSymbolTable);
|
||||
if (isAccessible(symbolFromSymbolTable, resolvedImportedSymbol)) {
|
||||
if (isAccessible(symbolFromSymbolTable, resolvedImportedSymbol, ignoreQualification)) {
|
||||
return [symbolFromSymbolTable];
|
||||
}
|
||||
|
||||
// Look in the exported members, if we can find accessibleSymbolChain, symbol is accessible using this chain
|
||||
// but only if the symbolFromSymbolTable can be qualified
|
||||
const candidateTable = getExportsOfSymbol(resolvedImportedSymbol);
|
||||
const accessibleSymbolsFromExports = candidateTable && getAccessibleSymbolChainFromSymbolTable(candidateTable);
|
||||
const accessibleSymbolsFromExports = candidateTable && getAccessibleSymbolChainFromSymbolTable(candidateTable, /*ignoreQualification*/ true);
|
||||
if (accessibleSymbolsFromExports && canQualifySymbol(symbolFromSymbolTable, getQualifiedLeftMeaning(meaning))) {
|
||||
return [symbolFromSymbolTable].concat(accessibleSymbolsFromExports);
|
||||
}
|
||||
@@ -3962,7 +3971,8 @@ namespace ts {
|
||||
if (strictNullChecks && declaration.flags & NodeFlags.Ambient && isParameterDeclaration(declaration)) {
|
||||
parentType = getNonNullableType(parentType);
|
||||
}
|
||||
const declaredType = getTypeOfPropertyOfType(parentType, text);
|
||||
const propType = getTypeOfPropertyOfType(parentType, text);
|
||||
const declaredType = propType && getApparentTypeForLocation(propType, declaration.name);
|
||||
type = declaredType && getFlowTypeOfReference(declaration, declaredType) ||
|
||||
isNumericLiteralName(text) && getIndexTypeOfType(parentType, IndexKind.Number) ||
|
||||
getIndexTypeOfType(parentType, IndexKind.String);
|
||||
@@ -5433,18 +5443,19 @@ namespace ts {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
function getTypeWithThisArgument(type: Type, thisArgument?: Type): Type {
|
||||
function getTypeWithThisArgument(type: Type, thisArgument?: Type, needApparentType?: boolean): Type {
|
||||
if (getObjectFlags(type) & ObjectFlags.Reference) {
|
||||
const target = (<TypeReference>type).target;
|
||||
const typeArguments = (<TypeReference>type).typeArguments;
|
||||
if (length(target.typeParameters) === length(typeArguments)) {
|
||||
return createTypeReference(target, concatenate(typeArguments, [thisArgument || target.thisType]));
|
||||
const ref = createTypeReference(target, concatenate(typeArguments, [thisArgument || target.thisType]));
|
||||
return needApparentType ? getApparentType(ref) : ref;
|
||||
}
|
||||
}
|
||||
else if (type.flags & TypeFlags.Intersection) {
|
||||
return getIntersectionType(map((<IntersectionType>type).types, t => getTypeWithThisArgument(t, thisArgument)));
|
||||
return getIntersectionType(map((<IntersectionType>type).types, t => getTypeWithThisArgument(t, thisArgument, needApparentType)));
|
||||
}
|
||||
return type;
|
||||
return needApparentType ? getApparentType(type) : type;
|
||||
}
|
||||
|
||||
function resolveObjectTypeMembers(type: ObjectType, source: InterfaceTypeWithDeclaredMembers, typeParameters: TypeParameter[], typeArguments: Type[]) {
|
||||
@@ -6008,7 +6019,9 @@ namespace ts {
|
||||
for (const memberType of types) {
|
||||
for (const { escapedName } of getAugmentedPropertiesOfType(memberType)) {
|
||||
if (!props.has(escapedName)) {
|
||||
props.set(escapedName, createUnionOrIntersectionProperty(unionType as UnionType, escapedName));
|
||||
const prop = createUnionOrIntersectionProperty(unionType as UnionType, escapedName);
|
||||
// May be undefined if the property is private
|
||||
if (prop) props.set(escapedName, prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6155,7 +6168,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getApparentTypeOfIntersectionType(type: IntersectionType) {
|
||||
return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type));
|
||||
return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type, /*apparentType*/ true));
|
||||
}
|
||||
|
||||
function getResolvedTypeParameterDefault(typeParameter: TypeParameter): Type | undefined {
|
||||
@@ -6221,7 +6234,7 @@ namespace ts {
|
||||
t;
|
||||
}
|
||||
|
||||
function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol {
|
||||
function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol | undefined {
|
||||
let props: Symbol[];
|
||||
const isUnion = containingType.flags & TypeFlags.Union;
|
||||
const excludeModifiers = isUnion ? ModifierFlags.NonPublicAccessibilityModifier : 0;
|
||||
@@ -6609,7 +6622,7 @@ namespace ts {
|
||||
// b) It references `arguments` somewhere
|
||||
const lastParam = lastOrUndefined(declaration.parameters);
|
||||
const lastParamTags = lastParam && getJSDocParameterTags(lastParam);
|
||||
const lastParamVariadicType = lastParamTags && firstDefined(lastParamTags, p =>
|
||||
const lastParamVariadicType = firstDefined(lastParamTags, p =>
|
||||
p.typeExpression && isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined);
|
||||
if (!lastParamVariadicType && !containsArgumentsReference(declaration)) {
|
||||
return false;
|
||||
@@ -8490,11 +8503,18 @@ namespace ts {
|
||||
|
||||
function instantiateList<T>(items: T[], mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): T[] {
|
||||
if (items && items.length) {
|
||||
const result: T[] = [];
|
||||
for (const v of items) {
|
||||
result.push(instantiator(v, mapper));
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const item = items[i];
|
||||
const mapped = instantiator(item, mapper);
|
||||
if (item !== mapped) {
|
||||
const result = i === 0 ? [] : items.slice(0, i);
|
||||
result.push(mapped);
|
||||
for (i++; i < items.length; i++) {
|
||||
result.push(instantiator(items[i], mapper));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return items;
|
||||
}
|
||||
@@ -8620,8 +8640,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
function instantiateSymbol(symbol: Symbol, mapper: TypeMapper): Symbol {
|
||||
const links = getSymbolLinks(symbol);
|
||||
if (links.type && !maybeTypeOfKind(links.type, TypeFlags.Object | TypeFlags.Instantiable)) {
|
||||
// If the type of the symbol is already resolved, and if that type could not possibly
|
||||
// be affected by instantiation, simply return the symbol itself.
|
||||
return symbol;
|
||||
}
|
||||
if (getCheckFlags(symbol) & CheckFlags.Instantiated) {
|
||||
const links = getSymbolLinks(symbol);
|
||||
// If symbol being instantiated is itself a instantiation, fetch the original target and combine the
|
||||
// type mappers. This ensures that original type identities are properly preserved and that aliases
|
||||
// always reference a non-aliases.
|
||||
@@ -8785,14 +8810,20 @@ namespace ts {
|
||||
return getAnonymousTypeInstantiation(<MappedType>type, mapper);
|
||||
}
|
||||
if ((<ObjectType>type).objectFlags & ObjectFlags.Reference) {
|
||||
return createTypeReference((<TypeReference>type).target, instantiateTypes((<TypeReference>type).typeArguments, mapper));
|
||||
const typeArguments = (<TypeReference>type).typeArguments;
|
||||
const newTypeArguments = instantiateTypes(typeArguments, mapper);
|
||||
return newTypeArguments !== typeArguments ? createTypeReference((<TypeReference>type).target, newTypeArguments) : type;
|
||||
}
|
||||
}
|
||||
if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Primitive)) {
|
||||
return getUnionType(instantiateTypes((<UnionType>type).types, mapper), UnionReduction.Literal, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
const types = (<UnionType>type).types;
|
||||
const newTypes = instantiateTypes(types, mapper);
|
||||
return newTypes !== types ? getUnionType(newTypes, UnionReduction.Literal, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)) : type;
|
||||
}
|
||||
if (type.flags & TypeFlags.Intersection) {
|
||||
return getIntersectionType(instantiateTypes((<IntersectionType>type).types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
const types = (<IntersectionType>type).types;
|
||||
const newTypes = instantiateTypes(types, mapper);
|
||||
return newTypes !== types ? getIntersectionType(newTypes, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)) : type;
|
||||
}
|
||||
if (type.flags & TypeFlags.Index) {
|
||||
return getIndexType(instantiateType((<IndexType>type).type, mapper));
|
||||
@@ -9428,7 +9459,8 @@ namespace ts {
|
||||
isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True;
|
||||
|
||||
if (isObjectLiteralType(source) && source.flags & TypeFlags.FreshLiteral) {
|
||||
if (hasExcessProperties(<FreshObjectLiteralType>source, target, reportErrors)) {
|
||||
const discriminantType = target.flags & TypeFlags.Union ? findMatchingDiscriminantType(source, target as UnionType) : undefined;
|
||||
if (hasExcessProperties(<FreshObjectLiteralType>source, target, discriminantType, reportErrors)) {
|
||||
if (reportErrors) {
|
||||
reportRelationError(headMessage, source, target);
|
||||
}
|
||||
@@ -9438,7 +9470,7 @@ namespace ts {
|
||||
// and intersection types are further deconstructed on the target side, we don't want to
|
||||
// make the check again (as it might fail for a partial target type). Therefore we obtain
|
||||
// the regular source type and proceed with that.
|
||||
if (isUnionOrIntersectionTypeWithoutNullableConstituents(target)) {
|
||||
if (isUnionOrIntersectionTypeWithoutNullableConstituents(target) && !discriminantType) {
|
||||
source = getRegularTypeOfObjectLiteral(source);
|
||||
}
|
||||
}
|
||||
@@ -9539,19 +9571,16 @@ namespace ts {
|
||||
return Ternary.False;
|
||||
}
|
||||
|
||||
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean {
|
||||
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, discriminant: Type | undefined, reportErrors: boolean): boolean {
|
||||
if (maybeTypeOfKind(target, TypeFlags.Object) && !(getObjectFlags(target) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) {
|
||||
const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes);
|
||||
if ((relation === assignableRelation || relation === definitelyAssignableRelation || relation === comparableRelation) &&
|
||||
(isTypeSubsetOf(globalObjectType, target) || (!isComparingJsxAttributes && isEmptyObjectType(target)))) {
|
||||
return false;
|
||||
}
|
||||
if (target.flags & TypeFlags.Union) {
|
||||
const discriminantType = findMatchingDiscriminantType(source, target as UnionType);
|
||||
if (discriminantType) {
|
||||
// check excess properties against discriminant type only, not the entire union
|
||||
return hasExcessProperties(source, discriminantType, reportErrors);
|
||||
}
|
||||
if (discriminant) {
|
||||
// check excess properties against discriminant type only, not the entire union
|
||||
return hasExcessProperties(source, discriminant, /*discriminant*/ undefined, reportErrors);
|
||||
}
|
||||
for (const prop of getPropertiesOfObjectType(source)) {
|
||||
if (!isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) {
|
||||
@@ -9904,10 +9933,11 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (target.flags & TypeFlags.IndexedAccess && (<IndexedAccessType>source).indexType === (<IndexedAccessType>target).indexType) {
|
||||
// if we have indexed access types with identical index types, see if relationship holds for
|
||||
// the two object types.
|
||||
else if (target.flags & TypeFlags.IndexedAccess) {
|
||||
if (result = isRelatedTo((<IndexedAccessType>source).objectType, (<IndexedAccessType>target).objectType, reportErrors)) {
|
||||
result &= isRelatedTo((<IndexedAccessType>source).indexType, (<IndexedAccessType>target).indexType, reportErrors);
|
||||
}
|
||||
if (result) {
|
||||
errorInfo = saveErrorInfo;
|
||||
return result;
|
||||
}
|
||||
@@ -11203,7 +11233,7 @@ namespace ts {
|
||||
return type === typeParameter || type.flags & TypeFlags.UnionOrIntersection && forEach((<UnionOrIntersectionType>type).types, t => isTypeParameterAtTopLevel(t, typeParameter));
|
||||
}
|
||||
|
||||
/** Create an object with properties named in the string literal type. Every property has type `{}` */
|
||||
/** Create an object with properties named in the string literal type. Every property has type `any` */
|
||||
function createEmptyObjectTypeFromStringLiteral(type: Type) {
|
||||
const members = createSymbolTable();
|
||||
forEachType(type, t => {
|
||||
@@ -11212,7 +11242,7 @@ namespace ts {
|
||||
}
|
||||
const name = escapeLeadingUnderscores((t as StringLiteralType).value);
|
||||
const literalProp = createSymbol(SymbolFlags.Property, name);
|
||||
literalProp.type = emptyObjectType;
|
||||
literalProp.type = anyType;
|
||||
if (t.symbol) {
|
||||
literalProp.declarations = t.symbol.declarations;
|
||||
literalProp.valueDeclaration = t.symbol.valueDeclaration;
|
||||
@@ -12017,16 +12047,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getTypeWithFacts(type: Type, include: TypeFacts) {
|
||||
if (type.flags & TypeFlags.IndexedAccess) {
|
||||
// TODO (weswig): This is a substitute for a lazy negated type to remove the types indicated by the TypeFacts from the (potential) union the IndexedAccess refers to
|
||||
// - See discussion in https://github.com/Microsoft/TypeScript/pull/19275 for details, and test `strictNullNotNullIndexTypeShouldWork` for current behavior
|
||||
const baseConstraint = getBaseConstraintOfType(type) || emptyObjectType;
|
||||
const result = filterType(baseConstraint, t => (getTypeFacts(t) & include) !== 0);
|
||||
if (result !== baseConstraint) {
|
||||
return result;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
return filterType(type, t => (getTypeFacts(t) & include) !== 0);
|
||||
}
|
||||
|
||||
@@ -13140,19 +13160,20 @@ namespace ts {
|
||||
const parent = node.parent;
|
||||
return parent.kind === SyntaxKind.PropertyAccessExpression ||
|
||||
parent.kind === SyntaxKind.CallExpression && (<CallExpression>parent).expression === node ||
|
||||
parent.kind === SyntaxKind.ElementAccessExpression && (<ElementAccessExpression>parent).expression === node;
|
||||
parent.kind === SyntaxKind.ElementAccessExpression && (<ElementAccessExpression>parent).expression === node ||
|
||||
parent.kind === SyntaxKind.NonNullExpression ||
|
||||
parent.kind === SyntaxKind.BindingElement && (<BindingElement>parent).name === node && !!(<BindingElement>parent).initializer;
|
||||
}
|
||||
|
||||
function typeHasNullableConstraint(type: Type) {
|
||||
return type.flags & TypeFlags.InstantiableNonPrimitive && maybeTypeOfKind(getBaseConstraintOfType(type) || emptyObjectType, TypeFlags.Nullable);
|
||||
}
|
||||
|
||||
function getDeclaredOrApparentType(symbol: Symbol, node: Node) {
|
||||
function getApparentTypeForLocation(type: Type, node: Node) {
|
||||
// When a node is the left hand expression of a property access, element access, or call expression,
|
||||
// and the type of the node includes type variables with constraints that are nullable, we fetch the
|
||||
// apparent type of the node *before* performing control flow analysis such that narrowings apply to
|
||||
// the constraint type.
|
||||
const type = getTypeOfSymbol(symbol);
|
||||
if (isApparentTypePosition(node) && forEachType(type, typeHasNullableConstraint)) {
|
||||
return mapType(getWidenedType(type), getApparentType);
|
||||
}
|
||||
@@ -13242,7 +13263,7 @@ namespace ts {
|
||||
checkCollisionWithCapturedNewTargetVariable(node, node);
|
||||
checkNestedBlockScopedBinding(node, symbol);
|
||||
|
||||
const type = getDeclaredOrApparentType(localOrExportSymbol, node);
|
||||
const type = getApparentTypeForLocation(getTypeOfSymbol(localOrExportSymbol), node);
|
||||
const assignmentKind = getAssignmentTargetKind(node);
|
||||
|
||||
if (assignmentKind) {
|
||||
@@ -13301,7 +13322,7 @@ namespace ts {
|
||||
node.parent.kind === SyntaxKind.NonNullExpression ||
|
||||
declaration.kind === SyntaxKind.VariableDeclaration && (<VariableDeclaration>declaration).exclamationToken ||
|
||||
declaration.flags & NodeFlags.Ambient;
|
||||
const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, getRootDeclaration(declaration) as VariableLikeDeclaration) : type) :
|
||||
const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, declaration as VariableLikeDeclaration) : type) :
|
||||
type === autoType || type === autoArrayType ? undefinedType :
|
||||
getOptionalType(type);
|
||||
const flowType = getFlowTypeOfReference(node, type, initialType, flowContainer, !assumeInitialized);
|
||||
@@ -13525,6 +13546,16 @@ namespace ts {
|
||||
if (needToCaptureLexicalThis) {
|
||||
captureLexicalThis(node, container);
|
||||
}
|
||||
|
||||
const type = tryGetThisTypeAt(node, container);
|
||||
if (!type && noImplicitThis) {
|
||||
// With noImplicitThis, functions may not reference 'this' if it has type 'any'
|
||||
error(node, Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation);
|
||||
}
|
||||
return type || anyType;
|
||||
}
|
||||
|
||||
function tryGetThisTypeAt(node: Node, container = getThisContainer(node, /*includeArrowFunctions*/ false)): Type | undefined {
|
||||
if (isFunctionLike(container) &&
|
||||
(!isInParameterInitializerBeforeContainingFunction(node) || getThisParameter(container))) {
|
||||
// Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
|
||||
@@ -13563,12 +13594,6 @@ namespace ts {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
if (noImplicitThis) {
|
||||
// With noImplicitThis, functions may not reference 'this' if it has type 'any'
|
||||
error(node, Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation);
|
||||
}
|
||||
return anyType;
|
||||
}
|
||||
|
||||
function getTypeForThisExpressionFromJSDoc(node: Node) {
|
||||
@@ -14317,7 +14342,7 @@ namespace ts {
|
||||
// If the given type is an object or union type with a single signature, and if that signature has at
|
||||
// least as many parameters as the given function, return the signature. Otherwise return undefined.
|
||||
function getContextualCallSignature(type: Type, node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature {
|
||||
const signatures = getSignaturesOfStructuredType(type, SignatureKind.Call);
|
||||
const signatures = getSignaturesOfType(type, SignatureKind.Call);
|
||||
if (signatures.length === 1) {
|
||||
const signature = signatures[0];
|
||||
if (!isAritySmaller(signature, node)) {
|
||||
@@ -15560,7 +15585,7 @@ namespace ts {
|
||||
|
||||
// If the targetAttributesType is an emptyObjectType, indicating that there is no property named 'props' on this instance type.
|
||||
// but there exists a sourceAttributesType, we need to explicitly give an error as normal assignability check allow excess properties and will pass.
|
||||
if (targetAttributesType === emptyObjectType && (isTypeAny(sourceAttributesType) || (<ResolvedType>sourceAttributesType).properties.length > 0)) {
|
||||
if (targetAttributesType === emptyObjectType && (isTypeAny(sourceAttributesType) || getPropertiesOfType(<ResolvedType>sourceAttributesType).length > 0)) {
|
||||
error(openingLikeElement, Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, unescapeLeadingUnderscores(getJsxElementPropertiesName()));
|
||||
}
|
||||
else {
|
||||
@@ -15805,7 +15830,7 @@ namespace ts {
|
||||
return unknownType;
|
||||
}
|
||||
}
|
||||
propType = getDeclaredOrApparentType(prop, node);
|
||||
propType = getApparentTypeForLocation(getTypeOfSymbol(prop), node);
|
||||
}
|
||||
// Only compute control flow type if this is a property access expression that isn't an
|
||||
// assignment target, and the referenced property was declared as a variable, property,
|
||||
@@ -16967,7 +16992,7 @@ namespace ts {
|
||||
const isDecorator = node.kind === SyntaxKind.Decorator;
|
||||
const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node);
|
||||
|
||||
let typeArguments: ReadonlyArray<TypeNode>;
|
||||
let typeArguments: NodeArray<TypeNode>;
|
||||
|
||||
if (!isTaggedTemplate && !isDecorator && !isJsxOpeningOrSelfClosingElement) {
|
||||
typeArguments = (<CallExpression>node).typeArguments;
|
||||
@@ -17096,7 +17121,7 @@ namespace ts {
|
||||
max = Math.max(max, length(sig.typeParameters));
|
||||
}
|
||||
const paramCount = min < max ? min + "-" + max : min;
|
||||
diagnostics.add(createDiagnosticForNode(node, Diagnostics.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.length));
|
||||
diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.length));
|
||||
}
|
||||
else if (args) {
|
||||
let min = Number.POSITIVE_INFINITY;
|
||||
@@ -18624,6 +18649,9 @@ namespace ts {
|
||||
|
||||
function checkObjectLiteralAssignment(node: ObjectLiteralExpression, sourceType: Type): Type {
|
||||
const properties = node.properties;
|
||||
if (strictNullChecks && properties.length === 0) {
|
||||
return checkNonNullType(sourceType, node);
|
||||
}
|
||||
for (const p of properties) {
|
||||
checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, properties);
|
||||
}
|
||||
@@ -21224,7 +21252,7 @@ namespace ts {
|
||||
error(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local));
|
||||
}
|
||||
}
|
||||
else if (compilerOptions.noUnusedLocals) {
|
||||
else if (local.flags & SymbolFlags.TypeParameter ? compilerOptions.noUnusedParameters : compilerOptions.noUnusedLocals) {
|
||||
forEach(local.declarations, d => errorUnusedLocal(d, symbolName(local)));
|
||||
}
|
||||
}
|
||||
@@ -21288,6 +21316,7 @@ namespace ts {
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.IndexSignature:
|
||||
case SyntaxKind.SemicolonClassElement:
|
||||
// Can't be private
|
||||
break;
|
||||
default:
|
||||
@@ -21298,7 +21327,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkUnusedTypeParameters(node: ClassDeclaration | ClassExpression | FunctionDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction | ConstructorDeclaration | SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration) {
|
||||
if (compilerOptions.noUnusedLocals && !(node.flags & NodeFlags.Ambient)) {
|
||||
if (compilerOptions.noUnusedParameters && !(node.flags & NodeFlags.Ambient)) {
|
||||
if (node.typeParameters) {
|
||||
// Only report errors on the last declaration for the type parameter container;
|
||||
// this ensures that all uses have been accounted for.
|
||||
@@ -21704,7 +21733,13 @@ namespace ts {
|
||||
if (isBindingPattern(node.name)) {
|
||||
// Don't validate for-in initializer as it is already an error
|
||||
if (node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) {
|
||||
checkTypeAssignableTo(checkExpressionCached(node.initializer), getWidenedTypeForVariableLikeDeclaration(node), node, /*headMessage*/ undefined);
|
||||
const initializerType = checkExpressionCached(node.initializer);
|
||||
if (strictNullChecks && node.name.elements.length === 0) {
|
||||
checkNonNullType(initializerType, node);
|
||||
}
|
||||
else {
|
||||
checkTypeAssignableTo(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, /*headMessage*/ undefined);
|
||||
}
|
||||
checkParameterInitializer(node);
|
||||
}
|
||||
return;
|
||||
@@ -26458,7 +26493,7 @@ namespace ts {
|
||||
function checkGrammarBindingElement(node: BindingElement) {
|
||||
if (node.dotDotDotToken) {
|
||||
const elements = (<BindingPattern>node.parent).elements;
|
||||
if (node !== lastOrUndefined(elements)) {
|
||||
if (node !== last(elements)) {
|
||||
return grammarErrorOnNode(node, Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
|
||||
}
|
||||
|
||||
@@ -26466,6 +26501,10 @@ namespace ts {
|
||||
return grammarErrorOnNode(node.name, Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
|
||||
}
|
||||
|
||||
if (node.propertyName) {
|
||||
return grammarErrorOnNode(node.name, Diagnostics.A_rest_element_cannot_have_a_property_name);
|
||||
}
|
||||
|
||||
if (node.initializer) {
|
||||
// Error on equals token which immediately precedes the initializer
|
||||
return grammarErrorAtPos(node, node.initializer.pos - 1, 1, Diagnostics.A_rest_element_cannot_have_an_initializer);
|
||||
|
||||
@@ -186,6 +186,12 @@ namespace ts {
|
||||
category: Diagnostics.Basic_Options,
|
||||
description: Diagnostics.Generates_corresponding_d_ts_file,
|
||||
},
|
||||
{
|
||||
name: "emitDeclarationsOnly",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Only_emit_d_ts_declaration_files,
|
||||
},
|
||||
{
|
||||
name: "sourceMap",
|
||||
type: "boolean",
|
||||
|
||||
+25
-223
@@ -4,7 +4,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 = "2.7";
|
||||
export const versionMajorMinor = "2.8";
|
||||
/** The version of the TypeScript compiler release */
|
||||
export const version = `${versionMajorMinor}.0`;
|
||||
}
|
||||
@@ -16,10 +16,15 @@ namespace ts {
|
||||
// Update: We also consider a path like `C:\foo.ts` "relative" because we do not search for it in `node_modules` or treat it as an ambient module.
|
||||
return pathIsRelative(moduleName) || isRootedDiskPath(moduleName);
|
||||
}
|
||||
|
||||
export function sortAndDeduplicateDiagnostics(diagnostics: ReadonlyArray<Diagnostic>): Diagnostic[] {
|
||||
return sortAndDeduplicate(diagnostics, compareDiagnostics);
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export const emptyArray: never[] = [] as never[];
|
||||
/** Create a MapLike with good performance. */
|
||||
function createDictionaryObject<T>(): MapLike<T> {
|
||||
const map = Object.create(/*prototype*/ null); // tslint:disable-line:no-null-keyword
|
||||
@@ -182,6 +187,10 @@ namespace ts {
|
||||
|
||||
/** Like `forEach`, but suitable for use with numbers and strings (which may be falsy). */
|
||||
export function firstDefined<T, U>(array: ReadonlyArray<T> | undefined, callback: (element: T, index: number) => U | undefined): U | undefined {
|
||||
if (array === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const result = callback(array[i], i);
|
||||
if (result !== undefined) {
|
||||
@@ -335,6 +344,10 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function arraysEqual<T>(a: ReadonlyArray<T>, b: ReadonlyArray<T>, equalityComparer: EqualityComparer<T> = equateValues): boolean {
|
||||
return a.length === b.length && a.every((x, i) => equalityComparer(x, b[i]));
|
||||
}
|
||||
|
||||
export function indexOfAnyCharCode(text: string, charCodes: ReadonlyArray<number>, start?: number): number {
|
||||
for (let i = start || 0; i < text.length; i++) {
|
||||
if (contains(charCodes, text.charCodeAt(i))) {
|
||||
@@ -1339,7 +1352,8 @@ namespace ts {
|
||||
|
||||
export function cloneMap(map: SymbolTable): SymbolTable;
|
||||
export function cloneMap<T>(map: ReadonlyMap<T>): Map<T>;
|
||||
export function cloneMap<T>(map: ReadonlyMap<T> | SymbolTable): Map<T> | SymbolTable {
|
||||
export function cloneMap<T>(map: ReadonlyUnderscoreEscapedMap<T>): UnderscoreEscapedMap<T>;
|
||||
export function cloneMap<T>(map: ReadonlyMap<T> | ReadonlyUnderscoreEscapedMap<T> | SymbolTable): Map<T> | UnderscoreEscapedMap<T> | SymbolTable {
|
||||
const clone = createMap<T>();
|
||||
copyEntries(map as Map<T>, clone);
|
||||
return clone;
|
||||
@@ -1453,6 +1467,9 @@ namespace ts {
|
||||
/** Returns its argument. */
|
||||
export function identity<T>(x: T) { return x; }
|
||||
|
||||
/** Returns lower case string */
|
||||
export function toLowerCase(x: string) { return x.toLowerCase(); }
|
||||
|
||||
/** Throws an error because a function is not implemented. */
|
||||
export function notImplemented(): never {
|
||||
throw new Error("Not implemented");
|
||||
@@ -1886,10 +1903,6 @@ namespace ts {
|
||||
return text1 ? Comparison.GreaterThan : Comparison.LessThan;
|
||||
}
|
||||
|
||||
export function sortAndDeduplicateDiagnostics(diagnostics: ReadonlyArray<Diagnostic>): Diagnostic[] {
|
||||
return sortAndDeduplicate(diagnostics, compareDiagnostics);
|
||||
}
|
||||
|
||||
export function normalizeSlashes(path: string): string {
|
||||
return path.replace(/\\/g, "/");
|
||||
}
|
||||
@@ -1907,7 +1920,7 @@ namespace ts {
|
||||
return p2 + 1;
|
||||
}
|
||||
if (path.charCodeAt(1) === CharacterCodes.colon) {
|
||||
if (path.charCodeAt(2) === CharacterCodes.slash) return 3;
|
||||
if (path.charCodeAt(2) === CharacterCodes.slash || path.charCodeAt(2) === CharacterCodes.backslash) return 3;
|
||||
}
|
||||
// Per RFC 1738 'file' URI schema has the shape file://<host>/<path>
|
||||
// if <host> is omitted then it is assumed that host value is 'localhost',
|
||||
@@ -2923,9 +2936,7 @@ namespace ts {
|
||||
|
||||
export type GetCanonicalFileName = (fileName: string) => string;
|
||||
export function createGetCanonicalFileName(useCaseSensitiveFileNames: boolean): GetCanonicalFileName {
|
||||
return useCaseSensitiveFileNames
|
||||
? ((fileName) => fileName)
|
||||
: ((fileName) => fileName.toLowerCase());
|
||||
return useCaseSensitiveFileNames ? identity : toLowerCase;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3050,219 +3061,10 @@ namespace ts {
|
||||
|
||||
export function assertTypeIsNever(_: never): void { } // tslint:disable-line no-empty
|
||||
|
||||
export interface FileAndDirectoryExistence {
|
||||
fileExists: boolean;
|
||||
directoryExists: boolean;
|
||||
}
|
||||
|
||||
export interface CachedDirectoryStructureHost extends DirectoryStructureHost {
|
||||
/** Returns the queried result for the file exists and directory exists if at all it was done */
|
||||
addOrDeleteFileOrDirectory(fileOrDirectory: string, fileOrDirectoryPath: Path): FileAndDirectoryExistence | undefined;
|
||||
addOrDeleteFile(fileName: string, filePath: Path, eventKind: FileWatcherEventKind): void;
|
||||
clearCache(): void;
|
||||
}
|
||||
|
||||
interface MutableFileSystemEntries {
|
||||
readonly files: string[];
|
||||
readonly directories: string[];
|
||||
}
|
||||
|
||||
export function createCachedDirectoryStructureHost(host: DirectoryStructureHost): CachedDirectoryStructureHost {
|
||||
const cachedReadDirectoryResult = createMap<MutableFileSystemEntries>();
|
||||
const getCurrentDirectory = memoize(() => host.getCurrentDirectory());
|
||||
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames);
|
||||
return {
|
||||
useCaseSensitiveFileNames: host.useCaseSensitiveFileNames,
|
||||
newLine: host.newLine,
|
||||
readFile: (path, encoding) => host.readFile(path, encoding),
|
||||
write: s => host.write(s),
|
||||
writeFile,
|
||||
fileExists,
|
||||
directoryExists,
|
||||
createDirectory,
|
||||
getCurrentDirectory,
|
||||
getDirectories,
|
||||
readDirectory,
|
||||
addOrDeleteFileOrDirectory,
|
||||
addOrDeleteFile,
|
||||
clearCache,
|
||||
exit: code => host.exit(code)
|
||||
};
|
||||
|
||||
function toPath(fileName: string) {
|
||||
return ts.toPath(fileName, getCurrentDirectory(), getCanonicalFileName);
|
||||
}
|
||||
|
||||
function getCachedFileSystemEntries(rootDirPath: Path): MutableFileSystemEntries | undefined {
|
||||
return cachedReadDirectoryResult.get(rootDirPath);
|
||||
}
|
||||
|
||||
function getCachedFileSystemEntriesForBaseDir(path: Path): MutableFileSystemEntries | undefined {
|
||||
return getCachedFileSystemEntries(getDirectoryPath(path));
|
||||
}
|
||||
|
||||
function getBaseNameOfFileName(fileName: string) {
|
||||
return getBaseFileName(normalizePath(fileName));
|
||||
}
|
||||
|
||||
function createCachedFileSystemEntries(rootDir: string, rootDirPath: Path) {
|
||||
const resultFromHost: MutableFileSystemEntries = {
|
||||
files: map(host.readDirectory(rootDir, /*extensions*/ undefined, /*exclude*/ undefined, /*include*/["*.*"]), getBaseNameOfFileName) || [],
|
||||
directories: host.getDirectories(rootDir) || []
|
||||
};
|
||||
|
||||
cachedReadDirectoryResult.set(rootDirPath, resultFromHost);
|
||||
return resultFromHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the readDirectory result was already cached, it returns that
|
||||
* Otherwise gets result from host and caches it.
|
||||
* The host request is done under try catch block to avoid caching incorrect result
|
||||
*/
|
||||
function tryReadDirectory(rootDir: string, rootDirPath: Path): MutableFileSystemEntries | undefined {
|
||||
const cachedResult = getCachedFileSystemEntries(rootDirPath);
|
||||
if (cachedResult) {
|
||||
return cachedResult;
|
||||
}
|
||||
|
||||
try {
|
||||
return createCachedFileSystemEntries(rootDir, rootDirPath);
|
||||
}
|
||||
catch (_e) {
|
||||
// If there is exception to read directories, dont cache the result and direct the calls to host
|
||||
Debug.assert(!cachedReadDirectoryResult.has(rootDirPath));
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function fileNameEqual(name1: string, name2: string) {
|
||||
return getCanonicalFileName(name1) === getCanonicalFileName(name2);
|
||||
}
|
||||
|
||||
function hasEntry(entries: ReadonlyArray<string>, name: string) {
|
||||
return some(entries, file => fileNameEqual(file, name));
|
||||
}
|
||||
|
||||
function updateFileSystemEntry(entries: string[], baseName: string, isValid: boolean) {
|
||||
if (hasEntry(entries, baseName)) {
|
||||
if (!isValid) {
|
||||
return filterMutate(entries, entry => !fileNameEqual(entry, baseName));
|
||||
}
|
||||
}
|
||||
else if (isValid) {
|
||||
return entries.push(baseName);
|
||||
}
|
||||
}
|
||||
|
||||
function writeFile(fileName: string, data: string, writeByteOrderMark?: boolean): void {
|
||||
const path = toPath(fileName);
|
||||
const result = getCachedFileSystemEntriesForBaseDir(path);
|
||||
if (result) {
|
||||
updateFilesOfFileSystemEntry(result, getBaseNameOfFileName(fileName), /*fileExists*/ true);
|
||||
}
|
||||
return host.writeFile(fileName, data, writeByteOrderMark);
|
||||
}
|
||||
|
||||
function fileExists(fileName: string): boolean {
|
||||
const path = toPath(fileName);
|
||||
const result = getCachedFileSystemEntriesForBaseDir(path);
|
||||
return result && hasEntry(result.files, getBaseNameOfFileName(fileName)) ||
|
||||
host.fileExists(fileName);
|
||||
}
|
||||
|
||||
function directoryExists(dirPath: string): boolean {
|
||||
const path = toPath(dirPath);
|
||||
return cachedReadDirectoryResult.has(path) || host.directoryExists(dirPath);
|
||||
}
|
||||
|
||||
function createDirectory(dirPath: string) {
|
||||
const path = toPath(dirPath);
|
||||
const result = getCachedFileSystemEntriesForBaseDir(path);
|
||||
const baseFileName = getBaseNameOfFileName(dirPath);
|
||||
if (result) {
|
||||
updateFileSystemEntry(result.directories, baseFileName, /*isValid*/ true);
|
||||
}
|
||||
host.createDirectory(dirPath);
|
||||
}
|
||||
|
||||
function getDirectories(rootDir: string): string[] {
|
||||
const rootDirPath = toPath(rootDir);
|
||||
const result = tryReadDirectory(rootDir, rootDirPath);
|
||||
if (result) {
|
||||
return result.directories.slice();
|
||||
}
|
||||
return host.getDirectories(rootDir);
|
||||
}
|
||||
|
||||
function readDirectory(rootDir: string, extensions?: ReadonlyArray<string>, excludes?: ReadonlyArray<string>, includes?: ReadonlyArray<string>, depth?: number): string[] {
|
||||
const rootDirPath = toPath(rootDir);
|
||||
const result = tryReadDirectory(rootDir, rootDirPath);
|
||||
if (result) {
|
||||
return matchFiles(rootDir, extensions, excludes, includes, host.useCaseSensitiveFileNames, getCurrentDirectory(), depth, getFileSystemEntries);
|
||||
}
|
||||
return host.readDirectory(rootDir, extensions, excludes, includes, depth);
|
||||
|
||||
function getFileSystemEntries(dir: string) {
|
||||
const path = toPath(dir);
|
||||
if (path === rootDirPath) {
|
||||
return result;
|
||||
}
|
||||
return getCachedFileSystemEntries(path) || createCachedFileSystemEntries(dir, path);
|
||||
}
|
||||
}
|
||||
|
||||
function addOrDeleteFileOrDirectory(fileOrDirectory: string, fileOrDirectoryPath: Path) {
|
||||
const existingResult = getCachedFileSystemEntries(fileOrDirectoryPath);
|
||||
if (existingResult) {
|
||||
// Just clear the cache for now
|
||||
// For now just clear the cache, since this could mean that multiple level entries might need to be re-evaluated
|
||||
clearCache();
|
||||
}
|
||||
else {
|
||||
// This was earlier a file (hence not in cached directory contents)
|
||||
// or we never cached the directory containing it
|
||||
const parentResult = getCachedFileSystemEntriesForBaseDir(fileOrDirectoryPath);
|
||||
if (parentResult) {
|
||||
const baseName = getBaseNameOfFileName(fileOrDirectory);
|
||||
if (parentResult) {
|
||||
const fsQueryResult: FileAndDirectoryExistence = {
|
||||
fileExists: host.fileExists(fileOrDirectoryPath),
|
||||
directoryExists: host.directoryExists(fileOrDirectoryPath)
|
||||
};
|
||||
if (fsQueryResult.directoryExists || hasEntry(parentResult.directories, baseName)) {
|
||||
// Folder added or removed, clear the cache instead of updating the folder and its structure
|
||||
clearCache();
|
||||
}
|
||||
else {
|
||||
// No need to update the directory structure, just files
|
||||
updateFilesOfFileSystemEntry(parentResult, baseName, fsQueryResult.fileExists);
|
||||
}
|
||||
return fsQueryResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addOrDeleteFile(fileName: string, filePath: Path, eventKind: FileWatcherEventKind) {
|
||||
if (eventKind === FileWatcherEventKind.Changed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const parentResult = getCachedFileSystemEntriesForBaseDir(filePath);
|
||||
if (parentResult) {
|
||||
updateFilesOfFileSystemEntry(parentResult, getBaseNameOfFileName(fileName), eventKind === FileWatcherEventKind.Created);
|
||||
}
|
||||
}
|
||||
|
||||
function updateFilesOfFileSystemEntry(parentResult: MutableFileSystemEntries, baseName: string, fileExists: boolean) {
|
||||
updateFileSystemEntry(parentResult.files, baseName, fileExists);
|
||||
}
|
||||
|
||||
function clearCache() {
|
||||
cachedReadDirectoryResult.clear();
|
||||
}
|
||||
}
|
||||
export const emptyFileSystemEntries: FileSystemEntries = {
|
||||
files: emptyArray,
|
||||
directories: emptyArray
|
||||
};
|
||||
|
||||
export function singleElementArray<T>(t: T | undefined): T[] | undefined {
|
||||
return t === undefined ? undefined : [t];
|
||||
|
||||
@@ -2022,7 +2022,7 @@ namespace ts {
|
||||
export function writeDeclarationFile(declarationFilePath: string, sourceFileOrBundle: SourceFile | Bundle, host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, emitOnlyDtsFiles: boolean) {
|
||||
const emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFileOrBundle, emitOnlyDtsFiles);
|
||||
const emitSkipped = emitDeclarationResult.reportedDeclarationError || host.isEmitBlocked(declarationFilePath) || host.getCompilerOptions().noEmit;
|
||||
if (!emitSkipped) {
|
||||
if (!emitSkipped || emitOnlyDtsFiles) {
|
||||
const sourceFiles = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle];
|
||||
const declarationOutput = emitDeclarationResult.referencesOutput
|
||||
+ getDeclarationOutput(emitDeclarationResult.synchronousDeclarationOutput, emitDeclarationResult.moduleElementDeclarationEmitInfo);
|
||||
|
||||
@@ -1980,6 +1980,10 @@
|
||||
"category": "Error",
|
||||
"code": 2565
|
||||
},
|
||||
"A rest element cannot have a property name.": {
|
||||
"category": "Error",
|
||||
"code": 2566
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
@@ -2807,6 +2811,10 @@
|
||||
"category": "Message",
|
||||
"code": 6013
|
||||
},
|
||||
"Only emit '.d.ts' declaration files.": {
|
||||
"category": "Message",
|
||||
"code": 6014
|
||||
},
|
||||
"Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'.": {
|
||||
"category": "Message",
|
||||
"code": 6015
|
||||
@@ -3897,10 +3905,6 @@
|
||||
"category": "Message",
|
||||
"code": 95002
|
||||
},
|
||||
"Extract symbol": {
|
||||
"category": "Message",
|
||||
"code": 95003
|
||||
},
|
||||
"Extract to {0} in {1}": {
|
||||
"category": "Message",
|
||||
"code": 95004
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace ts {
|
||||
|
||||
function emitSourceFileOrBundle({ jsFilePath, sourceMapFilePath, declarationFilePath }: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) {
|
||||
// Make sure not to write js file and source map file if any of them cannot be written
|
||||
if (!host.isEmitBlocked(jsFilePath) && !compilerOptions.noEmit) {
|
||||
if (!host.isEmitBlocked(jsFilePath) && !compilerOptions.noEmit && !compilerOptions.emitDeclarationsOnly) {
|
||||
if (!emitOnlyDtsFiles) {
|
||||
printSourceFileOrBundle(jsFilePath, sourceMapFilePath, sourceFileOrBundle);
|
||||
}
|
||||
@@ -1287,12 +1287,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitBindingElement(node: BindingElement) {
|
||||
emitIfPresent(node.dotDotDotToken);
|
||||
if (node.propertyName) {
|
||||
emit(node.propertyName);
|
||||
writePunctuation(":");
|
||||
writeSpace();
|
||||
}
|
||||
emitIfPresent(node.dotDotDotToken);
|
||||
emit(node.name);
|
||||
emitInitializer(node.initializer);
|
||||
}
|
||||
|
||||
+13
-4
@@ -126,8 +126,8 @@ namespace ts {
|
||||
case SyntaxKind.BindingElement:
|
||||
return visitNodes(cbNode, cbNodes, node.decorators) ||
|
||||
visitNodes(cbNode, cbNodes, node.modifiers) ||
|
||||
visitNode(cbNode, (<BindingElement>node).propertyName) ||
|
||||
visitNode(cbNode, (<BindingElement>node).dotDotDotToken) ||
|
||||
visitNode(cbNode, (<BindingElement>node).propertyName) ||
|
||||
visitNode(cbNode, (<BindingElement>node).name) ||
|
||||
visitNode(cbNode, (<BindingElement>node).initializer);
|
||||
case SyntaxKind.FunctionType:
|
||||
@@ -6870,7 +6870,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag | undefined {
|
||||
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTemplateTag)) {
|
||||
if (some(tags, isJSDocTemplateTag)) {
|
||||
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.escapedText);
|
||||
}
|
||||
|
||||
@@ -6879,14 +6879,14 @@ namespace ts {
|
||||
const typeParametersPos = getNodePos();
|
||||
|
||||
while (true) {
|
||||
const name = parseJSDocIdentifierName();
|
||||
const typeParameter = <TypeParameterDeclaration>createNode(SyntaxKind.TypeParameter);
|
||||
const name = parseJSDocIdentifierNameWithOptionalBraces();
|
||||
skipWhitespace();
|
||||
if (!name) {
|
||||
parseErrorAtPosition(scanner.getStartPos(), 0, Diagnostics.Identifier_expected);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const typeParameter = <TypeParameterDeclaration>createNode(SyntaxKind.TypeParameter, name.pos);
|
||||
typeParameter.name = name;
|
||||
finishNode(typeParameter);
|
||||
|
||||
@@ -6909,6 +6909,15 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseJSDocIdentifierNameWithOptionalBraces(): Identifier | undefined {
|
||||
const parsedBrace = parseOptional(SyntaxKind.OpenBraceToken);
|
||||
const res = parseJSDocIdentifierName();
|
||||
if (parsedBrace) {
|
||||
parseExpected(SyntaxKind.CloseBraceToken);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function nextJSDocToken(): JsDocSyntaxKind {
|
||||
return currentToken = scanner.scanJSDocToken();
|
||||
}
|
||||
|
||||
+64
-30
@@ -1,7 +1,6 @@
|
||||
/// <reference path="sys.ts" />
|
||||
/// <reference path="emitter.ts" />
|
||||
/// <reference path="core.ts" />
|
||||
/// <reference path="builder.ts" />
|
||||
|
||||
namespace ts {
|
||||
const ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/;
|
||||
@@ -1141,32 +1140,34 @@ namespace ts {
|
||||
function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult {
|
||||
let declarationDiagnostics: ReadonlyArray<Diagnostic> = [];
|
||||
|
||||
if (options.noEmit) {
|
||||
return { diagnostics: declarationDiagnostics, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true };
|
||||
}
|
||||
|
||||
// If the noEmitOnError flag is set, then check if we have any errors so far. If so,
|
||||
// immediately bail out. Note that we pass 'undefined' for 'sourceFile' so that we
|
||||
// get any preEmit diagnostics, not just the ones
|
||||
if (options.noEmitOnError) {
|
||||
const diagnostics = [
|
||||
...program.getOptionsDiagnostics(cancellationToken),
|
||||
...program.getSyntacticDiagnostics(sourceFile, cancellationToken),
|
||||
...program.getGlobalDiagnostics(cancellationToken),
|
||||
...program.getSemanticDiagnostics(sourceFile, cancellationToken)
|
||||
];
|
||||
|
||||
if (diagnostics.length === 0 && program.getCompilerOptions().declaration) {
|
||||
declarationDiagnostics = program.getDeclarationDiagnostics(/*sourceFile*/ undefined, cancellationToken);
|
||||
if (!emitOnlyDtsFiles) {
|
||||
if (options.noEmit) {
|
||||
return { diagnostics: declarationDiagnostics, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true };
|
||||
}
|
||||
|
||||
if (diagnostics.length > 0 || declarationDiagnostics.length > 0) {
|
||||
return {
|
||||
diagnostics: concatenate(diagnostics, declarationDiagnostics),
|
||||
sourceMaps: undefined,
|
||||
emittedFiles: undefined,
|
||||
emitSkipped: true
|
||||
};
|
||||
// If the noEmitOnError flag is set, then check if we have any errors so far. If so,
|
||||
// immediately bail out. Note that we pass 'undefined' for 'sourceFile' so that we
|
||||
// get any preEmit diagnostics, not just the ones
|
||||
if (options.noEmitOnError) {
|
||||
const diagnostics = [
|
||||
...program.getOptionsDiagnostics(cancellationToken),
|
||||
...program.getSyntacticDiagnostics(sourceFile, cancellationToken),
|
||||
...program.getGlobalDiagnostics(cancellationToken),
|
||||
...program.getSemanticDiagnostics(sourceFile, cancellationToken)
|
||||
];
|
||||
|
||||
if (diagnostics.length === 0 && program.getCompilerOptions().declaration) {
|
||||
declarationDiagnostics = program.getDeclarationDiagnostics(/*sourceFile*/ undefined, cancellationToken);
|
||||
}
|
||||
|
||||
if (diagnostics.length > 0 || declarationDiagnostics.length > 0) {
|
||||
return {
|
||||
diagnostics: concatenate(diagnostics, declarationDiagnostics),
|
||||
sourceMaps: undefined,
|
||||
emittedFiles: undefined,
|
||||
emitSkipped: true
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1178,7 +1179,7 @@ namespace ts {
|
||||
// This is because in the -out scenario all files need to be emitted, and therefore all
|
||||
// files need to be type checked. And the way to specify that all files need to be type
|
||||
// checked is to not pass the file to getEmitResolver.
|
||||
const emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile);
|
||||
const emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile, cancellationToken, emitOnlyDtsFiles);
|
||||
|
||||
performance.mark("beforeEmit");
|
||||
|
||||
@@ -2200,6 +2201,16 @@ namespace ts {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs"));
|
||||
}
|
||||
|
||||
if (options.emitDeclarationsOnly) {
|
||||
if (!options.declaration) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDeclarationsOnly", "declarations");
|
||||
}
|
||||
|
||||
if (options.noEmit) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "emitDeclarationsOnly", "noEmit");
|
||||
}
|
||||
}
|
||||
|
||||
if (options.emitDecoratorMetadata &&
|
||||
!options.experimentalDecorators) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators");
|
||||
@@ -2222,7 +2233,9 @@ namespace ts {
|
||||
const emitHost = getEmitHost();
|
||||
const emitFilesSeen = createMap<true>();
|
||||
forEachEmittedFile(emitHost, (emitFileNames) => {
|
||||
verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen);
|
||||
if (!options.emitDeclarationsOnly) {
|
||||
verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen);
|
||||
}
|
||||
verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen);
|
||||
});
|
||||
}
|
||||
@@ -2350,9 +2363,30 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
return forEachEmittedFile(getEmitHost(), ({ jsFilePath, declarationFilePath }) =>
|
||||
isSameFile(jsFilePath, file) ||
|
||||
(declarationFilePath && isSameFile(declarationFilePath, file)));
|
||||
// If this is source file, its not emitted file
|
||||
const filePath = toPath(file);
|
||||
if (getSourceFileByPath(filePath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If options have --outFile or --out just check that
|
||||
const out = options.outFile || options.out;
|
||||
if (out) {
|
||||
return isSameFile(filePath, out) || isSameFile(filePath, removeFileExtension(out) + Extension.Dts);
|
||||
}
|
||||
|
||||
// If --outDir, check if file is in that directory
|
||||
if (options.outDir) {
|
||||
return containsPath(options.outDir, filePath, currentDirectory, !host.useCaseSensitiveFileNames());
|
||||
}
|
||||
|
||||
if (fileExtensionIsOneOf(filePath, supportedJavascriptExtensions) || fileExtensionIs(filePath, Extension.Dts)) {
|
||||
// Otherwise just check if sourceFile with the name exists
|
||||
const filePathWithoutExtension = removeFileExtension(filePath);
|
||||
return !!getSourceFileByPath(combinePaths(filePathWithoutExtension, Extension.Ts) as Path) ||
|
||||
!!getSourceFileByPath(combinePaths(filePathWithoutExtension, Extension.Tsx) as Path);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isSameFile(file1: string, file2: string) {
|
||||
|
||||
@@ -9,12 +9,12 @@ namespace ts {
|
||||
startRecordingFilesWithChangedResolutions(): void;
|
||||
finishRecordingFilesWithChangedResolutions(): Path[];
|
||||
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, logChanges: boolean): ResolvedModuleFull[];
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined): ResolvedModuleFull[];
|
||||
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
|
||||
invalidateResolutionOfFile(filePath: Path): void;
|
||||
removeResolutionsOfFile(filePath: Path): void;
|
||||
createHasInvalidatedResolution(): HasInvalidatedResolution;
|
||||
createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution;
|
||||
|
||||
startCachingPerDirectoryResolution(): void;
|
||||
finishCachingPerDirectoryResolution(): void;
|
||||
@@ -47,7 +47,7 @@ namespace ts {
|
||||
onInvalidatedResolution(): void;
|
||||
watchTypeRootsDirectory(directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags): FileWatcher;
|
||||
onChangedAutomaticTypeDirectiveNames(): void;
|
||||
getCachedDirectoryStructureHost?(): CachedDirectoryStructureHost;
|
||||
getCachedDirectoryStructureHost(): CachedDirectoryStructureHost | undefined;
|
||||
projectName?: string;
|
||||
getGlobalCache?(): string | undefined;
|
||||
writeLog(s: string): void;
|
||||
@@ -73,7 +73,7 @@ namespace ts {
|
||||
type GetResolutionWithResolvedFileName<T extends ResolutionWithFailedLookupLocations = ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName = ResolutionWithResolvedFileName> =
|
||||
(resolution: T) => R;
|
||||
|
||||
export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string): ResolutionCache {
|
||||
export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string, logChangesWhenResolvingModule: boolean): ResolutionCache {
|
||||
let filesWithChangedSetOfUnresolvedImports: Path[] | undefined;
|
||||
let filesWithInvalidatedResolutions: Map<true> | undefined;
|
||||
let allFilesHaveInvalidatedResolution = false;
|
||||
@@ -88,6 +88,7 @@ namespace ts {
|
||||
const perDirectoryResolvedTypeReferenceDirectives = createMap<Map<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
|
||||
|
||||
const getCurrentDirectory = memoize(() => resolutionHost.getCurrentDirectory());
|
||||
const cachedDirectoryStructureHost = resolutionHost.getCachedDirectoryStructureHost();
|
||||
|
||||
/**
|
||||
* These are the extensions that failed lookup files will have by default,
|
||||
@@ -159,8 +160,8 @@ namespace ts {
|
||||
return collected;
|
||||
}
|
||||
|
||||
function createHasInvalidatedResolution(): HasInvalidatedResolution {
|
||||
if (allFilesHaveInvalidatedResolution) {
|
||||
function createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution {
|
||||
if (allFilesHaveInvalidatedResolution || forceAllFilesAsInvalidated) {
|
||||
// Any file asked would have invalidated resolution
|
||||
filesWithInvalidatedResolutions = undefined;
|
||||
return returnTrue;
|
||||
@@ -307,12 +308,12 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
function resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, logChanges: boolean): ResolvedModuleFull[] {
|
||||
function resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined): ResolvedModuleFull[] {
|
||||
return resolveNamesWithLocalCache(
|
||||
moduleNames, containingFile,
|
||||
resolvedModuleNames, perDirectoryResolvedModuleNames,
|
||||
resolveModuleName, getResolvedModule,
|
||||
reusedNames, logChanges
|
||||
reusedNames, logChangesWhenResolvingModule
|
||||
);
|
||||
}
|
||||
|
||||
@@ -468,14 +469,9 @@ namespace ts {
|
||||
function createDirectoryWatcher(directory: string, dirPath: Path) {
|
||||
return resolutionHost.watchDirectoryOfFailedLookupLocation(directory, fileOrDirectory => {
|
||||
const fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory);
|
||||
if (resolutionHost.getCachedDirectoryStructureHost) {
|
||||
if (cachedDirectoryStructureHost) {
|
||||
// Since the file existance changed, update the sourceFiles cache
|
||||
resolutionHost.getCachedDirectoryStructureHost().addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
|
||||
}
|
||||
|
||||
// Ignore emits from the program
|
||||
if (isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectory)) {
|
||||
return;
|
||||
cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
|
||||
}
|
||||
|
||||
// If the files are added to project root or node_modules directory, always run through the invalidation process
|
||||
@@ -581,6 +577,10 @@ namespace ts {
|
||||
if (!isPathWithDefaultFailedLookupExtension(fileOrDirectoryPath) && !customFailedLookupPaths.has(fileOrDirectoryPath)) {
|
||||
return false;
|
||||
}
|
||||
// Ignore emits from the program
|
||||
if (isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectoryPath)) {
|
||||
return false;
|
||||
}
|
||||
// Resolution need to be invalidated if failed lookup location is same as the file or directory getting created
|
||||
isChangedFailedLookupLocation = location => resolutionHost.toPath(location) === fileOrDirectoryPath;
|
||||
}
|
||||
@@ -602,9 +602,9 @@ namespace ts {
|
||||
// Create new watch and recursive info
|
||||
return resolutionHost.watchTypeRootsDirectory(typeRoot, fileOrDirectory => {
|
||||
const fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory);
|
||||
if (resolutionHost.getCachedDirectoryStructureHost) {
|
||||
if (cachedDirectoryStructureHost) {
|
||||
// Since the file existance changed, update the sourceFiles cache
|
||||
resolutionHost.getCachedDirectoryStructureHost().addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
|
||||
cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
|
||||
}
|
||||
|
||||
// For now just recompile
|
||||
|
||||
@@ -336,7 +336,10 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export function computePositionOfLineAndCharacter(lineStarts: ReadonlyArray<number>, line: number, character: number, debugText?: string): number {
|
||||
Debug.assert(line >= 0 && line < lineStarts.length);
|
||||
if (line < 0 || line >= lineStarts.length) {
|
||||
Debug.fail(`Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length} , line map is correct? ${debugText !== undefined ? arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"}`);
|
||||
}
|
||||
|
||||
const res = lineStarts[line] + character;
|
||||
if (line < lineStarts.length - 1) {
|
||||
Debug.assert(res < lineStarts[line + 1]);
|
||||
|
||||
+41
-24
@@ -30,27 +30,14 @@ namespace ts {
|
||||
mtime?: Date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partial interface of the System thats needed to support the caching of directory structure
|
||||
*/
|
||||
export interface DirectoryStructureHost {
|
||||
export interface System {
|
||||
args: string[];
|
||||
newLine: string;
|
||||
useCaseSensitiveFileNames: boolean;
|
||||
write(s: string): void;
|
||||
readFile(path: string, encoding?: string): string | undefined;
|
||||
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
|
||||
fileExists(path: string): boolean;
|
||||
directoryExists(path: string): boolean;
|
||||
createDirectory(path: string): void;
|
||||
getCurrentDirectory(): string;
|
||||
getDirectories(path: string): string[];
|
||||
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
exit(exitCode?: number): void;
|
||||
}
|
||||
|
||||
export interface System extends DirectoryStructureHost {
|
||||
args: string[];
|
||||
getFileSize?(path: string): number;
|
||||
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
|
||||
/**
|
||||
* @pollingInterval - this parameter is used in polling-based watchers and ignored in watchers that
|
||||
* use native OS file watching
|
||||
@@ -58,7 +45,13 @@ namespace ts {
|
||||
watchFile?(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
watchDirectory?(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
resolvePath(path: string): string;
|
||||
fileExists(path: string): boolean;
|
||||
directoryExists(path: string): boolean;
|
||||
createDirectory(path: string): void;
|
||||
getExecutingFilePath(): string;
|
||||
getCurrentDirectory(): string;
|
||||
getDirectories(path: string): string[];
|
||||
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
getModifiedTime?(path: string): Date;
|
||||
/**
|
||||
* This should be cryptographically secure.
|
||||
@@ -66,6 +59,7 @@ namespace ts {
|
||||
*/
|
||||
createHash?(data: string): string;
|
||||
getMemoryUsage?(): number;
|
||||
exit(exitCode?: number): void;
|
||||
realpath?(path: string): string;
|
||||
/*@internal*/ getEnvironmentVariable(name: string): string;
|
||||
/*@internal*/ tryEnableSourceMapsForHost?(): void;
|
||||
@@ -132,10 +126,32 @@ namespace ts {
|
||||
const _fs = require("fs");
|
||||
const _path = require("path");
|
||||
const _os = require("os");
|
||||
const _crypto = require("crypto");
|
||||
// crypto can be absent on reduced node installations
|
||||
let _crypto: any;
|
||||
try {
|
||||
_crypto = require("crypto");
|
||||
}
|
||||
catch {
|
||||
_crypto = undefined;
|
||||
}
|
||||
|
||||
const useNonPollingWatchers = process.env.TSC_NONPOLLING_WATCHER;
|
||||
|
||||
/**
|
||||
* djb2 hashing algorithm
|
||||
* http://www.cse.yorku.ca/~oz/hash.html
|
||||
*/
|
||||
function generateDjb2Hash(data: string): string {
|
||||
const chars = data.split("").map(str => str.charCodeAt(0));
|
||||
return `${chars.reduce((prev, curr) => ((prev << 5) + prev) + curr, 5381)}`;
|
||||
}
|
||||
|
||||
function createMD5HashUsingNativeCrypto(data: string) {
|
||||
const hash = _crypto.createHash("md5");
|
||||
hash.update(data);
|
||||
return hash.digest("hex");
|
||||
}
|
||||
|
||||
function createWatchedFileSet() {
|
||||
const dirWatchers = createMap<DirectoryWatcher>();
|
||||
// One file can have multiple watchers
|
||||
@@ -398,7 +414,7 @@ namespace ts {
|
||||
return { files, directories };
|
||||
}
|
||||
catch (e) {
|
||||
return { files: [], directories: [] };
|
||||
return emptyFileSystemEntries;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -499,11 +515,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
createHash(data) {
|
||||
const hash = _crypto.createHash("md5");
|
||||
hash.update(data);
|
||||
return hash.digest("hex");
|
||||
},
|
||||
createHash: _crypto ? createMD5HashUsingNativeCrypto : generateDjb2Hash,
|
||||
getMemoryUsage() {
|
||||
if (global.gc) {
|
||||
global.gc();
|
||||
@@ -524,7 +536,12 @@ namespace ts {
|
||||
process.exit(exitCode);
|
||||
},
|
||||
realpath(path: string): string {
|
||||
return _fs.realpathSync(path);
|
||||
try {
|
||||
return _fs.realpathSync(path);
|
||||
}
|
||||
catch {
|
||||
return path;
|
||||
}
|
||||
},
|
||||
debugMode: some(<string[]>process.execArgv, arg => /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg)),
|
||||
tryEnableSourceMapsForHost() {
|
||||
|
||||
@@ -12,9 +12,9 @@ namespace ts {
|
||||
|
||||
export function transformES2017(context: TransformationContext) {
|
||||
const {
|
||||
startLexicalEnvironment,
|
||||
resumeLexicalEnvironment,
|
||||
endLexicalEnvironment
|
||||
endLexicalEnvironment,
|
||||
hoistVariableDeclaration
|
||||
} = context;
|
||||
|
||||
const resolver = context.getEmitResolver();
|
||||
@@ -33,6 +33,8 @@ namespace ts {
|
||||
*/
|
||||
let enclosingSuperContainerFlags: NodeCheckFlags = 0;
|
||||
|
||||
let enclosingFunctionParameterNames: UnderscoreEscapedMap<true>;
|
||||
|
||||
// Save the previous transformation hooks.
|
||||
const previousOnEmitNode = context.onEmitNode;
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
@@ -83,6 +85,108 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function asyncBodyVisitor(node: Node): VisitResult<Node> {
|
||||
if (isNodeWithPossibleHoistedDeclaration(node)) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
return visitVariableStatementInAsyncBody(node);
|
||||
case SyntaxKind.ForStatement:
|
||||
return visitForStatementInAsyncBody(node);
|
||||
case SyntaxKind.ForInStatement:
|
||||
return visitForInStatementInAsyncBody(node);
|
||||
case SyntaxKind.ForOfStatement:
|
||||
return visitForOfStatementInAsyncBody(node);
|
||||
case SyntaxKind.CatchClause:
|
||||
return visitCatchClauseInAsyncBody(node);
|
||||
case SyntaxKind.Block:
|
||||
case SyntaxKind.SwitchStatement:
|
||||
case SyntaxKind.CaseBlock:
|
||||
case SyntaxKind.CaseClause:
|
||||
case SyntaxKind.DefaultClause:
|
||||
case SyntaxKind.TryStatement:
|
||||
case SyntaxKind.DoStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
case SyntaxKind.IfStatement:
|
||||
case SyntaxKind.WithStatement:
|
||||
case SyntaxKind.LabeledStatement:
|
||||
return visitEachChild(node, asyncBodyVisitor, context);
|
||||
default:
|
||||
return Debug.assertNever(node, "Unhandled node.");
|
||||
}
|
||||
}
|
||||
return visitor(node);
|
||||
}
|
||||
|
||||
function visitCatchClauseInAsyncBody(node: CatchClause) {
|
||||
const catchClauseNames = createUnderscoreEscapedMap<true>();
|
||||
recordDeclarationName(node.variableDeclaration, catchClauseNames);
|
||||
|
||||
// names declared in a catch variable are block scoped
|
||||
let catchClauseUnshadowedNames: UnderscoreEscapedMap<true>;
|
||||
catchClauseNames.forEach((_, escapedName) => {
|
||||
if (enclosingFunctionParameterNames.has(escapedName)) {
|
||||
if (!catchClauseUnshadowedNames) {
|
||||
catchClauseUnshadowedNames = cloneMap(enclosingFunctionParameterNames);
|
||||
}
|
||||
catchClauseUnshadowedNames.delete(escapedName);
|
||||
}
|
||||
});
|
||||
|
||||
if (catchClauseUnshadowedNames) {
|
||||
const savedEnclosingFunctionParameterNames = enclosingFunctionParameterNames;
|
||||
enclosingFunctionParameterNames = catchClauseUnshadowedNames;
|
||||
const result = visitEachChild(node, asyncBodyVisitor, context);
|
||||
enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames;
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return visitEachChild(node, asyncBodyVisitor, context);
|
||||
}
|
||||
}
|
||||
|
||||
function visitVariableStatementInAsyncBody(node: VariableStatement) {
|
||||
if (isVariableDeclarationListWithCollidingName(node.declarationList)) {
|
||||
const expression = visitVariableDeclarationListWithCollidingNames(node.declarationList, /*hasReceiver*/ false);
|
||||
return expression ? createStatement(expression) : undefined;
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitForInStatementInAsyncBody(node: ForInStatement) {
|
||||
return updateForIn(
|
||||
node,
|
||||
isVariableDeclarationListWithCollidingName(node.initializer)
|
||||
? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)
|
||||
: visitNode(node.initializer, visitor, isForInitializer),
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
visitNode(node.statement, asyncBodyVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
|
||||
function visitForOfStatementInAsyncBody(node: ForOfStatement) {
|
||||
return updateForOf(
|
||||
node,
|
||||
visitNode(node.awaitModifier, visitor, isToken),
|
||||
isVariableDeclarationListWithCollidingName(node.initializer)
|
||||
? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)
|
||||
: visitNode(node.initializer, visitor, isForInitializer),
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
visitNode(node.statement, asyncBodyVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
|
||||
function visitForStatementInAsyncBody(node: ForStatement) {
|
||||
return updateFor(
|
||||
node,
|
||||
isVariableDeclarationListWithCollidingName(node.initializer)
|
||||
? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ false)
|
||||
: visitNode(node.initializer, visitor, isForInitializer),
|
||||
visitNode(node.condition, visitor, isExpression),
|
||||
visitNode(node.incrementor, visitor, isExpression),
|
||||
visitNode((<ForStatement>node).statement, asyncBodyVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an AwaitExpression node.
|
||||
*
|
||||
@@ -197,6 +301,82 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
function recordDeclarationName({ name }: ParameterDeclaration | VariableDeclaration | BindingElement, names: UnderscoreEscapedMap<true>) {
|
||||
if (isIdentifier(name)) {
|
||||
names.set(name.escapedText, true);
|
||||
}
|
||||
else {
|
||||
for (const element of name.elements) {
|
||||
if (!isOmittedExpression(element)) {
|
||||
recordDeclarationName(element, names);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isVariableDeclarationListWithCollidingName(node: ForInitializer): node is VariableDeclarationList {
|
||||
return node
|
||||
&& isVariableDeclarationList(node)
|
||||
&& !(node.flags & NodeFlags.BlockScoped)
|
||||
&& forEach(node.declarations, collidesWithParameterName);
|
||||
}
|
||||
|
||||
function visitVariableDeclarationListWithCollidingNames(node: VariableDeclarationList, hasReceiver: boolean) {
|
||||
hoistVariableDeclarationList(node);
|
||||
|
||||
const variables = getInitializedVariables(node);
|
||||
if (variables.length === 0) {
|
||||
if (hasReceiver) {
|
||||
return visitNode(convertToAssignmentElementTarget(node.declarations[0].name), visitor, isExpression);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return inlineExpressions(map(variables, transformInitializedVariable));
|
||||
}
|
||||
|
||||
function hoistVariableDeclarationList(node: VariableDeclarationList) {
|
||||
forEach(node.declarations, hoistVariable);
|
||||
}
|
||||
|
||||
function hoistVariable({ name }: VariableDeclaration | BindingElement) {
|
||||
if (isIdentifier(name)) {
|
||||
hoistVariableDeclaration(name);
|
||||
}
|
||||
else {
|
||||
for (const element of name.elements) {
|
||||
if (!isOmittedExpression(element)) {
|
||||
hoistVariable(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function transformInitializedVariable(node: VariableDeclaration) {
|
||||
const converted = setSourceMapRange(
|
||||
createAssignment(
|
||||
convertToAssignmentElementTarget(node.name),
|
||||
node.initializer
|
||||
),
|
||||
node
|
||||
);
|
||||
return visitNode(converted, visitor, isExpression);
|
||||
}
|
||||
|
||||
function collidesWithParameterName({ name }: VariableDeclaration | BindingElement): boolean {
|
||||
if (isIdentifier(name)) {
|
||||
return enclosingFunctionParameterNames.has(name.escapedText);
|
||||
}
|
||||
else {
|
||||
for (const element of name.elements) {
|
||||
if (!isOmittedExpression(element) && collidesWithParameterName(element)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function transformAsyncFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody;
|
||||
function transformAsyncFunctionBody(node: ArrowFunction): ConciseBody;
|
||||
function transformAsyncFunctionBody(node: FunctionLikeDeclaration): ConciseBody {
|
||||
@@ -214,6 +394,13 @@ namespace ts {
|
||||
// passed to `__awaiter` is executed inside of the callback to the
|
||||
// promise constructor.
|
||||
|
||||
const savedEnclosingFunctionParameterNames = enclosingFunctionParameterNames;
|
||||
enclosingFunctionParameterNames = createUnderscoreEscapedMap<true>();
|
||||
for (const parameter of node.parameters) {
|
||||
recordDeclarationName(parameter, enclosingFunctionParameterNames);
|
||||
}
|
||||
|
||||
let result: ConciseBody;
|
||||
if (!isArrowFunction) {
|
||||
const statements: Statement[] = [];
|
||||
const statementOffset = addPrologue(statements, (<Block>node.body).statements, /*ensureUseStrict*/ false, visitor);
|
||||
@@ -223,7 +410,7 @@ namespace ts {
|
||||
context,
|
||||
hasLexicalArguments,
|
||||
promiseConstructor,
|
||||
transformFunctionBodyWorker(<Block>node.body, statementOffset)
|
||||
transformAsyncFunctionBodyWorker(<Block>node.body, statementOffset)
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -246,35 +433,36 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
return block;
|
||||
result = block;
|
||||
}
|
||||
else {
|
||||
const expression = createAwaiterHelper(
|
||||
context,
|
||||
hasLexicalArguments,
|
||||
promiseConstructor,
|
||||
transformFunctionBodyWorker(node.body)
|
||||
transformAsyncFunctionBodyWorker(node.body)
|
||||
);
|
||||
|
||||
const declarations = endLexicalEnvironment();
|
||||
if (some(declarations)) {
|
||||
const block = convertToFunctionBody(expression);
|
||||
return updateBlock(block, setTextRange(createNodeArray(concatenate(block.statements, declarations)), block.statements));
|
||||
result = updateBlock(block, setTextRange(createNodeArray(concatenate(block.statements, declarations)), block.statements));
|
||||
}
|
||||
else {
|
||||
result = expression;
|
||||
}
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames;
|
||||
return result;
|
||||
}
|
||||
|
||||
function transformFunctionBodyWorker(body: ConciseBody, start?: number) {
|
||||
function transformAsyncFunctionBodyWorker(body: ConciseBody, start?: number) {
|
||||
if (isBlock(body)) {
|
||||
return updateBlock(body, visitLexicalEnvironment(body.statements, visitor, context, start));
|
||||
return updateBlock(body, visitNodes(body.statements, asyncBodyVisitor, isStatement, start));
|
||||
}
|
||||
else {
|
||||
startLexicalEnvironment();
|
||||
const visited = convertToFunctionBody(visitNode(body, visitor, isConciseBody));
|
||||
const declarations = endLexicalEnvironment();
|
||||
return updateBlock(visited, setTextRange(createNodeArray(concatenate(visited.statements, declarations)), visited.statements));
|
||||
return convertToFunctionBody(visitNode(body, asyncBodyVisitor, isConciseBody));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitLabeledStatement(node: LabeledStatement) {
|
||||
if (enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator) {
|
||||
if (enclosingFunctionFlags & FunctionFlags.Async) {
|
||||
const statement = unwrapInnermostStatementOfLabel(node);
|
||||
if (statement.kind === SyntaxKind.ForOfStatement && (<ForOfStatement>statement).awaitModifier) {
|
||||
return visitForOfStatement(<ForOfStatement>statement, node);
|
||||
|
||||
+33
-36
@@ -21,10 +21,10 @@ namespace ts {
|
||||
return <string>diagnostic.messageText;
|
||||
}
|
||||
|
||||
let reportDiagnostic = createDiagnosticReporter(sys, reportDiagnosticSimply);
|
||||
let reportDiagnostic = createDiagnosticReporter(sys);
|
||||
function udpateReportDiagnostic(options: CompilerOptions) {
|
||||
if (options.pretty) {
|
||||
reportDiagnostic = createDiagnosticReporter(sys, reportDiagnosticWithColorAndContext);
|
||||
reportDiagnostic = createDiagnosticReporter(sys, /*pretty*/ true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace ts {
|
||||
// If there are any errors due to command line parsing and/or
|
||||
// setting up localization, report them and quit.
|
||||
if (commandLine.errors.length > 0) {
|
||||
reportDiagnostics(commandLine.errors, reportDiagnostic);
|
||||
commandLine.errors.forEach(reportDiagnostic);
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
|
||||
@@ -110,12 +110,11 @@ namespace ts {
|
||||
|
||||
const commandLineOptions = commandLine.options;
|
||||
if (configFileName) {
|
||||
const reportWatchDiagnostic = createWatchDiagnosticReporter();
|
||||
const configParseResult = parseConfigFile(configFileName, commandLineOptions, sys, reportDiagnostic, reportWatchDiagnostic);
|
||||
const configParseResult = parseConfigFileWithSystem(configFileName, commandLineOptions, sys, reportDiagnostic);
|
||||
udpateReportDiagnostic(configParseResult.options);
|
||||
if (isWatchSet(configParseResult.options)) {
|
||||
reportWatchModeWithoutSysSupport();
|
||||
createWatchModeWithConfigFile(configParseResult, commandLineOptions, createWatchingSystemHost(reportWatchDiagnostic));
|
||||
createWatchOfConfigFile(configParseResult, commandLineOptions);
|
||||
}
|
||||
else {
|
||||
performCompilation(configParseResult.fileNames, configParseResult.options);
|
||||
@@ -125,7 +124,7 @@ namespace ts {
|
||||
udpateReportDiagnostic(commandLineOptions);
|
||||
if (isWatchSet(commandLineOptions)) {
|
||||
reportWatchModeWithoutSysSupport();
|
||||
createWatchModeWithoutConfigFile(commandLine.fileNames, commandLineOptions, createWatchingSystemHost());
|
||||
createWatchOfFilesAndCompilerOptions(commandLine.fileNames, commandLineOptions);
|
||||
}
|
||||
else {
|
||||
performCompilation(commandLine.fileNames, commandLineOptions);
|
||||
@@ -145,44 +144,42 @@ namespace ts {
|
||||
enableStatistics(compilerOptions);
|
||||
|
||||
const program = createProgram(rootFileNames, compilerOptions, compilerHost);
|
||||
const exitStatus = compileProgram(program);
|
||||
|
||||
const exitStatus = emitFilesAndReportErrors(program, reportDiagnostic, s => sys.write(s + sys.newLine));
|
||||
reportStatistics(program);
|
||||
return sys.exit(exitStatus);
|
||||
}
|
||||
|
||||
function createWatchingSystemHost(reportWatchDiagnostic?: DiagnosticReporter) {
|
||||
const watchingHost = ts.createWatchingSystemHost(/*pretty*/ undefined, sys, parseConfigFile, reportDiagnostic, reportWatchDiagnostic);
|
||||
watchingHost.beforeCompile = enableStatistics;
|
||||
const afterCompile = watchingHost.afterCompile;
|
||||
watchingHost.afterCompile = (host, program, builder) => {
|
||||
afterCompile(host, program, builder);
|
||||
reportStatistics(program);
|
||||
function updateWatchCompilationHost(watchCompilerHost: WatchCompilerHost<EmitAndSemanticDiagnosticsBuilderProgram>) {
|
||||
const compileUsingBuilder = watchCompilerHost.createProgram;
|
||||
watchCompilerHost.createProgram = (rootNames, options, host, oldProgram) => {
|
||||
enableStatistics(options);
|
||||
return compileUsingBuilder(rootNames, options, host, oldProgram);
|
||||
};
|
||||
const emitFilesUsingBuilder = watchCompilerHost.afterProgramCreate;
|
||||
watchCompilerHost.afterProgramCreate = builderProgram => {
|
||||
emitFilesUsingBuilder(builderProgram);
|
||||
reportStatistics(builderProgram.getProgram());
|
||||
};
|
||||
return watchingHost;
|
||||
}
|
||||
|
||||
function compileProgram(program: Program): ExitStatus {
|
||||
let diagnostics: Diagnostic[];
|
||||
function createWatchStatusReporter(options: CompilerOptions) {
|
||||
return ts.createWatchStatusReporter(sys, !!options.pretty);
|
||||
}
|
||||
|
||||
// First get and report any syntactic errors.
|
||||
diagnostics = program.getSyntacticDiagnostics().slice();
|
||||
function createWatchOfConfigFile(configParseResult: ParsedCommandLine, optionsToExtend: CompilerOptions) {
|
||||
const watchCompilerHost = ts.createWatchCompilerHostOfConfigFile(configParseResult.options.configFilePath, optionsToExtend, sys, /*createProgram*/ undefined, reportDiagnostic, createWatchStatusReporter(configParseResult.options));
|
||||
updateWatchCompilationHost(watchCompilerHost);
|
||||
watchCompilerHost.rootFiles = configParseResult.fileNames;
|
||||
watchCompilerHost.options = configParseResult.options;
|
||||
watchCompilerHost.configFileSpecs = configParseResult.configFileSpecs;
|
||||
watchCompilerHost.configFileWildCardDirectories = configParseResult.wildcardDirectories;
|
||||
createWatchProgram(watchCompilerHost);
|
||||
}
|
||||
|
||||
// If we didn't have any syntactic errors, then also try getting the global and
|
||||
// semantic errors.
|
||||
if (diagnostics.length === 0) {
|
||||
diagnostics = program.getOptionsDiagnostics().concat(program.getGlobalDiagnostics());
|
||||
|
||||
if (diagnostics.length === 0) {
|
||||
diagnostics = program.getSemanticDiagnostics().slice();
|
||||
}
|
||||
}
|
||||
|
||||
// Emit and report any errors we ran into.
|
||||
const { emittedFiles, emitSkipped, diagnostics: emitDiagnostics } = program.emit();
|
||||
addRange(diagnostics, emitDiagnostics);
|
||||
|
||||
return handleEmitOutputAndReportErrors(sys, program, emittedFiles, emitSkipped, diagnostics, reportDiagnostic);
|
||||
function createWatchOfFilesAndCompilerOptions(rootFiles: string[], options: CompilerOptions) {
|
||||
const watchCompilerHost = ts.createWatchCompilerHostOfFilesAndCompilerOptions(rootFiles, options, sys, /*createProgram*/ undefined, reportDiagnostic, createWatchStatusReporter(options));
|
||||
updateWatchCompilationHost(watchCompilerHost);
|
||||
createWatchProgram(watchCompilerHost);
|
||||
}
|
||||
|
||||
function enableStatistics(compilerOptions: CompilerOptions) {
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"emitter.ts",
|
||||
"watchUtilities.ts",
|
||||
"program.ts",
|
||||
"builderState.ts",
|
||||
"builder.ts",
|
||||
"resolutionCache.ts",
|
||||
"watch.ts",
|
||||
|
||||
@@ -2908,7 +2908,7 @@ namespace ts {
|
||||
// Should not be called directly. Should only be accessed through the Program instance.
|
||||
/* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
|
||||
/* @internal */ getGlobalDiagnostics(): Diagnostic[];
|
||||
/* @internal */ getEmitResolver(sourceFile?: SourceFile, cancellationToken?: CancellationToken): EmitResolver;
|
||||
/* @internal */ getEmitResolver(sourceFile?: SourceFile, cancellationToken?: CancellationToken, ignoreDiagnostics?: boolean): EmitResolver;
|
||||
|
||||
/* @internal */ getNodeCount(): number;
|
||||
/* @internal */ getIdentifierCount(): number;
|
||||
@@ -2937,6 +2937,8 @@ namespace ts {
|
||||
/* @internal */ getAccessibleSymbolChain(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, useOnlyExternalAliasing: boolean): Symbol[] | undefined;
|
||||
/* @internal */ getTypePredicateOfSignature(signature: Signature): TypePredicate;
|
||||
/* @internal */ resolveExternalModuleSymbol(symbol: Symbol): Symbol;
|
||||
/** @param node A location where we might consider accessing `this`. Not necessarily a ThisExpression. */
|
||||
/* @internal */ tryGetThisTypeAt(node: Node): Type | undefined;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -4016,6 +4018,7 @@ namespace ts {
|
||||
/** configFile is set as non enumerable property so as to avoid checking of json source files */
|
||||
/* @internal */ readonly configFile?: JsonSourceFile;
|
||||
declaration?: boolean;
|
||||
emitDeclarationsOnly?: boolean;
|
||||
declarationDir?: string;
|
||||
/* @internal */ diagnostics?: boolean;
|
||||
/* @internal */ extendedDiagnostics?: boolean;
|
||||
@@ -4520,6 +4523,7 @@ namespace ts {
|
||||
/* @internal */ onReleaseOldSourceFile?(oldSourceFile: SourceFile, oldOptions: CompilerOptions): void;
|
||||
/* @internal */ hasInvalidatedResolution?: HasInvalidatedResolution;
|
||||
/* @internal */ hasChangedAutomaticTypeDirectiveNames?: boolean;
|
||||
createHash?(data: string): string;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export const emptyArray: never[] = [] as never[];
|
||||
export const resolvingEmptyArray: never[] = [] as never[];
|
||||
export const emptyMap: ReadonlyMap<never> = createMap<never>();
|
||||
export const emptyUnderscoreEscapedMap: ReadonlyUnderscoreEscapedMap<never> = emptyMap as ReadonlyUnderscoreEscapedMap<never>;
|
||||
@@ -600,6 +599,11 @@ namespace ts {
|
||||
return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
export function createDiagnosticForNodeArray(sourceFile: SourceFile, nodes: NodeArray<Node>, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic {
|
||||
const start = skipTrivia(sourceFile.text, nodes.pos);
|
||||
return createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
export function createDiagnosticForNodeInSourceFile(sourceFile: SourceFile, node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic {
|
||||
const span = getErrorSpanForNode(sourceFile, node);
|
||||
return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2, arg3);
|
||||
@@ -1766,6 +1770,51 @@ namespace ts {
|
||||
return getAssignmentTargetKind(node) !== AssignmentKind.None;
|
||||
}
|
||||
|
||||
export type NodeWithPossibleHoistedDeclaration =
|
||||
| Block
|
||||
| VariableStatement
|
||||
| WithStatement
|
||||
| IfStatement
|
||||
| SwitchStatement
|
||||
| CaseBlock
|
||||
| CaseClause
|
||||
| DefaultClause
|
||||
| LabeledStatement
|
||||
| ForStatement
|
||||
| ForInStatement
|
||||
| ForOfStatement
|
||||
| DoStatement
|
||||
| WhileStatement
|
||||
| TryStatement
|
||||
| CatchClause;
|
||||
|
||||
/**
|
||||
* Indicates whether a node could contain a `var` VariableDeclarationList that contributes to
|
||||
* the same `var` declaration scope as the node's parent.
|
||||
*/
|
||||
export function isNodeWithPossibleHoistedDeclaration(node: Node): node is NodeWithPossibleHoistedDeclaration {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Block:
|
||||
case SyntaxKind.VariableStatement:
|
||||
case SyntaxKind.WithStatement:
|
||||
case SyntaxKind.IfStatement:
|
||||
case SyntaxKind.SwitchStatement:
|
||||
case SyntaxKind.CaseBlock:
|
||||
case SyntaxKind.CaseClause:
|
||||
case SyntaxKind.DefaultClause:
|
||||
case SyntaxKind.LabeledStatement:
|
||||
case SyntaxKind.ForStatement:
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
case SyntaxKind.DoStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
case SyntaxKind.TryStatement:
|
||||
case SyntaxKind.CatchClause:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function walkUp(node: Node, kind: SyntaxKind) {
|
||||
while (node && node.kind === kind) {
|
||||
node = node.parent;
|
||||
@@ -1985,7 +2034,13 @@ namespace ts {
|
||||
return token !== undefined && isNonContextualKeyword(token);
|
||||
}
|
||||
|
||||
export function isTrivia(token: SyntaxKind) {
|
||||
export type TriviaKind = SyntaxKind.SingleLineCommentTrivia
|
||||
| SyntaxKind.MultiLineCommentTrivia
|
||||
| SyntaxKind.NewLineTrivia
|
||||
| SyntaxKind.WhitespaceTrivia
|
||||
| SyntaxKind.ShebangTrivia
|
||||
| SyntaxKind.ConflictMarkerTrivia;
|
||||
export function isTrivia(token: SyntaxKind): token is TriviaKind {
|
||||
return SyntaxKind.FirstTriviaToken <= token && token <= SyntaxKind.LastTriviaToken;
|
||||
}
|
||||
|
||||
@@ -3330,14 +3385,14 @@ namespace ts {
|
||||
|
||||
const carriageReturnLineFeed = "\r\n";
|
||||
const lineFeed = "\n";
|
||||
export function getNewLineCharacter(options: CompilerOptions | PrinterOptions, system?: { newLine: string }): string {
|
||||
export function getNewLineCharacter(options: CompilerOptions | PrinterOptions, getNewLine?: () => string): string {
|
||||
switch (options.newLine) {
|
||||
case NewLineKind.CarriageReturnLineFeed:
|
||||
return carriageReturnLineFeed;
|
||||
case NewLineKind.LineFeed:
|
||||
return lineFeed;
|
||||
}
|
||||
return system ? system.newLine : sys ? sys.newLine : carriageReturnLineFeed;
|
||||
return getNewLine ? getNewLine() : sys ? sys.newLine : carriageReturnLineFeed;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4662,7 +4717,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function isTypeOfExpression(node: Node): node is TypeOfExpression {
|
||||
return node.kind === SyntaxKind.AwaitExpression;
|
||||
return node.kind === SyntaxKind.TypeOfExpression;
|
||||
}
|
||||
|
||||
export function isVoidExpression(node: Node): node is VoidExpression {
|
||||
|
||||
+523
-263
File diff suppressed because it is too large
Load Diff
+260
-11
@@ -2,6 +2,247 @@
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
/**
|
||||
* Partial interface of the System thats needed to support the caching of directory structure
|
||||
*/
|
||||
export interface DirectoryStructureHost {
|
||||
fileExists(path: string): boolean;
|
||||
readFile(path: string, encoding?: string): string | undefined;
|
||||
|
||||
directoryExists?(path: string): boolean;
|
||||
getDirectories?(path: string): string[];
|
||||
readDirectory?(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
|
||||
createDirectory?(path: string): void;
|
||||
writeFile?(path: string, data: string, writeByteOrderMark?: boolean): void;
|
||||
}
|
||||
|
||||
interface FileAndDirectoryExistence {
|
||||
fileExists: boolean;
|
||||
directoryExists: boolean;
|
||||
}
|
||||
|
||||
export interface CachedDirectoryStructureHost extends DirectoryStructureHost {
|
||||
useCaseSensitiveFileNames: boolean;
|
||||
|
||||
getDirectories(path: string): string[];
|
||||
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
|
||||
/** Returns the queried result for the file exists and directory exists if at all it was done */
|
||||
addOrDeleteFileOrDirectory(fileOrDirectory: string, fileOrDirectoryPath: Path): FileAndDirectoryExistence | undefined;
|
||||
addOrDeleteFile(fileName: string, filePath: Path, eventKind: FileWatcherEventKind): void;
|
||||
clearCache(): void;
|
||||
}
|
||||
|
||||
interface MutableFileSystemEntries {
|
||||
readonly files: string[];
|
||||
readonly directories: string[];
|
||||
}
|
||||
|
||||
export function createCachedDirectoryStructureHost(host: DirectoryStructureHost, currentDirectory: string, useCaseSensitiveFileNames: boolean): CachedDirectoryStructureHost | undefined {
|
||||
if (!host.getDirectories || !host.readDirectory) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const cachedReadDirectoryResult = createMap<MutableFileSystemEntries>();
|
||||
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
return {
|
||||
useCaseSensitiveFileNames,
|
||||
fileExists,
|
||||
readFile: (path, encoding) => host.readFile(path, encoding),
|
||||
directoryExists: host.directoryExists && directoryExists,
|
||||
getDirectories,
|
||||
readDirectory,
|
||||
createDirectory: host.createDirectory && createDirectory,
|
||||
writeFile: host.writeFile && writeFile,
|
||||
addOrDeleteFileOrDirectory,
|
||||
addOrDeleteFile,
|
||||
clearCache
|
||||
};
|
||||
|
||||
function toPath(fileName: string) {
|
||||
return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
|
||||
}
|
||||
|
||||
function getCachedFileSystemEntries(rootDirPath: Path): MutableFileSystemEntries | undefined {
|
||||
return cachedReadDirectoryResult.get(rootDirPath);
|
||||
}
|
||||
|
||||
function getCachedFileSystemEntriesForBaseDir(path: Path): MutableFileSystemEntries | undefined {
|
||||
return getCachedFileSystemEntries(getDirectoryPath(path));
|
||||
}
|
||||
|
||||
function getBaseNameOfFileName(fileName: string) {
|
||||
return getBaseFileName(normalizePath(fileName));
|
||||
}
|
||||
|
||||
function createCachedFileSystemEntries(rootDir: string, rootDirPath: Path) {
|
||||
const resultFromHost: MutableFileSystemEntries = {
|
||||
files: map(host.readDirectory(rootDir, /*extensions*/ undefined, /*exclude*/ undefined, /*include*/["*.*"]), getBaseNameOfFileName) || [],
|
||||
directories: host.getDirectories(rootDir) || []
|
||||
};
|
||||
|
||||
cachedReadDirectoryResult.set(rootDirPath, resultFromHost);
|
||||
return resultFromHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the readDirectory result was already cached, it returns that
|
||||
* Otherwise gets result from host and caches it.
|
||||
* The host request is done under try catch block to avoid caching incorrect result
|
||||
*/
|
||||
function tryReadDirectory(rootDir: string, rootDirPath: Path): MutableFileSystemEntries | undefined {
|
||||
const cachedResult = getCachedFileSystemEntries(rootDirPath);
|
||||
if (cachedResult) {
|
||||
return cachedResult;
|
||||
}
|
||||
|
||||
try {
|
||||
return createCachedFileSystemEntries(rootDir, rootDirPath);
|
||||
}
|
||||
catch (_e) {
|
||||
// If there is exception to read directories, dont cache the result and direct the calls to host
|
||||
Debug.assert(!cachedReadDirectoryResult.has(rootDirPath));
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function fileNameEqual(name1: string, name2: string) {
|
||||
return getCanonicalFileName(name1) === getCanonicalFileName(name2);
|
||||
}
|
||||
|
||||
function hasEntry(entries: ReadonlyArray<string>, name: string) {
|
||||
return some(entries, file => fileNameEqual(file, name));
|
||||
}
|
||||
|
||||
function updateFileSystemEntry(entries: string[], baseName: string, isValid: boolean) {
|
||||
if (hasEntry(entries, baseName)) {
|
||||
if (!isValid) {
|
||||
return filterMutate(entries, entry => !fileNameEqual(entry, baseName));
|
||||
}
|
||||
}
|
||||
else if (isValid) {
|
||||
return entries.push(baseName);
|
||||
}
|
||||
}
|
||||
|
||||
function writeFile(fileName: string, data: string, writeByteOrderMark?: boolean): void {
|
||||
const path = toPath(fileName);
|
||||
const result = getCachedFileSystemEntriesForBaseDir(path);
|
||||
if (result) {
|
||||
updateFilesOfFileSystemEntry(result, getBaseNameOfFileName(fileName), /*fileExists*/ true);
|
||||
}
|
||||
return host.writeFile(fileName, data, writeByteOrderMark);
|
||||
}
|
||||
|
||||
function fileExists(fileName: string): boolean {
|
||||
const path = toPath(fileName);
|
||||
const result = getCachedFileSystemEntriesForBaseDir(path);
|
||||
return result && hasEntry(result.files, getBaseNameOfFileName(fileName)) ||
|
||||
host.fileExists(fileName);
|
||||
}
|
||||
|
||||
function directoryExists(dirPath: string): boolean {
|
||||
const path = toPath(dirPath);
|
||||
return cachedReadDirectoryResult.has(path) || host.directoryExists(dirPath);
|
||||
}
|
||||
|
||||
function createDirectory(dirPath: string) {
|
||||
const path = toPath(dirPath);
|
||||
const result = getCachedFileSystemEntriesForBaseDir(path);
|
||||
const baseFileName = getBaseNameOfFileName(dirPath);
|
||||
if (result) {
|
||||
updateFileSystemEntry(result.directories, baseFileName, /*isValid*/ true);
|
||||
}
|
||||
host.createDirectory(dirPath);
|
||||
}
|
||||
|
||||
function getDirectories(rootDir: string): string[] {
|
||||
const rootDirPath = toPath(rootDir);
|
||||
const result = tryReadDirectory(rootDir, rootDirPath);
|
||||
if (result) {
|
||||
return result.directories.slice();
|
||||
}
|
||||
return host.getDirectories(rootDir);
|
||||
}
|
||||
|
||||
function readDirectory(rootDir: string, extensions?: ReadonlyArray<string>, excludes?: ReadonlyArray<string>, includes?: ReadonlyArray<string>, depth?: number): string[] {
|
||||
const rootDirPath = toPath(rootDir);
|
||||
const result = tryReadDirectory(rootDir, rootDirPath);
|
||||
if (result) {
|
||||
return matchFiles(rootDir, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory, depth, getFileSystemEntries);
|
||||
}
|
||||
return host.readDirectory(rootDir, extensions, excludes, includes, depth);
|
||||
|
||||
function getFileSystemEntries(dir: string) {
|
||||
const path = toPath(dir);
|
||||
if (path === rootDirPath) {
|
||||
return result;
|
||||
}
|
||||
return tryReadDirectory(dir, path) || emptyFileSystemEntries;
|
||||
}
|
||||
}
|
||||
|
||||
function addOrDeleteFileOrDirectory(fileOrDirectory: string, fileOrDirectoryPath: Path) {
|
||||
const existingResult = getCachedFileSystemEntries(fileOrDirectoryPath);
|
||||
if (existingResult) {
|
||||
// Just clear the cache for now
|
||||
// For now just clear the cache, since this could mean that multiple level entries might need to be re-evaluated
|
||||
clearCache();
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const parentResult = getCachedFileSystemEntriesForBaseDir(fileOrDirectoryPath);
|
||||
if (!parentResult) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// This was earlier a file (hence not in cached directory contents)
|
||||
// or we never cached the directory containing it
|
||||
|
||||
if (!host.directoryExists) {
|
||||
// Since host doesnt support directory exists, clear the cache as otherwise it might not be same
|
||||
clearCache();
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const baseName = getBaseNameOfFileName(fileOrDirectory);
|
||||
const fsQueryResult: FileAndDirectoryExistence = {
|
||||
fileExists: host.fileExists(fileOrDirectoryPath),
|
||||
directoryExists: host.directoryExists(fileOrDirectoryPath)
|
||||
};
|
||||
if (fsQueryResult.directoryExists || hasEntry(parentResult.directories, baseName)) {
|
||||
// Folder added or removed, clear the cache instead of updating the folder and its structure
|
||||
clearCache();
|
||||
}
|
||||
else {
|
||||
// No need to update the directory structure, just files
|
||||
updateFilesOfFileSystemEntry(parentResult, baseName, fsQueryResult.fileExists);
|
||||
}
|
||||
return fsQueryResult;
|
||||
|
||||
}
|
||||
|
||||
function addOrDeleteFile(fileName: string, filePath: Path, eventKind: FileWatcherEventKind) {
|
||||
if (eventKind === FileWatcherEventKind.Changed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const parentResult = getCachedFileSystemEntriesForBaseDir(filePath);
|
||||
if (parentResult) {
|
||||
updateFilesOfFileSystemEntry(parentResult, getBaseNameOfFileName(fileName), eventKind === FileWatcherEventKind.Created);
|
||||
}
|
||||
}
|
||||
|
||||
function updateFilesOfFileSystemEntry(parentResult: MutableFileSystemEntries, baseName: string, fileExists: boolean) {
|
||||
updateFileSystemEntry(parentResult.files, baseName, fileExists);
|
||||
}
|
||||
|
||||
function clearCache() {
|
||||
cachedReadDirectoryResult.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export enum ConfigFileProgramReloadLevel {
|
||||
None,
|
||||
/** Update the file name list from the disk */
|
||||
@@ -90,53 +331,61 @@ namespace ts {
|
||||
return program.isEmittedFile(file);
|
||||
}
|
||||
|
||||
export function addFileWatcher(host: System, file: string, cb: FileWatcherCallback): FileWatcher {
|
||||
export interface WatchFileHost {
|
||||
watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
}
|
||||
|
||||
export function addFileWatcher(host: WatchFileHost, file: string, cb: FileWatcherCallback): FileWatcher {
|
||||
return host.watchFile(file, cb);
|
||||
}
|
||||
|
||||
export function addFileWatcherWithLogging(host: System, file: string, cb: FileWatcherCallback, log: (s: string) => void): FileWatcher {
|
||||
export function addFileWatcherWithLogging(host: WatchFileHost, file: string, cb: FileWatcherCallback, log: (s: string) => void): FileWatcher {
|
||||
const watcherCaption = `FileWatcher:: `;
|
||||
return createWatcherWithLogging(addFileWatcher, watcherCaption, log, /*logOnlyTrigger*/ false, host, file, cb);
|
||||
}
|
||||
|
||||
export function addFileWatcherWithOnlyTriggerLogging(host: System, file: string, cb: FileWatcherCallback, log: (s: string) => void): FileWatcher {
|
||||
export function addFileWatcherWithOnlyTriggerLogging(host: WatchFileHost, file: string, cb: FileWatcherCallback, log: (s: string) => void): FileWatcher {
|
||||
const watcherCaption = `FileWatcher:: `;
|
||||
return createWatcherWithLogging(addFileWatcher, watcherCaption, log, /*logOnlyTrigger*/ true, host, file, cb);
|
||||
}
|
||||
|
||||
export type FilePathWatcherCallback = (fileName: string, eventKind: FileWatcherEventKind, filePath: Path) => void;
|
||||
export function addFilePathWatcher(host: System, file: string, cb: FilePathWatcherCallback, path: Path): FileWatcher {
|
||||
export function addFilePathWatcher(host: WatchFileHost, file: string, cb: FilePathWatcherCallback, path: Path): FileWatcher {
|
||||
return host.watchFile(file, (fileName, eventKind) => cb(fileName, eventKind, path));
|
||||
}
|
||||
|
||||
export function addFilePathWatcherWithLogging(host: System, file: string, cb: FilePathWatcherCallback, path: Path, log: (s: string) => void): FileWatcher {
|
||||
export function addFilePathWatcherWithLogging(host: WatchFileHost, file: string, cb: FilePathWatcherCallback, path: Path, log: (s: string) => void): FileWatcher {
|
||||
const watcherCaption = `FileWatcher:: `;
|
||||
return createWatcherWithLogging(addFileWatcher, watcherCaption, log, /*logOnlyTrigger*/ false, host, file, cb, path);
|
||||
}
|
||||
|
||||
export function addFilePathWatcherWithOnlyTriggerLogging(host: System, file: string, cb: FilePathWatcherCallback, path: Path, log: (s: string) => void): FileWatcher {
|
||||
export function addFilePathWatcherWithOnlyTriggerLogging(host: WatchFileHost, file: string, cb: FilePathWatcherCallback, path: Path, log: (s: string) => void): FileWatcher {
|
||||
const watcherCaption = `FileWatcher:: `;
|
||||
return createWatcherWithLogging(addFileWatcher, watcherCaption, log, /*logOnlyTrigger*/ true, host, file, cb, path);
|
||||
}
|
||||
|
||||
export function addDirectoryWatcher(host: System, directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags): FileWatcher {
|
||||
export interface WatchDirectoryHost {
|
||||
watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
}
|
||||
|
||||
export function addDirectoryWatcher(host: WatchDirectoryHost, directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags): FileWatcher {
|
||||
const recursive = (flags & WatchDirectoryFlags.Recursive) !== 0;
|
||||
return host.watchDirectory(directory, cb, recursive);
|
||||
}
|
||||
|
||||
export function addDirectoryWatcherWithLogging(host: System, directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags, log: (s: string) => void): FileWatcher {
|
||||
export function addDirectoryWatcherWithLogging(host: WatchDirectoryHost, directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags, log: (s: string) => void): FileWatcher {
|
||||
const watcherCaption = `DirectoryWatcher ${(flags & WatchDirectoryFlags.Recursive) !== 0 ? "recursive" : ""}:: `;
|
||||
return createWatcherWithLogging(addDirectoryWatcher, watcherCaption, log, /*logOnlyTrigger*/ false, host, directory, cb, flags);
|
||||
}
|
||||
|
||||
export function addDirectoryWatcherWithOnlyTriggerLogging(host: System, directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags, log: (s: string) => void): FileWatcher {
|
||||
export function addDirectoryWatcherWithOnlyTriggerLogging(host: WatchDirectoryHost, directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags, log: (s: string) => void): FileWatcher {
|
||||
const watcherCaption = `DirectoryWatcher ${(flags & WatchDirectoryFlags.Recursive) !== 0 ? "recursive" : ""}:: `;
|
||||
return createWatcherWithLogging(addDirectoryWatcher, watcherCaption, log, /*logOnlyTrigger*/ true, host, directory, cb, flags);
|
||||
}
|
||||
|
||||
type WatchCallback<T, U> = (fileName: string, cbOptional1?: T, optional?: U) => void;
|
||||
type AddWatch<T, U> = (host: System, file: string, cb: WatchCallback<T, U>, optional?: U) => FileWatcher;
|
||||
function createWatcherWithLogging<T, U>(addWatch: AddWatch<T, U>, watcherCaption: string, log: (s: string) => void, logOnlyTrigger: boolean, host: System, file: string, cb: WatchCallback<T, U>, optional?: U): FileWatcher {
|
||||
type AddWatch<H, T, U> = (host: H, file: string, cb: WatchCallback<T, U>, optional?: U) => FileWatcher;
|
||||
function createWatcherWithLogging<H, T, U>(addWatch: AddWatch<H, T, U>, watcherCaption: string, log: (s: string) => void, logOnlyTrigger: boolean, host: H, file: string, cb: WatchCallback<T, U>, optional?: U): FileWatcher {
|
||||
const info = `PathInfo: ${file}`;
|
||||
if (!logOnlyTrigger) {
|
||||
log(`${watcherCaption}Added: ${info}`);
|
||||
|
||||
@@ -33,12 +33,15 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
|
||||
});
|
||||
}
|
||||
private runTest(directoryName: string) {
|
||||
describe(directoryName, () => {
|
||||
// tslint:disable-next-line:no-this-assignment
|
||||
const cls = this;
|
||||
const timeout = 600_000; // 10 minutes
|
||||
describe(directoryName, function(this: Mocha.ISuiteCallbackContext) {
|
||||
this.timeout(timeout);
|
||||
const cp = require("child_process");
|
||||
|
||||
it("should build successfully", () => {
|
||||
let cwd = path.join(__dirname, "../../", this.testDir, directoryName);
|
||||
const timeout = 600000; // 600s = 10 minutes
|
||||
let cwd = path.join(__dirname, "../../", cls.testDir, directoryName);
|
||||
const stdio = isWorker ? "pipe" : "inherit";
|
||||
let types: string[];
|
||||
if (fs.existsSync(path.join(cwd, "test.json"))) {
|
||||
@@ -61,9 +64,9 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
|
||||
fs.unlinkSync(path.join(cwd, "package-lock.json"));
|
||||
}
|
||||
if (fs.existsSync(path.join(cwd, "node_modules"))) {
|
||||
require("del").sync(path.join(cwd, "node_modules"));
|
||||
require("del").sync(path.join(cwd, "node_modules"), { force: true });
|
||||
}
|
||||
const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio });
|
||||
const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout: timeout / 2, shell: true, stdio }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
|
||||
if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed: ${install.stderr.toString()}`);
|
||||
}
|
||||
const args = [path.join(__dirname, "tsc.js")];
|
||||
@@ -71,8 +74,8 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
|
||||
args.push("--types", types.join(","));
|
||||
}
|
||||
args.push("--noEmit");
|
||||
Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => {
|
||||
return this.report(cp.spawnSync(`node`, args, { cwd, timeout, shell: true }), cwd);
|
||||
Harness.Baseline.runBaseline(`${cls.kind()}/${directoryName}.log`, () => {
|
||||
return cls.report(cp.spawnSync(`node`, args, { cwd, timeout, shell: true }), cwd);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -128,13 +131,13 @@ function removeExpectedErrors(errors: string, cwd: string): string {
|
||||
function isUnexpectedError(cwd: string) {
|
||||
return (error: string[]) => {
|
||||
ts.Debug.assertGreaterThanOrEqual(error.length, 1);
|
||||
const match = error[0].match(/(.+\.ts)\((\d+),\d+\): error TS/);
|
||||
const match = error[0].match(/(.+\.tsx?)\((\d+),\d+\): error TS/);
|
||||
if (!match) {
|
||||
return true;
|
||||
}
|
||||
const [, errorFile, lineNumberString] = match;
|
||||
const lines = fs.readFileSync(path.join(cwd, errorFile), { encoding: "utf8" }).split("\n");
|
||||
const lineNumber = parseInt(lineNumberString);
|
||||
const lineNumber = parseInt(lineNumberString) - 1;
|
||||
ts.Debug.assertGreaterThanOrEqual(lineNumber, 0);
|
||||
ts.Debug.assertLessThan(lineNumber, lines.length);
|
||||
const previousLine = lineNumber - 1 > 0 ? lines[lineNumber - 1] : "";
|
||||
|
||||
+51
-59
@@ -23,7 +23,7 @@ namespace FourSlash {
|
||||
ts.disableIncrementalParsing = false;
|
||||
|
||||
// Represents a parsed source file with metadata
|
||||
export interface FourSlashFile {
|
||||
interface FourSlashFile {
|
||||
// The contents of the file (with markers, etc stripped out)
|
||||
content: string;
|
||||
fileName: string;
|
||||
@@ -34,7 +34,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
// Represents a set of parsed source files and options
|
||||
export interface FourSlashData {
|
||||
interface FourSlashData {
|
||||
// Global options (name/value pairs)
|
||||
globalOptions: Harness.TestCaseParser.CompilerSettings;
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace FourSlash {
|
||||
export interface Marker {
|
||||
fileName: string;
|
||||
position: number;
|
||||
data?: any;
|
||||
data?: {};
|
||||
}
|
||||
|
||||
export interface Range {
|
||||
@@ -89,21 +89,6 @@ namespace FourSlash {
|
||||
end: number;
|
||||
}
|
||||
|
||||
export import IndentStyle = ts.IndentStyle;
|
||||
|
||||
const entityMap = ts.createMapFromTemplate({
|
||||
"&": "&",
|
||||
"\"": """,
|
||||
"'": "'",
|
||||
"/": "/",
|
||||
"<": "<",
|
||||
">": ">"
|
||||
});
|
||||
|
||||
export function escapeXmlAttributeValue(s: string) {
|
||||
return s.replace(/[&<>"'\/]/g, ch => entityMap.get(ch));
|
||||
}
|
||||
|
||||
// Name of testcase metadata including ts.CompilerOptions properties that will be used by globalOptions
|
||||
// To add additional option, add property into the testOptMetadataNames, refer the property in either globalMetadataNames or fileMetadataNames
|
||||
// Add cases into convertGlobalOptionsToCompilationsSettings function for the compiler to acknowledge such option from meta data
|
||||
@@ -1079,7 +1064,7 @@ namespace FourSlash {
|
||||
for (const reference of expectedReferences) {
|
||||
const { fileName, start, end } = reference;
|
||||
if (reference.marker && reference.marker.data) {
|
||||
const { isWriteAccess, isDefinition } = reference.marker.data;
|
||||
const { isWriteAccess, isDefinition } = reference.marker.data as { isWriteAccess?: boolean, isDefinition?: boolean };
|
||||
this.verifyReferencesWorker(actualReferences, fileName, start, end, isWriteAccess, isDefinition);
|
||||
}
|
||||
else {
|
||||
@@ -1102,25 +1087,35 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
public verifyReferenceGroups(startRanges: Range | Range[], parts: FourSlashInterface.ReferenceGroup[]): void {
|
||||
const fullExpected = ts.map(parts, ({ definition, ranges }) => ({ definition, ranges: ranges.map(rangeToReferenceEntry) }));
|
||||
interface ReferenceGroupJson {
|
||||
definition: string | { text: string, range: ts.TextSpan };
|
||||
references: ts.ReferenceEntry[];
|
||||
}
|
||||
const fullExpected = ts.map<FourSlashInterface.ReferenceGroup, ReferenceGroupJson>(parts, ({ definition, ranges }) => ({
|
||||
definition: typeof definition === "string" ? definition : { ...definition, range: textSpanFromRange(definition.range) },
|
||||
references: ranges.map<ts.ReferenceEntry>(r => {
|
||||
const { isWriteAccess = false, isDefinition = false, isInString } = (r.marker && r.marker.data || {}) as { isWriteAccess?: boolean, isDefinition?: boolean, isInString?: true };
|
||||
return {
|
||||
isWriteAccess,
|
||||
isDefinition,
|
||||
fileName: r.fileName,
|
||||
textSpan: textSpanFromRange(r),
|
||||
...(isInString ? { isInString: true } : undefined),
|
||||
};
|
||||
}),
|
||||
}));
|
||||
|
||||
for (const startRange of toArray(startRanges)) {
|
||||
this.goToRangeStart(startRange);
|
||||
const fullActual = ts.map(this.findReferencesAtCaret(), ({ definition, references }) => ({
|
||||
definition: definition.displayParts.map(d => d.text).join(""),
|
||||
ranges: references
|
||||
}));
|
||||
const fullActual = ts.map<ts.ReferencedSymbol, ReferenceGroupJson>(this.findReferencesAtCaret(), ({ definition, references }, i) => {
|
||||
const text = definition.displayParts.map(d => d.text).join("");
|
||||
return {
|
||||
definition: typeof fullExpected[i].definition === "string" ? text : { text, range: definition.textSpan },
|
||||
references,
|
||||
};
|
||||
});
|
||||
this.assertObjectsEqual(fullActual, fullExpected);
|
||||
}
|
||||
|
||||
function rangeToReferenceEntry(r: Range): ts.ReferenceEntry {
|
||||
const { isWriteAccess, isDefinition, isInString } = (r.marker && r.marker.data) || { isWriteAccess: false, isDefinition: false, isInString: undefined };
|
||||
const result: ts.ReferenceEntry = { fileName: r.fileName, textSpan: { start: r.start, length: r.end - r.start }, isWriteAccess: !!isWriteAccess, isDefinition: !!isDefinition };
|
||||
if (isInString !== undefined) {
|
||||
result.isInString = isInString;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public verifyNoReferences(markerNameOrRange?: string | Range) {
|
||||
@@ -1139,7 +1134,7 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public verifySingleReferenceGroup(definition: string, ranges?: Range[]) {
|
||||
public verifySingleReferenceGroup(definition: FourSlashInterface.ReferenceGroupDefinition, ranges?: Range[]) {
|
||||
ranges = ranges || this.getRanges();
|
||||
this.verifyReferenceGroups(ranges, [{ definition, ranges }]);
|
||||
}
|
||||
@@ -1305,8 +1300,13 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
public verifyRangesAreRenameLocations(options?: Range[] | { findInStrings?: boolean, findInComments?: boolean, ranges?: Range[] }) {
|
||||
const ranges = ts.isArray(options) ? options : options && options.ranges || this.getRanges();
|
||||
this.verifyRenameLocations(ranges, { ranges, ...options });
|
||||
if (ts.isArray(options)) {
|
||||
this.verifyRenameLocations(options, options);
|
||||
}
|
||||
else {
|
||||
const ranges = options && options.ranges || this.getRanges();
|
||||
this.verifyRenameLocations(ranges, { ranges, ...options });
|
||||
}
|
||||
}
|
||||
|
||||
public verifyRenameLocations(startRanges: Range | Range[], options: Range[] | { findInStrings?: boolean, findInComments?: boolean, ranges: Range[] }) {
|
||||
@@ -1535,8 +1535,8 @@ Actual: ${stringify(fullActual)}`);
|
||||
const addSpanInfoString = () => {
|
||||
if (previousSpanInfo) {
|
||||
resultString += currentLine;
|
||||
let thisLineMarker = repeatString(startColumn, " ") + repeatString(length, "~");
|
||||
thisLineMarker += repeatString(this.alignmentForExtraInfo - thisLineMarker.length - prefixString.length + 1, " ");
|
||||
let thisLineMarker = ts.repeatString(" ", startColumn) + ts.repeatString("~", length);
|
||||
thisLineMarker += ts.repeatString(" ", this.alignmentForExtraInfo - thisLineMarker.length - prefixString.length + 1);
|
||||
resultString += thisLineMarker;
|
||||
resultString += "=> Pos: (" + (pos - length) + " to " + (pos - 1) + ") ";
|
||||
resultString += " " + previousSpanInfo;
|
||||
@@ -1551,7 +1551,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
if (resultString.length) {
|
||||
resultString += "\n--------------------------------";
|
||||
}
|
||||
currentLine = "\n" + nextLine.toString() + repeatString(3 - nextLine.toString().length, " ") + ">" + this.activeFile.content.substring(pos, fileLineMap[nextLine]) + "\n ";
|
||||
currentLine = "\n" + nextLine.toString() + ts.repeatString(" ", 3 - nextLine.toString().length) + ">" + this.activeFile.content.substring(pos, fileLineMap[nextLine]) + "\n ";
|
||||
startColumn = 0;
|
||||
length = 0;
|
||||
}
|
||||
@@ -2568,18 +2568,14 @@ Actual: ${stringify(fullActual)}`);
|
||||
const originalContent = scriptInfo.content;
|
||||
for (const codeFix of codeFixes) {
|
||||
this.applyEdits(codeFix.changes[0].fileName, codeFix.changes[0].textChanges, /*isFormattingEdit*/ false);
|
||||
let text = this.rangeText(ranges[0]);
|
||||
// TODO:GH#18445 (remove this line to see errors in many `importNameCodeFix` tests)
|
||||
text = text.replace(/\r\n/g, "\n");
|
||||
const text = this.rangeText(ranges[0]);
|
||||
actualTextArray.push(text);
|
||||
scriptInfo.updateContent(originalContent);
|
||||
}
|
||||
const sortedExpectedArray = expectedTextArray.sort();
|
||||
const sortedActualArray = actualTextArray.sort();
|
||||
if (sortedExpectedArray.length !== sortedActualArray.length) {
|
||||
this.raiseError(`Expected ${sortedExpectedArray.length} import fixes, got ${sortedActualArray.length}`);
|
||||
if (expectedTextArray.length !== actualTextArray.length) {
|
||||
this.raiseError(`Expected ${expectedTextArray.length} import fixes, got ${actualTextArray.length}`);
|
||||
}
|
||||
ts.zipWith(sortedExpectedArray, sortedActualArray, (expected, actual, index) => {
|
||||
ts.zipWith(expectedTextArray, actualTextArray, (expected, actual, index) => {
|
||||
if (expected !== actual) {
|
||||
this.raiseError(`Import fix at index ${index} doesn't match.\n${showTextDiff(expected, actual)}`);
|
||||
}
|
||||
@@ -2787,7 +2783,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
const items = this.languageService.getNavigationBarItems(this.activeFile.fileName);
|
||||
Harness.IO.log(`Navigation bar (${items.length} items)`);
|
||||
for (const item of items) {
|
||||
Harness.IO.log(`${repeatString(item.indent, " ")}name: ${item.text}, kind: ${item.kind}, childItems: ${item.childItems.map(child => child.text)}`);
|
||||
Harness.IO.log(`${ts.repeatString(" ", item.indent)}name: ${item.text}, kind: ${item.kind}, childItems: ${item.childItems.map(child => child.text)}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3152,8 +3148,9 @@ Actual: ${stringify(fullActual)}`);
|
||||
assert.isTrue(TestState.textSpansEqual(span, item.replacementSpan), this.assertionMessageAtLastKnownMarker(stringify(span) + " does not equal " + stringify(item.replacementSpan) + " replacement span for " + entryId));
|
||||
}
|
||||
|
||||
assert.equal(item.hasAction, hasAction);
|
||||
assert.equal(item.hasAction, hasAction, "hasAction");
|
||||
assert.equal(item.isRecommended, options && options.isRecommended, "isRecommended");
|
||||
assert.equal(item.insertText, options && options.insertText, "insertText");
|
||||
}
|
||||
|
||||
private findFile(indexOrName: string | number) {
|
||||
@@ -3688,14 +3685,6 @@ ${code}
|
||||
};
|
||||
}
|
||||
|
||||
function repeatString(count: number, char: string) {
|
||||
let result = "";
|
||||
for (let i = 0; i < count; i++) {
|
||||
result += char;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function stringify(data: any, replacer?: (key: string, value: any) => any): string {
|
||||
return JSON.stringify(data, replacer, 2);
|
||||
}
|
||||
@@ -4084,7 +4073,7 @@ namespace FourSlashInterface {
|
||||
this.state.verifyNoReferences(markerNameOrRange);
|
||||
}
|
||||
|
||||
public singleReferenceGroup(definition: string, ranges?: FourSlash.Range[]) {
|
||||
public singleReferenceGroup(definition: ReferenceGroupDefinition, ranges?: FourSlash.Range[]) {
|
||||
this.state.verifySingleReferenceGroup(definition, ranges);
|
||||
}
|
||||
|
||||
@@ -4596,10 +4585,12 @@ namespace FourSlashInterface {
|
||||
}
|
||||
|
||||
export interface ReferenceGroup {
|
||||
definition: string;
|
||||
definition: ReferenceGroupDefinition;
|
||||
ranges: FourSlash.Range[];
|
||||
}
|
||||
|
||||
export type ReferenceGroupDefinition = string | { text: string, range: FourSlash.Range };
|
||||
|
||||
export interface ApplyRefactorOptions {
|
||||
refactorName: string;
|
||||
actionName: string;
|
||||
@@ -4615,6 +4606,7 @@ namespace FourSlashInterface {
|
||||
export interface VerifyCompletionListContainsOptions extends ts.GetCompletionsAtPositionOptions {
|
||||
sourceDisplay: string;
|
||||
isRecommended?: true;
|
||||
insertText?: string;
|
||||
}
|
||||
|
||||
export interface NewContentOptions {
|
||||
|
||||
+13
-3
@@ -1252,8 +1252,18 @@ namespace Harness {
|
||||
options: ts.CompilerOptions,
|
||||
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
|
||||
currentDirectory: string): DeclarationCompilationContext | undefined {
|
||||
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length !== result.files.length) {
|
||||
throw new Error("There were no errors and declFiles generated did not match number of js files generated");
|
||||
|
||||
if (result.errors.length === 0) {
|
||||
if (options.declaration) {
|
||||
if (options.emitDeclarationsOnly) {
|
||||
if (result.files.length > 0 || result.declFilesCode.length === 0) {
|
||||
throw new Error("Only declaration files should be generated when emitDeclarationsOnly:true");
|
||||
}
|
||||
}
|
||||
else if (result.declFilesCode.length !== result.files.length) {
|
||||
throw new Error("There were no errors and declFiles generated did not match number of js files generated");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const declInputFiles: TestFile[] = [];
|
||||
@@ -1654,7 +1664,7 @@ namespace Harness {
|
||||
}
|
||||
|
||||
export function doJsEmitBaseline(baselinePath: string, header: string, options: ts.CompilerOptions, result: CompilerResult, tsConfigFiles: Harness.Compiler.TestFile[], toBeCompiled: Harness.Compiler.TestFile[], otherFiles: Harness.Compiler.TestFile[], harnessSettings: Harness.TestCaseParser.CompilerSettings) {
|
||||
if (!options.noEmit && result.files.length === 0 && result.errors.length === 0) {
|
||||
if (!options.noEmit && !options.emitDeclarationsOnly && result.files.length === 0 && result.errors.length === 0) {
|
||||
throw new Error("Expected at least one js file to be emitted or at least one error to be created.");
|
||||
}
|
||||
|
||||
|
||||
@@ -41,22 +41,97 @@ namespace ts {
|
||||
program = updateProgramFile(program, "/b.ts", "namespace B { export const x = 1; }");
|
||||
assertChanges(["/b.js", "/a.js"]);
|
||||
});
|
||||
|
||||
it("keeps the file in affected files if cancellation token throws during the operation", () => {
|
||||
const files: NamedSourceText[] = [
|
||||
{ name: "/a.ts", text: SourceText.New("", 'import { b } from "./b";', "") },
|
||||
{ name: "/b.ts", text: SourceText.New("", ' import { c } from "./c";', "export const b = c;") },
|
||||
{ name: "/c.ts", text: SourceText.New("", "", "export const c = 0;") },
|
||||
{ name: "/d.ts", text: SourceText.New("", "", "export const dd = 0;") },
|
||||
{ name: "/e.ts", text: SourceText.New("", "", "export const ee = 0;") },
|
||||
];
|
||||
|
||||
let program = newProgram(files, ["/d.ts", "/e.ts", "/a.ts"], {});
|
||||
const assertChanges = makeAssertChangesWithCancellationToken(() => program);
|
||||
// No cancellation
|
||||
assertChanges(["/d.js", "/e.js", "/c.js", "/b.js", "/a.js"]);
|
||||
|
||||
// cancel when emitting a.ts
|
||||
program = updateProgramFile(program, "/a.ts", "export function foo() { }");
|
||||
assertChanges(["/a.js"], 0);
|
||||
// Change d.ts and verify previously pending a.ts is emitted as well
|
||||
program = updateProgramFile(program, "/d.ts", "export function bar() { }");
|
||||
assertChanges(["/a.js", "/d.js"]);
|
||||
|
||||
// Cancel when emitting b.js
|
||||
program = updateProgramFile(program, "/b.ts", "export class b { foo() { c + 1; } }");
|
||||
program = updateProgramFile(program, "/d.ts", "export function bar2() { }");
|
||||
assertChanges(["/d.js", "/b.js", "/a.js"], 1);
|
||||
// Change e.ts and verify previously b.js as well as a.js get emitted again since previous change was consumed completely but not d.ts
|
||||
program = updateProgramFile(program, "/e.ts", "export function bar3() { }");
|
||||
assertChanges(["/b.js", "/a.js", "/e.js"]);
|
||||
|
||||
// Cancel in the middle of affected files list after b.js emit
|
||||
program = updateProgramFile(program, "/b.ts", "export class b { foo2() { c + 1; } }");
|
||||
assertChanges(["/b.js", "/a.js"], 1);
|
||||
// Change e.ts and verify previously b.js as well as a.js get emitted again since previous change was consumed completely but not d.ts
|
||||
program = updateProgramFile(program, "/e.ts", "export function bar5() { }");
|
||||
assertChanges(["/b.js", "/a.js", "/e.js"]);
|
||||
});
|
||||
});
|
||||
|
||||
function makeAssertChanges(getProgram: () => Program): (fileNames: ReadonlyArray<string>) => void {
|
||||
const builder = createBuilder({
|
||||
getCanonicalFileName: identity,
|
||||
computeHash: identity
|
||||
});
|
||||
const host: BuilderProgramHost = { useCaseSensitiveFileNames: returnTrue };
|
||||
let builderProgram: EmitAndSemanticDiagnosticsBuilderProgram | undefined;
|
||||
return fileNames => {
|
||||
const program = getProgram();
|
||||
builder.updateProgram(program);
|
||||
builderProgram = createEmitAndSemanticDiagnosticsBuilderProgram(program, host, builderProgram);
|
||||
const outputFileNames: string[] = [];
|
||||
builder.emitChangedFiles(program, fileName => outputFileNames.push(fileName));
|
||||
// tslint:disable-next-line no-empty
|
||||
while (builderProgram.emitNextAffectedFile(fileName => outputFileNames.push(fileName))) {
|
||||
}
|
||||
assert.deepEqual(outputFileNames, fileNames);
|
||||
};
|
||||
}
|
||||
|
||||
function makeAssertChangesWithCancellationToken(getProgram: () => Program): (fileNames: ReadonlyArray<string>, cancelAfterEmitLength?: number) => void {
|
||||
const host: BuilderProgramHost = { useCaseSensitiveFileNames: returnTrue };
|
||||
let builderProgram: EmitAndSemanticDiagnosticsBuilderProgram | undefined;
|
||||
let cancel = false;
|
||||
const cancellationToken: CancellationToken = {
|
||||
isCancellationRequested: () => cancel,
|
||||
throwIfCancellationRequested: () => {
|
||||
if (cancel) {
|
||||
throw new OperationCanceledException();
|
||||
}
|
||||
},
|
||||
};
|
||||
return (fileNames, cancelAfterEmitLength?: number) => {
|
||||
cancel = false;
|
||||
let operationWasCancelled = false;
|
||||
const program = getProgram();
|
||||
builderProgram = createEmitAndSemanticDiagnosticsBuilderProgram(program, host, builderProgram);
|
||||
const outputFileNames: string[] = [];
|
||||
try {
|
||||
// tslint:disable-next-line no-empty
|
||||
do {
|
||||
assert.isFalse(cancel);
|
||||
if (outputFileNames.length === cancelAfterEmitLength) {
|
||||
cancel = true;
|
||||
}
|
||||
} while (builderProgram.emitNextAffectedFile(fileName => outputFileNames.push(fileName), cancellationToken));
|
||||
}
|
||||
catch (e) {
|
||||
assert.isFalse(operationWasCancelled);
|
||||
assert(e instanceof OperationCanceledException, e.toString());
|
||||
operationWasCancelled = true;
|
||||
}
|
||||
assert.equal(cancel, operationWasCancelled);
|
||||
assert.equal(operationWasCancelled, fileNames.length > cancelAfterEmitLength);
|
||||
assert.deepEqual(outputFileNames, fileNames.slice(0, cancelAfterEmitLength));
|
||||
};
|
||||
}
|
||||
|
||||
function updateProgramFile(program: ProgramWithSourceTexts, fileName: string, fileContent: string): ProgramWithSourceTexts {
|
||||
return updateProgram(program, program.getRootFileNames(), program.getCompilerOptions(), files => {
|
||||
updateProgramText(files, fileName, fileContent);
|
||||
|
||||
@@ -273,6 +273,13 @@ let i: I = [#|{ a: 1 }|];
|
||||
const myObj: { member(x: number, y: string): void } = {
|
||||
member: [#|(x, y) => x + y|],
|
||||
}
|
||||
`);
|
||||
|
||||
testExtractConstant("extractConstant_CaseClauseExpression", `
|
||||
switch (1) {
|
||||
case [#|1|]:
|
||||
break;
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
|
||||
@@ -365,6 +365,58 @@ switch (x) {
|
||||
refactor.extractSymbol.Messages.cannotExtractRange.message
|
||||
]);
|
||||
|
||||
testExtractRangeFailed("extractRangeFailed14",
|
||||
`
|
||||
switch(1) {
|
||||
case [#|1:
|
||||
break;|]
|
||||
}
|
||||
`,
|
||||
[
|
||||
refactor.extractSymbol.Messages.cannotExtractRange.message
|
||||
]);
|
||||
|
||||
testExtractRangeFailed("extractRangeFailed15",
|
||||
`
|
||||
switch(1) {
|
||||
case [#|1:
|
||||
break|];
|
||||
}
|
||||
`,
|
||||
[
|
||||
refactor.extractSymbol.Messages.cannotExtractRange.message
|
||||
]);
|
||||
|
||||
// Documentation only - it would be nice if the result were [$|1|]
|
||||
testExtractRangeFailed("extractRangeFailed16",
|
||||
`
|
||||
switch(1) {
|
||||
[#|case 1|]:
|
||||
break;
|
||||
}
|
||||
`,
|
||||
[
|
||||
refactor.extractSymbol.Messages.cannotExtractRange.message
|
||||
]);
|
||||
|
||||
// Documentation only - it would be nice if the result were [$|1|]
|
||||
testExtractRangeFailed("extractRangeFailed17",
|
||||
`
|
||||
switch(1) {
|
||||
[#|case 1:|]
|
||||
break;
|
||||
}
|
||||
`,
|
||||
[
|
||||
refactor.extractSymbol.Messages.cannotExtractRange.message
|
||||
]);
|
||||
|
||||
testExtractRangeFailed("extractRangeFailed18",
|
||||
`[#|{ 1;|] }`,
|
||||
[
|
||||
refactor.extractSymbol.Messages.cannotExtractRange.message
|
||||
]);
|
||||
|
||||
testExtractRangeFailed("extract-method-not-for-token-expression-statement", `[#|a|]`, [refactor.extractSymbol.Messages.cannotExtractIdentifier.message]);
|
||||
});
|
||||
}
|
||||
@@ -121,7 +121,6 @@ namespace ts {
|
||||
const sourceFile = program.getSourceFile(path);
|
||||
const context: RefactorContext = {
|
||||
cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse },
|
||||
newLineCharacter,
|
||||
program,
|
||||
file: sourceFile,
|
||||
startPosition: selectionRange.start,
|
||||
@@ -185,7 +184,6 @@ namespace ts {
|
||||
const sourceFile = program.getSourceFile(f.path);
|
||||
const context: RefactorContext = {
|
||||
cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse },
|
||||
newLineCharacter,
|
||||
program,
|
||||
file: sourceFile,
|
||||
startPosition: selectionRange.start,
|
||||
|
||||
@@ -884,7 +884,6 @@ namespace ts {
|
||||
});
|
||||
});
|
||||
|
||||
import TestSystem = ts.TestFSWithWatch.TestServerHost;
|
||||
type FileOrFolder = ts.TestFSWithWatch.FileOrFolder;
|
||||
import createTestSystem = ts.TestFSWithWatch.createWatchedSystem;
|
||||
import libFile = ts.TestFSWithWatch.libFile;
|
||||
@@ -910,30 +909,21 @@ namespace ts {
|
||||
return JSON.parse(JSON.stringify(filesOrOptions));
|
||||
}
|
||||
|
||||
function createWatchingSystemHost(host: TestSystem) {
|
||||
return ts.createWatchingSystemHost(/*pretty*/ undefined, host);
|
||||
}
|
||||
|
||||
function verifyProgramWithoutConfigFile(watchingSystemHost: WatchingSystemHost, rootFiles: string[], options: CompilerOptions) {
|
||||
const program = createWatchModeWithoutConfigFile(rootFiles, options, watchingSystemHost)();
|
||||
function verifyProgramWithoutConfigFile(system: System, rootFiles: string[], options: CompilerOptions) {
|
||||
const program = createWatchProgram(createWatchCompilerHostOfFilesAndCompilerOptions(rootFiles, options, system)).getCurrentProgram().getProgram();
|
||||
verifyProgramIsUptoDate(program, duplicate(rootFiles), duplicate(options));
|
||||
}
|
||||
|
||||
function getConfigParseResult(watchingSystemHost: WatchingSystemHost, configFileName: string) {
|
||||
return parseConfigFile(configFileName, {}, watchingSystemHost.system, watchingSystemHost.reportDiagnostic, watchingSystemHost.reportWatchDiagnostic);
|
||||
}
|
||||
|
||||
function verifyProgramWithConfigFile(watchingSystemHost: WatchingSystemHost, configFile: string) {
|
||||
const result = getConfigParseResult(watchingSystemHost, configFile);
|
||||
const program = createWatchModeWithConfigFile(result, {}, watchingSystemHost)();
|
||||
const { fileNames, options } = getConfigParseResult(watchingSystemHost, configFile);
|
||||
function verifyProgramWithConfigFile(system: System, configFileName: string) {
|
||||
const program = createWatchProgram(createWatchCompilerHostOfConfigFile(configFileName, {}, system)).getCurrentProgram().getProgram();
|
||||
const { fileNames, options } = parseConfigFileWithSystem(configFileName, {}, system, notImplemented);
|
||||
verifyProgramIsUptoDate(program, fileNames, options);
|
||||
}
|
||||
|
||||
function verifyProgram(files: FileOrFolder[], rootFiles: string[], options: CompilerOptions, configFile: string) {
|
||||
const watchingSystemHost = createWatchingSystemHost(createTestSystem(files));
|
||||
verifyProgramWithoutConfigFile(watchingSystemHost, rootFiles, options);
|
||||
verifyProgramWithConfigFile(watchingSystemHost, configFile);
|
||||
const system = createTestSystem(files);
|
||||
verifyProgramWithoutConfigFile(system, rootFiles, options);
|
||||
verifyProgramWithConfigFile(system, configFile);
|
||||
}
|
||||
|
||||
it("has empty options", () => {
|
||||
@@ -1044,11 +1034,9 @@ namespace ts {
|
||||
};
|
||||
const configFile: FileOrFolder = {
|
||||
path: "/src/tsconfig.json",
|
||||
content: JSON.stringify({ compilerOptions, include: ["packages/**/ *.ts"] })
|
||||
content: JSON.stringify({ compilerOptions, include: ["packages/**/*.ts"] })
|
||||
};
|
||||
|
||||
const watchingSystemHost = createWatchingSystemHost(createTestSystem([app, module1, module2, module3, libFile, configFile]));
|
||||
verifyProgramWithConfigFile(watchingSystemHost, configFile.path);
|
||||
verifyProgramWithConfigFile(createTestSystem([app, module1, module2, module3, libFile, configFile]), configFile.path);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ const expect: typeof _chai.expect = _chai.expect;
|
||||
|
||||
namespace ts.server {
|
||||
let lastWrittenToHost: string;
|
||||
const noopFileWatcher: FileWatcher = { close: noop };
|
||||
const mockHost: ServerHost = {
|
||||
args: [],
|
||||
newLine: "\n",
|
||||
@@ -26,6 +27,8 @@ namespace ts.server {
|
||||
setImmediate: () => 0,
|
||||
clearImmediate: noop,
|
||||
createHash: Harness.mockHash,
|
||||
watchFile: () => noopFileWatcher,
|
||||
watchDirectory: () => noopFileWatcher
|
||||
};
|
||||
|
||||
class TestSession extends Session {
|
||||
|
||||
@@ -22,24 +22,16 @@ namespace ts.tscWatch {
|
||||
checkFileNames(`Program rootFileNames`, program.getRootFileNames(), expectedFiles);
|
||||
}
|
||||
|
||||
function createWatchingSystemHost(system: WatchedSystem) {
|
||||
return ts.createWatchingSystemHost(/*pretty*/ undefined, system);
|
||||
function createWatchOfConfigFile(configFileName: string, host: WatchedSystem, maxNumberOfFilesToIterateForInvalidation?: number) {
|
||||
const compilerHost = ts.createWatchCompilerHostOfConfigFile(configFileName, {}, host);
|
||||
compilerHost.maxNumberOfFilesToIterateForInvalidation = maxNumberOfFilesToIterateForInvalidation;
|
||||
const watch = createWatchProgram(compilerHost);
|
||||
return () => watch.getCurrentProgram().getProgram();
|
||||
}
|
||||
|
||||
function parseConfigFile(configFileName: string, watchingSystemHost: WatchingSystemHost) {
|
||||
return ts.parseConfigFile(configFileName, {}, watchingSystemHost.system, watchingSystemHost.reportDiagnostic, watchingSystemHost.reportWatchDiagnostic);
|
||||
}
|
||||
|
||||
function createWatchModeWithConfigFile(configFilePath: string, host: WatchedSystem, maxNumberOfFilesToIterateForInvalidation?: number) {
|
||||
const watchingSystemHost = createWatchingSystemHost(host);
|
||||
watchingSystemHost.maxNumberOfFilesToIterateForInvalidation = maxNumberOfFilesToIterateForInvalidation;
|
||||
const configFileResult = parseConfigFile(configFilePath, watchingSystemHost);
|
||||
return ts.createWatchModeWithConfigFile(configFileResult, {}, watchingSystemHost);
|
||||
}
|
||||
|
||||
function createWatchModeWithoutConfigFile(fileNames: string[], host: WatchedSystem, options: CompilerOptions = {}) {
|
||||
const watchingSystemHost = createWatchingSystemHost(host);
|
||||
return ts.createWatchModeWithoutConfigFile(fileNames, options, watchingSystemHost);
|
||||
function createWatchOfFilesAndCompilerOptions(rootFiles: string[], host: WatchedSystem, options: CompilerOptions = {}) {
|
||||
const watch = createWatchProgram(createWatchCompilerHostOfFilesAndCompilerOptions(rootFiles, options, host));
|
||||
return () => watch.getCurrentProgram().getProgram();
|
||||
}
|
||||
|
||||
function getEmittedLineForMultiFileOutput(file: FileOrFolder, host: WatchedSystem) {
|
||||
@@ -218,7 +210,7 @@ namespace ts.tscWatch {
|
||||
content: `export let x: number`
|
||||
};
|
||||
const host = createWatchedSystem([appFile, moduleFile, libFile]);
|
||||
const watch = createWatchModeWithoutConfigFile([appFile.path], host);
|
||||
const watch = createWatchOfFilesAndCompilerOptions([appFile.path], host);
|
||||
|
||||
checkProgramActualFiles(watch(), [appFile.path, libFile.path, moduleFile.path]);
|
||||
|
||||
@@ -243,7 +235,7 @@ namespace ts.tscWatch {
|
||||
|
||||
const host = createWatchedSystem([f1, config], { useCaseSensitiveFileNames: false });
|
||||
const upperCaseConfigFilePath = combinePaths(getDirectoryPath(config.path).toUpperCase(), getBaseFileName(config.path));
|
||||
const watch = createWatchModeWithConfigFile(upperCaseConfigFilePath, host);
|
||||
const watch = createWatchOfConfigFile(upperCaseConfigFilePath, host);
|
||||
checkProgramActualFiles(watch(), [combinePaths(getDirectoryPath(upperCaseConfigFilePath), getBaseFileName(f1.path))]);
|
||||
});
|
||||
|
||||
@@ -272,14 +264,10 @@ namespace ts.tscWatch {
|
||||
};
|
||||
|
||||
const host = createWatchedSystem([configFile, libFile, file1, file2, file3]);
|
||||
const watchingSystemHost = createWatchingSystemHost(host);
|
||||
const configFileResult = parseConfigFile(configFile.path, watchingSystemHost);
|
||||
assert.equal(configFileResult.errors.length, 0, `expect no errors in config file, got ${JSON.stringify(configFileResult.errors)}`);
|
||||
const watch = createWatchProgram(createWatchCompilerHostOfConfigFile(configFile.path, {}, host, /*createProgram*/ undefined, notImplemented));
|
||||
|
||||
const watch = ts.createWatchModeWithConfigFile(configFileResult, {}, watchingSystemHost);
|
||||
|
||||
checkProgramActualFiles(watch(), [file1.path, libFile.path, file2.path]);
|
||||
checkProgramRootFiles(watch(), [file1.path, file2.path]);
|
||||
checkProgramActualFiles(watch.getCurrentProgram().getProgram(), [file1.path, libFile.path, file2.path]);
|
||||
checkProgramRootFiles(watch.getCurrentProgram().getProgram(), [file1.path, file2.path]);
|
||||
checkWatchedFiles(host, [configFile.path, file1.path, file2.path, libFile.path]);
|
||||
const configDir = getDirectoryPath(configFile.path);
|
||||
checkWatchedDirectories(host, [configDir, combinePaths(configDir, projectSystem.nodeModulesAtTypes)], /*recursive*/ true);
|
||||
@@ -295,7 +283,7 @@ namespace ts.tscWatch {
|
||||
content: `{}`
|
||||
};
|
||||
const host = createWatchedSystem([commonFile1, libFile, configFile]);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
const configDir = getDirectoryPath(configFile.path);
|
||||
checkWatchedDirectories(host, [configDir, combinePaths(configDir, projectSystem.nodeModulesAtTypes)], /*recursive*/ true);
|
||||
|
||||
@@ -319,7 +307,7 @@ namespace ts.tscWatch {
|
||||
}`
|
||||
};
|
||||
const host = createWatchedSystem([commonFile1, commonFile2, configFile]);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
|
||||
const commonFile3 = "/a/b/commonFile3.ts";
|
||||
checkProgramRootFiles(watch(), [commonFile1.path, commonFile3]);
|
||||
@@ -332,7 +320,7 @@ namespace ts.tscWatch {
|
||||
content: `{}`
|
||||
};
|
||||
const host = createWatchedSystem([commonFile1, commonFile2, configFile]);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
checkProgramRootFiles(watch(), [commonFile1.path, commonFile2.path]);
|
||||
|
||||
// delete commonFile2
|
||||
@@ -354,7 +342,7 @@ namespace ts.tscWatch {
|
||||
let x = y`
|
||||
};
|
||||
const host = createWatchedSystem([file1, libFile]);
|
||||
const watch = createWatchModeWithoutConfigFile([file1.path], host);
|
||||
const watch = createWatchOfFilesAndCompilerOptions([file1.path], host);
|
||||
|
||||
checkProgramRootFiles(watch(), [file1.path]);
|
||||
checkProgramActualFiles(watch(), [file1.path, libFile.path]);
|
||||
@@ -380,7 +368,7 @@ namespace ts.tscWatch {
|
||||
};
|
||||
const files = [commonFile1, commonFile2, configFile];
|
||||
const host = createWatchedSystem(files);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
|
||||
checkProgramRootFiles(watch(), [commonFile1.path, commonFile2.path]);
|
||||
configFile.content = `{
|
||||
@@ -407,7 +395,7 @@ namespace ts.tscWatch {
|
||||
};
|
||||
|
||||
const host = createWatchedSystem([commonFile1, commonFile2, excludedFile1, configFile]);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
checkProgramRootFiles(watch(), [commonFile1.path, commonFile2.path]);
|
||||
});
|
||||
|
||||
@@ -435,7 +423,7 @@ namespace ts.tscWatch {
|
||||
};
|
||||
const files = [file1, nodeModuleFile, classicModuleFile, configFile];
|
||||
const host = createWatchedSystem(files);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
checkProgramRootFiles(watch(), [file1.path]);
|
||||
checkProgramActualFiles(watch(), [file1.path, nodeModuleFile.path]);
|
||||
|
||||
@@ -463,7 +451,7 @@ namespace ts.tscWatch {
|
||||
}`
|
||||
};
|
||||
const host = createWatchedSystem([commonFile1, commonFile2, libFile, configFile]);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
checkProgramRootFiles(watch(), [commonFile1.path, commonFile2.path]);
|
||||
});
|
||||
|
||||
@@ -481,7 +469,7 @@ namespace ts.tscWatch {
|
||||
content: `export let y = 1;`
|
||||
};
|
||||
const host = createWatchedSystem([file1, file2, file3]);
|
||||
const watch = createWatchModeWithoutConfigFile([file1.path], host);
|
||||
const watch = createWatchOfFilesAndCompilerOptions([file1.path], host);
|
||||
checkProgramRootFiles(watch(), [file1.path]);
|
||||
checkProgramActualFiles(watch(), [file1.path, file2.path]);
|
||||
|
||||
@@ -510,7 +498,7 @@ namespace ts.tscWatch {
|
||||
content: `export let y = 1;`
|
||||
};
|
||||
const host = createWatchedSystem([file1, file2, file3]);
|
||||
const watch = createWatchModeWithoutConfigFile([file1.path], host);
|
||||
const watch = createWatchOfFilesAndCompilerOptions([file1.path], host);
|
||||
checkProgramActualFiles(watch(), [file1.path, file2.path, file3.path]);
|
||||
|
||||
host.reloadFS([file1, file3]);
|
||||
@@ -533,7 +521,7 @@ namespace ts.tscWatch {
|
||||
content: `export let y = 1;`
|
||||
};
|
||||
const host = createWatchedSystem([file1, file2, file3]);
|
||||
const watch = createWatchModeWithoutConfigFile([file1.path, file3.path], host);
|
||||
const watch = createWatchOfFilesAndCompilerOptions([file1.path, file3.path], host);
|
||||
checkProgramActualFiles(watch(), [file1.path, file2.path, file3.path]);
|
||||
|
||||
host.reloadFS([file1, file3]);
|
||||
@@ -561,7 +549,7 @@ namespace ts.tscWatch {
|
||||
};
|
||||
|
||||
const host = createWatchedSystem([file1, file2, file3, configFile]);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
|
||||
checkProgramRootFiles(watch(), [file2.path, file3.path]);
|
||||
checkProgramActualFiles(watch(), [file1.path, file2.path, file3.path]);
|
||||
@@ -583,10 +571,10 @@ namespace ts.tscWatch {
|
||||
content: "export let y = 1;"
|
||||
};
|
||||
const host = createWatchedSystem([file1, file2, file3]);
|
||||
const watch = createWatchModeWithoutConfigFile([file2.path, file3.path], host);
|
||||
const watch = createWatchOfFilesAndCompilerOptions([file2.path, file3.path], host);
|
||||
checkProgramActualFiles(watch(), [file2.path, file3.path]);
|
||||
|
||||
const watch2 = createWatchModeWithoutConfigFile([file1.path], host);
|
||||
const watch2 = createWatchOfFilesAndCompilerOptions([file1.path], host);
|
||||
checkProgramActualFiles(watch2(), [file1.path, file2.path, file3.path]);
|
||||
|
||||
// Previous program shouldnt be updated
|
||||
@@ -609,7 +597,7 @@ namespace ts.tscWatch {
|
||||
};
|
||||
|
||||
const host = createWatchedSystem([file1, configFile]);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
checkProgramActualFiles(watch(), [file1.path]);
|
||||
|
||||
host.reloadFS([file1, file2, configFile]);
|
||||
@@ -634,7 +622,7 @@ namespace ts.tscWatch {
|
||||
};
|
||||
|
||||
const host = createWatchedSystem([file1, file2, configFile]);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
|
||||
checkProgramActualFiles(watch(), [file1.path]);
|
||||
|
||||
@@ -664,7 +652,7 @@ namespace ts.tscWatch {
|
||||
};
|
||||
|
||||
const host = createWatchedSystem([file1, file2, configFile]);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
checkProgramActualFiles(watch(), [file1.path, file2.path]);
|
||||
|
||||
const modifiedConfigFile = {
|
||||
@@ -692,7 +680,7 @@ namespace ts.tscWatch {
|
||||
content: JSON.stringify({ compilerOptions: {} })
|
||||
};
|
||||
const host = createWatchedSystem([file1, file2, libFile, config]);
|
||||
const watch = createWatchModeWithConfigFile(config.path, host);
|
||||
const watch = createWatchOfConfigFile(config.path, host);
|
||||
|
||||
checkProgramActualFiles(watch(), [file1.path, file2.path, libFile.path]);
|
||||
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
|
||||
@@ -716,7 +704,7 @@ namespace ts.tscWatch {
|
||||
content: "{"
|
||||
};
|
||||
const host = createWatchedSystem([file1, corruptedConfig]);
|
||||
const watch = createWatchModeWithConfigFile(corruptedConfig.path, host);
|
||||
const watch = createWatchOfConfigFile(corruptedConfig.path, host);
|
||||
|
||||
checkProgramActualFiles(watch(), [file1.path]);
|
||||
});
|
||||
@@ -766,7 +754,7 @@ namespace ts.tscWatch {
|
||||
})
|
||||
};
|
||||
const host = createWatchedSystem([libES5, libES2015Promise, app, config1], { executingFilePath: "/compiler/tsc.js" });
|
||||
const watch = createWatchModeWithConfigFile(config1.path, host);
|
||||
const watch = createWatchOfConfigFile(config1.path, host);
|
||||
|
||||
checkProgramActualFiles(watch(), [libES5.path, app.path]);
|
||||
|
||||
@@ -791,7 +779,7 @@ namespace ts.tscWatch {
|
||||
})
|
||||
};
|
||||
const host = createWatchedSystem([f, config]);
|
||||
const watch = createWatchModeWithConfigFile(config.path, host);
|
||||
const watch = createWatchOfConfigFile(config.path, host);
|
||||
checkProgramActualFiles(watch(), [f.path]);
|
||||
});
|
||||
|
||||
@@ -805,7 +793,7 @@ namespace ts.tscWatch {
|
||||
content: 'import * as T from "./moduleFile"; T.bar();'
|
||||
};
|
||||
const host = createWatchedSystem([moduleFile, file1, libFile]);
|
||||
const watch = createWatchModeWithoutConfigFile([file1.path], host);
|
||||
const watch = createWatchOfFilesAndCompilerOptions([file1.path], host);
|
||||
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
|
||||
|
||||
const moduleFileOldPath = moduleFile.path;
|
||||
@@ -837,7 +825,7 @@ namespace ts.tscWatch {
|
||||
content: `{}`
|
||||
};
|
||||
const host = createWatchedSystem([moduleFile, file1, configFile, libFile]);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
|
||||
|
||||
const moduleFileOldPath = moduleFile.path;
|
||||
@@ -872,7 +860,7 @@ namespace ts.tscWatch {
|
||||
path: "/a/c"
|
||||
};
|
||||
const host = createWatchedSystem([f1, config, node, cwd], { currentDirectory: cwd.path });
|
||||
const watch = createWatchModeWithConfigFile(config.path, host);
|
||||
const watch = createWatchOfConfigFile(config.path, host);
|
||||
|
||||
checkProgramActualFiles(watch(), [f1.path, node.path]);
|
||||
});
|
||||
@@ -887,7 +875,7 @@ namespace ts.tscWatch {
|
||||
content: 'import * as T from "./moduleFile"; T.bar();'
|
||||
};
|
||||
const host = createWatchedSystem([file1, libFile]);
|
||||
const watch = createWatchModeWithoutConfigFile([file1.path], host);
|
||||
const watch = createWatchOfFilesAndCompilerOptions([file1.path], host);
|
||||
|
||||
checkOutputErrors(host, [
|
||||
getDiagnosticModuleNotFoundOfFile(watch(), file1, "./moduleFile")
|
||||
@@ -914,7 +902,7 @@ namespace ts.tscWatch {
|
||||
};
|
||||
|
||||
const host = createWatchedSystem([file, configFile, libFile]);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
checkOutputErrors(host, [
|
||||
getUnknownCompilerOption(watch(), configFile, "foo"),
|
||||
getUnknownCompilerOption(watch(), configFile, "allowJS")
|
||||
@@ -934,7 +922,7 @@ namespace ts.tscWatch {
|
||||
};
|
||||
|
||||
const host = createWatchedSystem([file, configFile, libFile]);
|
||||
createWatchModeWithConfigFile(configFile.path, host);
|
||||
createWatchOfConfigFile(configFile.path, host);
|
||||
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
|
||||
});
|
||||
|
||||
@@ -951,7 +939,7 @@ namespace ts.tscWatch {
|
||||
};
|
||||
|
||||
const host = createWatchedSystem([file, configFile, libFile]);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
|
||||
|
||||
configFile.content = `{
|
||||
@@ -987,7 +975,7 @@ namespace ts.tscWatch {
|
||||
};
|
||||
|
||||
const host = createWatchedSystem([file1, configFile, libFile]);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
|
||||
checkProgramActualFiles(watch(), [libFile.path]);
|
||||
});
|
||||
@@ -1013,7 +1001,7 @@ namespace ts.tscWatch {
|
||||
content: `export const x: number`
|
||||
};
|
||||
const host = createWatchedSystem([f, config, t1, t2], { currentDirectory: getDirectoryPath(f.path) });
|
||||
const watch = createWatchModeWithConfigFile(config.path, host);
|
||||
const watch = createWatchOfConfigFile(config.path, host);
|
||||
|
||||
checkProgramActualFiles(watch(), [t1.path, t2.path]);
|
||||
});
|
||||
@@ -1024,7 +1012,7 @@ namespace ts.tscWatch {
|
||||
content: "let x = 1"
|
||||
};
|
||||
const host = createWatchedSystem([f, libFile]);
|
||||
const watch = createWatchModeWithoutConfigFile([f.path], host, { allowNonTsExtensions: true });
|
||||
const watch = createWatchOfFilesAndCompilerOptions([f.path], host, { allowNonTsExtensions: true });
|
||||
checkProgramActualFiles(watch(), [f.path, libFile.path]);
|
||||
});
|
||||
|
||||
@@ -1052,7 +1040,7 @@ namespace ts.tscWatch {
|
||||
|
||||
const files = [file, libFile, configFile];
|
||||
const host = createWatchedSystem(files);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
const errors = () => [
|
||||
getDiagnosticOfFile(watch().getCompilerOptions().configFile, configFile.content.indexOf('"allowJs"'), '"allowJs"'.length, Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration"),
|
||||
getDiagnosticOfFile(watch().getCompilerOptions().configFile, configFile.content.indexOf('"declaration"'), '"declaration"'.length, Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration")
|
||||
@@ -1089,7 +1077,7 @@ namespace ts.tscWatch {
|
||||
})
|
||||
};
|
||||
const host = createWatchedSystem([file1, file2, libFile, tsconfig], { currentDirectory: proj });
|
||||
const watch = createWatchModeWithConfigFile(tsconfig.path, host, /*maxNumberOfFilesToIterateForInvalidation*/1);
|
||||
const watch = createWatchOfConfigFile(tsconfig.path, host, /*maxNumberOfFilesToIterateForInvalidation*/1);
|
||||
checkProgramActualFiles(watch(), [file1.path, file2.path, libFile.path]);
|
||||
|
||||
assert.isTrue(host.fileExists("build/file1.js"));
|
||||
@@ -1138,7 +1126,7 @@ namespace ts.tscWatch {
|
||||
|
||||
const files = [f1, f2, config, libFile];
|
||||
host.reloadFS(files);
|
||||
createWatchModeWithConfigFile(config.path, host);
|
||||
createWatchOfConfigFile(config.path, host);
|
||||
|
||||
const allEmittedLines = getEmittedLines(files);
|
||||
checkOutputContains(host, allEmittedLines);
|
||||
@@ -1200,7 +1188,7 @@ namespace ts.tscWatch {
|
||||
mapOfFilesWritten.set(p, count ? count + 1 : 1);
|
||||
return originalWriteFile(p, content);
|
||||
};
|
||||
createWatchModeWithConfigFile(configFile.path, host);
|
||||
createWatchOfConfigFile(configFile.path, host);
|
||||
if (useOutFile) {
|
||||
// Only out file
|
||||
assert.equal(mapOfFilesWritten.size, 1);
|
||||
@@ -1284,7 +1272,7 @@ namespace ts.tscWatch {
|
||||
host.reloadFS(firstReloadFileList ? getFiles(firstReloadFileList) : files);
|
||||
|
||||
// Initial compile
|
||||
createWatchModeWithConfigFile(configFile.path, host);
|
||||
createWatchOfConfigFile(configFile.path, host);
|
||||
if (firstCompilationEmitFiles) {
|
||||
checkAffectedLines(host, getFiles(firstCompilationEmitFiles), allEmittedFiles);
|
||||
}
|
||||
@@ -1595,11 +1583,11 @@ namespace ts.tscWatch {
|
||||
|
||||
// Initial compile
|
||||
if (configFile) {
|
||||
createWatchModeWithConfigFile(configFile.path, host);
|
||||
createWatchOfConfigFile(configFile.path, host);
|
||||
}
|
||||
else {
|
||||
// First file as the root
|
||||
createWatchModeWithoutConfigFile([files[0].path], host, { listEmittedFiles: true });
|
||||
createWatchOfFilesAndCompilerOptions([files[0].path], host, { listEmittedFiles: true });
|
||||
}
|
||||
checkOutputContains(host, allEmittedFiles);
|
||||
|
||||
@@ -1719,7 +1707,7 @@ namespace ts.tscWatch {
|
||||
|
||||
const files = [root, imported, libFile];
|
||||
const host = createWatchedSystem(files);
|
||||
const watch = createWatchModeWithoutConfigFile([root.path], host, { module: ModuleKind.AMD });
|
||||
const watch = createWatchOfFilesAndCompilerOptions([root.path], host, { module: ModuleKind.AMD });
|
||||
|
||||
const f1IsNotModule = getDiagnosticOfFileFromProgram(watch(), root.path, root.content.indexOf('"f1"'), '"f1"'.length, Diagnostics.File_0_is_not_a_module, imported.path);
|
||||
const cannotFindFoo = getDiagnosticOfFileFromProgram(watch(), imported.path, imported.content.indexOf("foo"), "foo".length, Diagnostics.Cannot_find_name_0, "foo");
|
||||
@@ -1820,7 +1808,7 @@ namespace ts.tscWatch {
|
||||
return originalFileExists.call(host, fileName);
|
||||
};
|
||||
|
||||
const watch = createWatchModeWithoutConfigFile([root.path], host, { module: ModuleKind.AMD });
|
||||
const watch = createWatchOfFilesAndCompilerOptions([root.path], host, { module: ModuleKind.AMD });
|
||||
|
||||
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called");
|
||||
checkOutputErrors(host, [
|
||||
@@ -1862,7 +1850,7 @@ namespace ts.tscWatch {
|
||||
return originalFileExists.call(host, fileName);
|
||||
};
|
||||
|
||||
const watch = createWatchModeWithoutConfigFile([root.path], host, { module: ModuleKind.AMD });
|
||||
const watch = createWatchOfFilesAndCompilerOptions([root.path], host, { module: ModuleKind.AMD });
|
||||
|
||||
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called");
|
||||
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
|
||||
@@ -1911,7 +1899,7 @@ declare module "fs" {
|
||||
const filesWithNodeType = files.concat(packageJson, nodeType);
|
||||
const host = createWatchedSystem(files, { currentDirectory: "/a/b" });
|
||||
|
||||
const watch = createWatchModeWithoutConfigFile([root.path], host, { });
|
||||
const watch = createWatchOfFilesAndCompilerOptions([root.path], host, { });
|
||||
|
||||
checkOutputErrors(host, [
|
||||
getDiagnosticModuleNotFoundOfFile(watch(), root, "fs")
|
||||
@@ -1953,7 +1941,7 @@ declare module "fs" {
|
||||
const files = [root, file, libFile];
|
||||
const host = createWatchedSystem(files, { currentDirectory: "/a/b" });
|
||||
|
||||
const watch = createWatchModeWithoutConfigFile([root.path, file.path], host, {});
|
||||
const watch = createWatchOfFilesAndCompilerOptions([root.path, file.path], host, {});
|
||||
|
||||
checkOutputErrors(host, [
|
||||
getDiagnosticModuleNotFoundOfFile(watch(), root, "fs")
|
||||
@@ -1995,7 +1983,7 @@ declare module "fs" {
|
||||
const outDirFolder = "/a/b/projects/myProject/dist/";
|
||||
const programFiles = [file1, file2, module1, libFile];
|
||||
const host = createWatchedSystem(programFiles.concat(configFile), { currentDirectory: "/a/b/projects/myProject/" });
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
checkProgramActualFiles(watch(), programFiles.map(f => f.path));
|
||||
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
|
||||
const expectedFiles: ExpectedFile[] = [
|
||||
@@ -2072,7 +2060,7 @@ declare module "fs" {
|
||||
};
|
||||
const files = [configFile, file1, file2, libFile];
|
||||
const host = createWatchedSystem(files);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
|
||||
checkProgramActualFiles(watch(), mapDefined(files, f => f === configFile ? undefined : f.path));
|
||||
file1.content = "var zz30 = 100;";
|
||||
@@ -2094,7 +2082,7 @@ declare module "fs" {
|
||||
};
|
||||
const host = createWatchedSystem([file]);
|
||||
|
||||
createWatchModeWithoutConfigFile([file.path], host);
|
||||
createWatchOfFilesAndCompilerOptions([file.path], host);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
host.checkScreenClears(1);
|
||||
@@ -2106,7 +2094,7 @@ declare module "fs" {
|
||||
content: ""
|
||||
};
|
||||
const host = createWatchedSystem([file]);
|
||||
createWatchModeWithoutConfigFile([file.path], host);
|
||||
createWatchOfFilesAndCompilerOptions([file.path], host);
|
||||
|
||||
const modifiedFile = {
|
||||
...file,
|
||||
|
||||
@@ -2821,6 +2821,70 @@ namespace ts.projectSystem {
|
||||
checkWatchedDirectories(host, watchedRecursiveDirectories, /*recursive*/ true);
|
||||
});
|
||||
|
||||
it("Properly handle Windows-style outDir", () => {
|
||||
const configFile: FileOrFolder = {
|
||||
path: "C:\\a\\tsconfig.json",
|
||||
content: JSON.stringify({
|
||||
compilerOptions: {
|
||||
outDir: `C:\\a\\b`
|
||||
},
|
||||
include: ["*.ts"]
|
||||
})
|
||||
};
|
||||
const file1: FileOrFolder = {
|
||||
path: "C:\\a\\f1.ts",
|
||||
content: "let x = 1;"
|
||||
};
|
||||
|
||||
const host = createServerHost([file1, configFile], { useWindowsStylePaths: true });
|
||||
const projectService = createProjectService(host);
|
||||
|
||||
projectService.openClientFile(file1.path);
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
const project = configuredProjectAt(projectService, 0);
|
||||
checkProjectActualFiles(project, [normalizePath(file1.path), normalizePath(configFile.path)]);
|
||||
const options = project.getCompilerOptions();
|
||||
assert.equal(options.outDir, "C:/a/b", "");
|
||||
});
|
||||
|
||||
it("dynamic file without external project", () => {
|
||||
const file: FileOrFolder = {
|
||||
path: "^walkThroughSnippet:/Users/UserName/projects/someProject/out/someFile#1.js",
|
||||
content: "var x = 10;"
|
||||
};
|
||||
const host = createServerHost([libFile], { useCaseSensitiveFileNames: true });
|
||||
const projectService = createProjectService(host);
|
||||
projectService.setCompilerOptionsForInferredProjects({
|
||||
module: ModuleKind.CommonJS,
|
||||
allowJs: true,
|
||||
allowSyntheticDefaultImports: true,
|
||||
allowNonTsExtensions: true
|
||||
});
|
||||
projectService.openClientFile(file.path, "var x = 10;");
|
||||
|
||||
projectService.checkNumberOfProjects({ inferredProjects: 1 });
|
||||
const project = projectService.inferredProjects[0];
|
||||
checkProjectRootFiles(project, [file.path]);
|
||||
checkProjectActualFiles(project, [file.path, libFile.path]);
|
||||
|
||||
assert.strictEqual(projectService.getDefaultProjectForFile(server.toNormalizedPath(file.path), /*ensureProject*/ true), project);
|
||||
const indexOfX = file.content.indexOf("x");
|
||||
assert.deepEqual(project.getLanguageService(/*ensureSynchronized*/ true).getQuickInfoAtPosition(file.path, indexOfX), {
|
||||
kind: ScriptElementKind.variableElement,
|
||||
kindModifiers: "",
|
||||
textSpan: { start: indexOfX, length: 1 },
|
||||
displayParts: [
|
||||
{ text: "var", kind: "keyword" },
|
||||
{ text: " ", kind: "space" },
|
||||
{ text: "x", kind: "localName" },
|
||||
{ text: ":", kind: "punctuation" },
|
||||
{ text: " ", kind: "space" },
|
||||
{ text: "number", kind: "keyword" }
|
||||
],
|
||||
documentation: [],
|
||||
tags: []
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsserverProjectSystem Proper errors", () => {
|
||||
@@ -3485,6 +3549,38 @@ namespace ts.projectSystem {
|
||||
it("works when project root is used with case-insensitive system", () => {
|
||||
verifyOpenFileWorks(/*useCaseSensitiveFileNames*/ false);
|
||||
});
|
||||
|
||||
it("uses existing project even if project refresh is pending", () => {
|
||||
const projectFolder = "/user/someuser/projects/myproject";
|
||||
const aFile: FileOrFolder = {
|
||||
path: `${projectFolder}/src/a.ts`,
|
||||
content: "export const x = 0;"
|
||||
};
|
||||
const configFile: FileOrFolder = {
|
||||
path: `${projectFolder}/tsconfig.json`,
|
||||
content: "{}"
|
||||
};
|
||||
const files = [aFile, configFile, libFile];
|
||||
const host = createServerHost(files);
|
||||
const service = createProjectService(host);
|
||||
service.openClientFile(aFile.path, /*fileContent*/ undefined, ScriptKind.TS, projectFolder);
|
||||
verifyProject();
|
||||
|
||||
const bFile: FileOrFolder = {
|
||||
path: `${projectFolder}/src/b.ts`,
|
||||
content: `export {}; declare module "./a" { export const y: number; }`
|
||||
};
|
||||
files.push(bFile);
|
||||
host.reloadFS(files);
|
||||
service.openClientFile(bFile.path, /*fileContent*/ undefined, ScriptKind.TS, projectFolder);
|
||||
verifyProject();
|
||||
|
||||
function verifyProject() {
|
||||
assert.isDefined(service.configuredProjects.get(configFile.path));
|
||||
const project = service.configuredProjects.get(configFile.path);
|
||||
checkProjectActualFiles(project, files.map(f => f.path));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsserverProjectSystem Language service", () => {
|
||||
@@ -4143,6 +4239,32 @@ namespace ts.projectSystem {
|
||||
// Since no file from the configured project is open, it would be closed immediately
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 0, inferredProjects: 1 });
|
||||
});
|
||||
|
||||
it("should tolerate invalid include files that start in subDirectory", () => {
|
||||
const projectFolder = "/user/username/projects/myproject";
|
||||
const f = {
|
||||
path: `${projectFolder}/src/server/index.ts`,
|
||||
content: "let x = 1"
|
||||
};
|
||||
const config = {
|
||||
path: `${projectFolder}/src/server/tsconfig.json`,
|
||||
content: JSON.stringify({
|
||||
compiler: {
|
||||
module: "commonjs",
|
||||
outDir: "../../build"
|
||||
},
|
||||
include: [
|
||||
"../src/**/*.ts"
|
||||
]
|
||||
})
|
||||
};
|
||||
const host = createServerHost([f, config, libFile], { useCaseSensitiveFileNames: true });
|
||||
const projectService = createProjectService(host);
|
||||
|
||||
projectService.openClientFile(f.path);
|
||||
// Since no file from the configured project is open, it would be closed immediately
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 0, inferredProjects: 1 });
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsserverProjectSystem reload", () => {
|
||||
@@ -6559,4 +6681,118 @@ namespace ts.projectSystem {
|
||||
checkProjectActualFiles(project, [file.path]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsserverProjectSystem with symLinks", () => {
|
||||
it("rename in common file renames all project", () => {
|
||||
const projects = "/users/username/projects";
|
||||
const folderA = `${projects}/a`;
|
||||
const aFile: FileOrFolder = {
|
||||
path: `${folderA}/a.ts`,
|
||||
content: `import {C} from "./c/fc"; console.log(C)`
|
||||
};
|
||||
const aTsconfig: FileOrFolder = {
|
||||
path: `${folderA}/tsconfig.json`,
|
||||
content: JSON.stringify({ compilerOptions: { module: "commonjs" } })
|
||||
};
|
||||
const aC: FileOrFolder = {
|
||||
path: `${folderA}/c`,
|
||||
symLink: "../c"
|
||||
};
|
||||
const aFc = `${folderA}/c/fc.ts`;
|
||||
|
||||
const folderB = `${projects}/b`;
|
||||
const bFile: FileOrFolder = {
|
||||
path: `${folderB}/b.ts`,
|
||||
content: `import {C} from "./c/fc"; console.log(C)`
|
||||
};
|
||||
const bTsconfig: FileOrFolder = {
|
||||
path: `${folderB}/tsconfig.json`,
|
||||
content: JSON.stringify({ compilerOptions: { module: "commonjs" } })
|
||||
};
|
||||
const bC: FileOrFolder = {
|
||||
path: `${folderB}/c`,
|
||||
symLink: "../c"
|
||||
};
|
||||
const bFc = `${folderB}/c/fc.ts`;
|
||||
|
||||
const folderC = `${projects}/c`;
|
||||
const cFile: FileOrFolder = {
|
||||
path: `${folderC}/fc.ts`,
|
||||
content: `export const C = 8`
|
||||
};
|
||||
|
||||
const files = [cFile, libFile, aFile, aTsconfig, aC, bFile, bTsconfig, bC];
|
||||
const host = createServerHost(files);
|
||||
const session = createSession(host);
|
||||
const projectService = session.getProjectService();
|
||||
debugger;
|
||||
session.executeCommandSeq<protocol.OpenRequest>({
|
||||
command: protocol.CommandTypes.Open,
|
||||
arguments: {
|
||||
file: aFile.path,
|
||||
projectRootPath: folderA
|
||||
}
|
||||
});
|
||||
session.executeCommandSeq<protocol.OpenRequest>({
|
||||
command: protocol.CommandTypes.Open,
|
||||
arguments: {
|
||||
file: bFile.path,
|
||||
projectRootPath: folderB
|
||||
}
|
||||
});
|
||||
|
||||
session.executeCommandSeq<protocol.OpenRequest>({
|
||||
command: protocol.CommandTypes.Open,
|
||||
arguments: {
|
||||
file: aFc,
|
||||
projectRootPath: folderA
|
||||
}
|
||||
});
|
||||
session.executeCommandSeq<protocol.OpenRequest>({
|
||||
command: protocol.CommandTypes.Open,
|
||||
arguments: {
|
||||
file: bFc,
|
||||
projectRootPath: folderB
|
||||
}
|
||||
});
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 2 });
|
||||
assert.isDefined(projectService.configuredProjects.get(aTsconfig.path));
|
||||
assert.isDefined(projectService.configuredProjects.get(bTsconfig.path));
|
||||
|
||||
debugger;
|
||||
verifyRenameResponse(session.executeCommandSeq<protocol.RenameRequest>({
|
||||
command: protocol.CommandTypes.Rename,
|
||||
arguments: {
|
||||
file: aFc,
|
||||
line: 1,
|
||||
offset: 14,
|
||||
findInStrings: false,
|
||||
findInComments: false
|
||||
}
|
||||
}).response as protocol.RenameResponseBody);
|
||||
|
||||
function verifyRenameResponse({ info, locs }: protocol.RenameResponseBody) {
|
||||
assert.isTrue(info.canRename);
|
||||
assert.equal(locs.length, 4);
|
||||
verifyLocations(0, aFile.path, aFc);
|
||||
verifyLocations(2, bFile.path, bFc);
|
||||
|
||||
function verifyLocations(locStartIndex: number, firstFile: string, secondFile: string) {
|
||||
assert.deepEqual(locs[locStartIndex], {
|
||||
file: firstFile,
|
||||
locs: [
|
||||
{ start: { line: 1, offset: 39 }, end: { line: 1, offset: 40 } },
|
||||
{ start: { line: 1, offset: 9 }, end: { line: 1, offset: 10 } }
|
||||
]
|
||||
});
|
||||
assert.deepEqual(locs[locStartIndex + 1], {
|
||||
file: secondFile,
|
||||
locs: [
|
||||
{ start: { line: 1, offset: 14 }, end: { line: 1, offset: 15 } }
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ interface Array<T> {}`
|
||||
path: string;
|
||||
content?: string;
|
||||
fileSize?: number;
|
||||
symLink?: string;
|
||||
}
|
||||
|
||||
interface FSEntry {
|
||||
@@ -86,6 +87,10 @@ interface Array<T> {}`
|
||||
entries: FSEntry[];
|
||||
}
|
||||
|
||||
interface SymLink extends FSEntry {
|
||||
symLink: string;
|
||||
}
|
||||
|
||||
function isFolder(s: FSEntry): s is Folder {
|
||||
return s && isArray((<Folder>s).entries);
|
||||
}
|
||||
@@ -94,6 +99,10 @@ interface Array<T> {}`
|
||||
return s && isString((<File>s).content);
|
||||
}
|
||||
|
||||
function isSymLink(s: FSEntry): s is SymLink {
|
||||
return s && isString((<SymLink>s).symLink);
|
||||
}
|
||||
|
||||
function invokeWatcherCallbacks<T>(callbacks: T[], invokeCallback: (cb: T) => void): void {
|
||||
if (callbacks) {
|
||||
// The array copy is made to ensure that even if one of the callback removes the callbacks,
|
||||
@@ -316,9 +325,12 @@ interface Array<T> {}`
|
||||
}
|
||||
}
|
||||
else {
|
||||
// TODO: Changing from file => folder
|
||||
// TODO: Changing from file => folder/Symlink
|
||||
}
|
||||
}
|
||||
else if (isSymLink(currentEntry)) {
|
||||
// TODO: update symlinks
|
||||
}
|
||||
else {
|
||||
// Folder
|
||||
if (isString(fileOrDirectory.content)) {
|
||||
@@ -339,7 +351,7 @@ interface Array<T> {}`
|
||||
// If this entry is not from the new file or folder
|
||||
if (!mapNewLeaves.get(path)) {
|
||||
// Leaf entries that arent in new list => remove these
|
||||
if (isFile(fileOrDirectory) || isFolder(fileOrDirectory) && fileOrDirectory.entries.length === 0) {
|
||||
if (isFile(fileOrDirectory) || isSymLink(fileOrDirectory) || isFolder(fileOrDirectory) && fileOrDirectory.entries.length === 0) {
|
||||
this.removeFileOrFolder(fileOrDirectory, folder => !mapNewLeaves.get(folder.path));
|
||||
}
|
||||
}
|
||||
@@ -387,6 +399,12 @@ interface Array<T> {}`
|
||||
const baseFolder = this.ensureFolder(getDirectoryPath(file.fullPath));
|
||||
this.addFileOrFolderInFolder(baseFolder, file, ignoreWatchInvokedWithTriggerAsFileCreate);
|
||||
}
|
||||
else if (isString(fileOrDirectory.symLink)) {
|
||||
const symLink = this.toSymLink(fileOrDirectory);
|
||||
Debug.assert(!this.fs.get(symLink.path));
|
||||
const baseFolder = this.ensureFolder(getDirectoryPath(symLink.fullPath));
|
||||
this.addFileOrFolderInFolder(baseFolder, symLink, ignoreWatchInvokedWithTriggerAsFileCreate);
|
||||
}
|
||||
else {
|
||||
const fullPath = getNormalizedAbsolutePath(fileOrDirectory.path, this.currentDirectory);
|
||||
this.ensureFolder(fullPath);
|
||||
@@ -414,20 +432,20 @@ interface Array<T> {}`
|
||||
return folder;
|
||||
}
|
||||
|
||||
private addFileOrFolderInFolder(folder: Folder, fileOrDirectory: File | Folder, ignoreWatch?: boolean) {
|
||||
private addFileOrFolderInFolder(folder: Folder, fileOrDirectory: File | Folder | SymLink, ignoreWatch?: boolean) {
|
||||
folder.entries.push(fileOrDirectory);
|
||||
this.fs.set(fileOrDirectory.path, fileOrDirectory);
|
||||
|
||||
if (ignoreWatch) {
|
||||
return;
|
||||
}
|
||||
if (isFile(fileOrDirectory)) {
|
||||
if (isFile(fileOrDirectory) || isSymLink(fileOrDirectory)) {
|
||||
this.invokeFileWatcher(fileOrDirectory.fullPath, FileWatcherEventKind.Created);
|
||||
}
|
||||
this.invokeDirectoryWatcher(folder.fullPath, fileOrDirectory.fullPath);
|
||||
}
|
||||
|
||||
private removeFileOrFolder(fileOrDirectory: File | Folder, isRemovableLeafFolder: (folder: Folder) => boolean, isRenaming?: boolean) {
|
||||
private removeFileOrFolder(fileOrDirectory: File | Folder | SymLink, isRemovableLeafFolder: (folder: Folder) => boolean, isRenaming?: boolean) {
|
||||
const basePath = getDirectoryPath(fileOrDirectory.path);
|
||||
const baseFolder = this.fs.get(basePath) as Folder;
|
||||
if (basePath !== fileOrDirectory.path) {
|
||||
@@ -436,7 +454,7 @@ interface Array<T> {}`
|
||||
}
|
||||
this.fs.delete(fileOrDirectory.path);
|
||||
|
||||
if (isFile(fileOrDirectory)) {
|
||||
if (isFile(fileOrDirectory) || isSymLink(fileOrDirectory)) {
|
||||
this.invokeFileWatcher(fileOrDirectory.fullPath, FileWatcherEventKind.Deleted);
|
||||
}
|
||||
else {
|
||||
@@ -461,7 +479,7 @@ interface Array<T> {}`
|
||||
|
||||
private invokeFileWatcher(fileFullPath: string, eventKind: FileWatcherEventKind) {
|
||||
const callbacks = this.watchedFiles.get(this.toPath(fileFullPath));
|
||||
invokeWatcherCallbacks(callbacks, ({ cb, fileName }) => cb(fileName, eventKind));
|
||||
invokeWatcherCallbacks(callbacks, ({ cb }) => cb(fileFullPath, eventKind));
|
||||
}
|
||||
|
||||
private getRelativePathToDirectory(directoryFullPath: string, fileFullPath: string) {
|
||||
@@ -503,6 +521,15 @@ interface Array<T> {}`
|
||||
};
|
||||
}
|
||||
|
||||
private toSymLink(fileOrDirectory: FileOrFolder): SymLink {
|
||||
const fullPath = getNormalizedAbsolutePath(fileOrDirectory.path, this.currentDirectory);
|
||||
return {
|
||||
path: this.toPath(fullPath),
|
||||
fullPath,
|
||||
symLink: getNormalizedAbsolutePath(fileOrDirectory.symLink, getDirectoryPath(fullPath))
|
||||
};
|
||||
}
|
||||
|
||||
private toFolder(path: string): Folder {
|
||||
const fullPath = getNormalizedAbsolutePath(path, this.currentDirectory);
|
||||
return {
|
||||
@@ -512,14 +539,52 @@ interface Array<T> {}`
|
||||
};
|
||||
}
|
||||
|
||||
fileExists(s: string) {
|
||||
const path = this.toFullPath(s);
|
||||
return isFile(this.fs.get(path));
|
||||
private getRealFsEntry<T extends FSEntry>(isFsEntry: (fsEntry: FSEntry) => fsEntry is T, path: Path, fsEntry = this.fs.get(path)): T | undefined {
|
||||
if (isFsEntry(fsEntry)) {
|
||||
return fsEntry;
|
||||
}
|
||||
|
||||
if (isSymLink(fsEntry)) {
|
||||
return this.getRealFsEntry(isFsEntry, this.toPath(fsEntry.symLink));
|
||||
}
|
||||
|
||||
if (fsEntry) {
|
||||
// This fs entry is something else
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const realpath = this.realpath(path);
|
||||
if (path !== realpath) {
|
||||
return this.getRealFsEntry(isFsEntry, realpath as Path);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
readFile(s: string) {
|
||||
const fsEntry = this.fs.get(this.toFullPath(s));
|
||||
return isFile(fsEntry) ? fsEntry.content : undefined;
|
||||
private isFile(fsEntry: FSEntry) {
|
||||
return !!this.getRealFile(fsEntry.path, fsEntry);
|
||||
}
|
||||
|
||||
private getRealFile(path: Path, fsEntry?: FSEntry): File | undefined {
|
||||
return this.getRealFsEntry(isFile, path, fsEntry);
|
||||
}
|
||||
|
||||
private isFolder(fsEntry: FSEntry) {
|
||||
return !!this.getRealFolder(fsEntry.path, fsEntry);
|
||||
}
|
||||
|
||||
private getRealFolder(path: Path, fsEntry = this.fs.get(path)): Folder | undefined {
|
||||
return this.getRealFsEntry(isFolder, path, fsEntry);
|
||||
}
|
||||
|
||||
fileExists(s: string) {
|
||||
const path = this.toFullPath(s);
|
||||
return !!this.getRealFile(path);
|
||||
}
|
||||
|
||||
readFile(s: string): string {
|
||||
const fsEntry = this.getRealFile(this.toFullPath(s));
|
||||
return fsEntry ? fsEntry.content : undefined;
|
||||
}
|
||||
|
||||
getFileSize(s: string) {
|
||||
@@ -533,14 +598,14 @@ interface Array<T> {}`
|
||||
|
||||
directoryExists(s: string) {
|
||||
const path = this.toFullPath(s);
|
||||
return isFolder(this.fs.get(path));
|
||||
return !!this.getRealFolder(path);
|
||||
}
|
||||
|
||||
getDirectories(s: string) {
|
||||
getDirectories(s: string): string[] {
|
||||
const path = this.toFullPath(s);
|
||||
const folder = this.fs.get(path);
|
||||
if (isFolder(folder)) {
|
||||
return mapDefined(folder.entries, entry => isFolder(entry) ? getBaseFileName(entry.fullPath) : undefined);
|
||||
const folder = this.getRealFolder(path);
|
||||
if (folder) {
|
||||
return mapDefined(folder.entries, entry => this.isFolder(entry) ? getBaseFileName(entry.fullPath) : undefined);
|
||||
}
|
||||
Debug.fail(folder ? "getDirectories called on file" : "getDirectories called on missing folder");
|
||||
return [];
|
||||
@@ -550,13 +615,13 @@ interface Array<T> {}`
|
||||
return ts.matchFiles(path, extensions, exclude, include, this.useCaseSensitiveFileNames, this.getCurrentDirectory(), depth, (dir) => {
|
||||
const directories: string[] = [];
|
||||
const files: string[] = [];
|
||||
const dirEntry = this.fs.get(this.toPath(dir));
|
||||
if (isFolder(dirEntry)) {
|
||||
dirEntry.entries.forEach((entry) => {
|
||||
if (isFolder(entry)) {
|
||||
const folder = this.getRealFolder(this.toPath(dir));
|
||||
if (folder) {
|
||||
folder.entries.forEach((entry) => {
|
||||
if (this.isFolder(entry)) {
|
||||
directories.push(getBaseFileName(entry.fullPath));
|
||||
}
|
||||
else if (isFile(entry)) {
|
||||
else if (this.isFile(entry)) {
|
||||
files.push(getBaseFileName(entry.fullPath));
|
||||
}
|
||||
else {
|
||||
@@ -682,6 +747,23 @@ interface Array<T> {}`
|
||||
clear(this.output);
|
||||
}
|
||||
|
||||
realpath(s: string): string {
|
||||
const fullPath = this.toNormalizedAbsolutePath(s);
|
||||
const path = this.toPath(fullPath);
|
||||
if (getDirectoryPath(path) === path) {
|
||||
// Root
|
||||
return s;
|
||||
}
|
||||
const dirFullPath = this.realpath(getDirectoryPath(fullPath));
|
||||
const realFullPath = combinePaths(dirFullPath, getBaseFileName(fullPath));
|
||||
const fsEntry = this.fs.get(this.toPath(realFullPath));
|
||||
if (isSymLink(fsEntry)) {
|
||||
return this.realpath(fsEntry.symLink);
|
||||
}
|
||||
|
||||
return realFullPath;
|
||||
}
|
||||
|
||||
readonly existMessage = "System Exit";
|
||||
exitCode: number;
|
||||
readonly resolvePath = (s: string) => s;
|
||||
|
||||
Vendored
+2
-2
@@ -3,7 +3,7 @@ interface ObjectConstructor {
|
||||
* Returns an array of values of the enumerable properties of an object
|
||||
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
|
||||
*/
|
||||
values<T>(o: { [s: string]: T } | { [n: number]: T }): T[];
|
||||
values<T>(o: { [s: string]: T } | ArrayLike<T>): T[];
|
||||
|
||||
/**
|
||||
* Returns an array of values of the enumerable properties of an object
|
||||
@@ -15,7 +15,7 @@ interface ObjectConstructor {
|
||||
* Returns an array of key/values of the enumerable properties of an object
|
||||
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
|
||||
*/
|
||||
entries<T>(o: { [s: string]: T } | { [n: number]: T }): [string, T][];
|
||||
entries<T>(o: { [s: string]: T } | ArrayLike<T>): [string, T][];
|
||||
|
||||
/**
|
||||
* Returns an array of key/values of the enumerable properties of an object
|
||||
|
||||
@@ -573,6 +573,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_a_property_name_2566" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have a property name.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[其余元素不能具有属性名。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_an_initializer_1186" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have an initializer.]]></Val>
|
||||
@@ -888,6 +897,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[将异步修饰符添加到包含函数]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3366,15 +3378,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_symbol_95003" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract symbol]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[提取符号]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_to_0_in_1_95004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1}]]></Val>
|
||||
@@ -3561,6 +3564,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_package_json_at_0_Package_ID_is_1_6190" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 'package.json' at '{0}'. Package ID is '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[在“{0}”找到了 "package.json"。包 ID 为“{1}”。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.]]></Val>
|
||||
@@ -4620,6 +4632,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[映射的对象类型隐式地含有 "any" 模板类型。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -5088,6 +5103,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Only_emit_d_ts_declaration_files_6014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Only emit '.d.ts' declaration files.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[仅发出 ".d.ts" 声明文件。 ]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause.]]></Val>
|
||||
@@ -6588,11 +6612,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_Colon_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Specify library files to be included in the compilation: ]]></Val>
|
||||
<Val><![CDATA[Specify library files to be included in the compilation.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[指定要在编译中包括的库文件: ]]></Val>
|
||||
<Val><![CDATA[指定要在编译中包括的库文件。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<Cmt Name="LcxAdmin" />
|
||||
<Cmt Name="Loc" />
|
||||
<Cmt Name="Note" />
|
||||
<Cmt Name="Rccx" />
|
||||
<Cmt Name="RCCX" />
|
||||
</OwnedComments>
|
||||
<Settings Name="@vsLocTools@\current\default.lss" Type="LSS" />
|
||||
<Item ItemId=";String Table" ItemType="0" PsrId="306" Leaf="false">
|
||||
@@ -573,6 +573,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_a_property_name_2566" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have a property name.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[REST 元素不得有屬性名稱。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_an_initializer_1186" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have an initializer.]]></Val>
|
||||
@@ -888,6 +897,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[將 async 修飾詞新增至包含的函式]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3366,15 +3378,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_symbol_95003" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract symbol]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[解壓縮符號]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_to_0_in_1_95004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1}]]></Val>
|
||||
@@ -3561,6 +3564,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_package_json_at_0_Package_ID_is_1_6190" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 'package.json' at '{0}'. Package ID is '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[於 '{0}' 找到 'package.json'。套件識別碼為 '{1}'。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.]]></Val>
|
||||
@@ -4620,6 +4632,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[對應的物件類型隱含具有 'any' 範本類型。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -6588,11 +6603,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_Colon_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Specify library files to be included in the compilation: ]]></Val>
|
||||
<Val><![CDATA[Specify library files to be included in the compilation.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[指定編譯內要包含的程式庫檔: ]]></Val>
|
||||
<Val><![CDATA[請指定要併入編譯中的程式庫檔案。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<Cmt Name="ManifestData" />
|
||||
<Cmt Name="Mnemonic" />
|
||||
<Cmt Name="Note" />
|
||||
<Cmt Name="Rccx" />
|
||||
<Cmt Name="RCCX" />
|
||||
<Cmt Name="UIType" />
|
||||
<Cmt Name="UTSData" />
|
||||
<Cmt Name="UTSUI" />
|
||||
@@ -582,6 +582,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_a_property_name_2566" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have a property name.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Element rest nemůže mít název vlastnosti.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_an_initializer_1186" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have an initializer.]]></Val>
|
||||
@@ -897,6 +906,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Přidat modifikátor async do obsahující funkce]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3375,15 +3387,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_symbol_95003" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract symbol]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Extrahovat symbol]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_to_0_in_1_95004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1}]]></Val>
|
||||
@@ -3570,6 +3573,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_package_json_at_0_Package_ID_is_1_6190" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 'package.json' at '{0}'. Package ID is '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[V {0} se našel soubor package.json. ID balíčku je {1}.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.]]></Val>
|
||||
@@ -4629,6 +4641,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Typu mapovaného objektu má implicitně typ šablony any.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -6597,11 +6612,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_Colon_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Specify library files to be included in the compilation: ]]></Val>
|
||||
<Val><![CDATA[Specify library files to be included in the compilation.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Zadejte soubory knihovny, které se mají zahrnout do kompilace: ]]></Val>
|
||||
<Val><![CDATA[Zadejte soubory knihovny, které se mají zahrnout do kompilace.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<Cmt Name="LcxAdmin" />
|
||||
<Cmt Name="Loc" />
|
||||
<Cmt Name="Note" />
|
||||
<Cmt Name="Rccx" />
|
||||
<Cmt Name="RCCX" />
|
||||
</OwnedComments>
|
||||
<Settings Name="@vsLocTools@\current\default.lss" Type="LSS" />
|
||||
<Item ItemId=";String Table" ItemType="0" PsrId="306" Leaf="false">
|
||||
@@ -573,6 +573,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_a_property_name_2566" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have a property name.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ein rest-Element darf keinen Eigenschaftennamen aufweisen.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_an_initializer_1186" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have an initializer.]]></Val>
|
||||
@@ -885,6 +894,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Async-Modifizierer zur enthaltenden Funktion hinzufügen]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3363,15 +3375,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_symbol_95003" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract symbol]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Symbol extrahieren]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_to_0_in_1_95004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1}]]></Val>
|
||||
@@ -3558,6 +3561,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_package_json_at_0_Package_ID_is_1_6190" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 'package.json' at '{0}'. Package ID is '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA["Package.json" unter "{0}" gefunden. Paket-ID: "{1}".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.]]></Val>
|
||||
@@ -4617,6 +4629,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Der zugeordnete Objekttyp weist implizit einen any-Vorlagentyp auf.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -6579,11 +6594,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_Colon_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Specify library files to be included in the compilation: ]]></Val>
|
||||
<Val><![CDATA[Specify library files to be included in the compilation.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Geben Sie Bibliotheksdateien an, die in die Kompilierung eingeschlossen werden sollen: ]]></Val>
|
||||
<Val><![CDATA[Geben Sie Bibliotheksdateien an, die in die Kompilierung eingeschlossen werden sollen.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<Cmt Name="ManifestData" />
|
||||
<Cmt Name="Mnemonic" />
|
||||
<Cmt Name="Note" />
|
||||
<Cmt Name="Rccx" />
|
||||
<Cmt Name="RCCX" />
|
||||
<Cmt Name="UIType" />
|
||||
<Cmt Name="UTSData" />
|
||||
<Cmt Name="UTSUI" />
|
||||
@@ -582,6 +582,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_a_property_name_2566" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have a property name.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Un elemento rest no puede tener un nombre de propiedad.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_an_initializer_1186" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have an initializer.]]></Val>
|
||||
@@ -897,6 +906,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Agregar el modificador async a la función contenedora]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3375,15 +3387,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_symbol_95003" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract symbol]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Extraer el símbolo]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_to_0_in_1_95004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1}]]></Val>
|
||||
@@ -3570,6 +3573,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_package_json_at_0_Package_ID_is_1_6190" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 'package.json' at '{0}'. Package ID is '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Se encontró "package.json" en "{0}". El identificador de paquete es "{1}".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.]]></Val>
|
||||
@@ -4629,6 +4641,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[El tipo de objeto asignado tiene implícitamente un tipo de plantilla "any".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -6597,11 +6612,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_Colon_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Specify library files to be included in the compilation: ]]></Val>
|
||||
<Val><![CDATA[Specify library files to be included in the compilation.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Especifique archivos de biblioteca para incluirlos en la compilación: ]]></Val>
|
||||
<Val><![CDATA[Especifique los archivos de biblioteca que se van a incluir en la compilación.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -582,6 +582,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_a_property_name_2566" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have a property name.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Un élément rest ne peut pas avoir de nom de propriété.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_an_initializer_1186" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have an initializer.]]></Val>
|
||||
@@ -897,6 +906,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ajouter le modificateur async dans la fonction conteneur]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3375,15 +3387,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_symbol_95003" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract symbol]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Extraire le symbole]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_to_0_in_1_95004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1}]]></Val>
|
||||
@@ -3570,6 +3573,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_package_json_at_0_Package_ID_is_1_6190" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 'package.json' at '{0}'. Package ID is '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['package.json' trouvé sur '{0}'. L'ID de package est '{1}'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.]]></Val>
|
||||
@@ -4629,6 +4641,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Le type d'objet mappé a implicitement un type de modèle 'any'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -5097,6 +5112,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Only_emit_d_ts_declaration_files_6014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Only emit '.d.ts' declaration files.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Émettez uniquement les fichiers de déclaration '.d.ts'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause.]]></Val>
|
||||
@@ -6597,11 +6621,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_Colon_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Specify library files to be included in the compilation: ]]></Val>
|
||||
<Val><![CDATA[Specify library files to be included in the compilation.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Spécifiez les fichiers bibliothèques à inclure dans la compilation : ]]></Val>
|
||||
<Val><![CDATA[Spécifiez les fichiers bibliothèques à inclure dans la compilation.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -8641,7 +8665,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['enum declarations' can only be used in a .ts file.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Les déclarations 'enum' peuvent uniquement être utilisées dans un fichier .ts.]]></Val>
|
||||
<Val><![CDATA['Les déclarations enum' peuvent uniquement être utilisées dans un fichier .ts.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -573,6 +573,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_a_property_name_2566" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have a property name.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Un elemento rest non può contenere un nome proprietà.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_an_initializer_1186" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have an initializer.]]></Val>
|
||||
@@ -888,6 +897,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Aggiungere il modificatore async alla funzione contenitore]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3366,15 +3378,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_symbol_95003" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract symbol]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Estrarre il simbolo]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_to_0_in_1_95004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1}]]></Val>
|
||||
@@ -3561,6 +3564,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_package_json_at_0_Package_ID_is_1_6190" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 'package.json' at '{0}'. Package ID is '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Il file 'package.json' è stato trovato in '{0}'. L'ID pacchetto è '{1}'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.]]></Val>
|
||||
@@ -4620,6 +4632,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Il tipo di oggetto con mapping contiene implicitamente un tipo di modello 'any'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -5088,6 +5103,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Only_emit_d_ts_declaration_files_6014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Only emit '.d.ts' declaration files.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Crea solo i file di dichiarazione '.d.ts'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause.]]></Val>
|
||||
@@ -6588,11 +6612,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_Colon_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Specify library files to be included in the compilation: ]]></Val>
|
||||
<Val><![CDATA[Specify library files to be included in the compilation.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Specifica i file di libreria da includere nella compilazione: ]]></Val>
|
||||
<Val><![CDATA[Specificare i file di libreria da includere nella compilazione.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -8632,7 +8656,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['enum declarations' can only be used in a .ts file.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['enum declarations' può essere usato solo in un file con estensione ts.]]></Val>
|
||||
<Val><![CDATA[Le dichiarazioni 'enum' possono essere usate solo in un file con estensione ts.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<Cmt Name="LcxAdmin" />
|
||||
<Cmt Name="Loc" />
|
||||
<Cmt Name="Note" />
|
||||
<Cmt Name="Rccx" />
|
||||
<Cmt Name="RCCX" />
|
||||
</OwnedComments>
|
||||
<Settings Name="@vsLocTools@\current\default.lss" Type="LSS" />
|
||||
<Item ItemId=";String Table" ItemType="0" PsrId="306" Leaf="false">
|
||||
@@ -573,6 +573,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_a_property_name_2566" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have a property name.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[rest 要素にプロパティ名を指定することはできません。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_an_initializer_1186" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have an initializer.]]></Val>
|
||||
@@ -888,6 +897,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[含まれている関数に async 修飾子を追加します]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3366,15 +3378,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_symbol_95003" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract symbol]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[シンボルの抽出]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_to_0_in_1_95004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1}]]></Val>
|
||||
@@ -3561,6 +3564,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_package_json_at_0_Package_ID_is_1_6190" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 'package.json' at '{0}'. Package ID is '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['{0}' で 'package.json' が見つかりました。パッケージ ID は、'{1}' です。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.]]></Val>
|
||||
@@ -4620,6 +4632,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[マップされたオブジェクト型のテンプレートの型は暗黙的に 'any' になります。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -6588,11 +6603,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_Colon_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Specify library files to be included in the compilation: ]]></Val>
|
||||
<Val><![CDATA[Specify library files to be included in the compilation.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[コンパイルに含めるライブラリ ファイルを指定します: ]]></Val>
|
||||
<Val><![CDATA[コンパイルに含めるライブラリ ファイルを指定します。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<Cmt Name="LcxAdmin" />
|
||||
<Cmt Name="Loc" />
|
||||
<Cmt Name="Note" />
|
||||
<Cmt Name="Rccx" />
|
||||
<Cmt Name="RCCX" />
|
||||
</OwnedComments>
|
||||
<Settings Name="@vsLocTools@\current\default.lss" Type="LSS" />
|
||||
<Item ItemId=";String Table" ItemType="0" PsrId="306" Leaf="false">
|
||||
@@ -573,6 +573,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_a_property_name_2566" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have a property name.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[rest 요소에는 속성 이름을 사용할 수 없습니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_an_initializer_1186" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have an initializer.]]></Val>
|
||||
@@ -888,6 +897,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[포함된 함수에 async 한정자 추가]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3366,15 +3378,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_symbol_95003" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract symbol]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[기호 추출]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_to_0_in_1_95004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1}]]></Val>
|
||||
@@ -3561,6 +3564,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_package_json_at_0_Package_ID_is_1_6190" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 'package.json' at '{0}'. Package ID is '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['{0}'에서 'package.json'을 찾았습니다. 패키지 ID는 '{1}'입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.]]></Val>
|
||||
@@ -4620,6 +4632,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[매핑된 개체 형식에는 'any' 템플릿 형식이 암시적으로 포함됩니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -6588,11 +6603,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_Colon_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Specify library files to be included in the compilation: ]]></Val>
|
||||
<Val><![CDATA[Specify library files to be included in the compilation.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[컴파일에 포함할 라이브러리 파일 지정: ]]></Val>
|
||||
<Val><![CDATA[컴파일에 포함할 라이브러리 파일을 지정합니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<Cmt Name="Dev" />
|
||||
<Cmt Name="LcxAdmin" />
|
||||
<Cmt Name="Loc" />
|
||||
<Cmt Name="Rccx" />
|
||||
<Cmt Name="RCCX" />
|
||||
</OwnedComments>
|
||||
<Settings Name="@vsLocTools@\current\default.lss" Type="LSS" />
|
||||
<Item ItemId=";String Table" ItemType="0" PsrId="306" Leaf="false">
|
||||
@@ -566,6 +566,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_a_property_name_2566" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have a property name.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Element rest nie może mieć nazwy właściwości.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_an_initializer_1186" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have an initializer.]]></Val>
|
||||
@@ -878,6 +887,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Dodaj modyfikator asynchroniczny do funkcji zawierającej]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3356,15 +3368,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_symbol_95003" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract symbol]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Wyodrębnij symbol]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_to_0_in_1_95004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1}]]></Val>
|
||||
@@ -3551,6 +3554,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_package_json_at_0_Package_ID_is_1_6190" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 'package.json' at '{0}'. Package ID is '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Znaleziono plik „package.json” w lokalizacji „{0}”. Identyfikator pakietu to „{1}”.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.]]></Val>
|
||||
@@ -4610,6 +4622,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Zmapowany typ obiektu niejawnie ma typ szablonu „any”.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -6572,11 +6587,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_Colon_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Specify library files to be included in the compilation: ]]></Val>
|
||||
<Val><![CDATA[Specify library files to be included in the compilation.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Określ pliki biblioteki do uwzględnienia w kompilacji: ]]></Val>
|
||||
<Val><![CDATA[Określ pliki biblioteki do uwzględnienia w kompilacji.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<Cmt Name="Dev" />
|
||||
<Cmt Name="LcxAdmin" />
|
||||
<Cmt Name="Loc" />
|
||||
<Cmt Name="Rccx" />
|
||||
<Cmt Name="RCCX" />
|
||||
</OwnedComments>
|
||||
<Settings Name="@vsLocTools@\current\default.lss" Type="LSS" />
|
||||
<Item ItemId=";String Table" ItemType="0" PsrId="306" Leaf="false">
|
||||
@@ -566,6 +566,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_a_property_name_2566" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have a property name.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Um elemento restante não pode ter um nome de propriedade.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_an_initializer_1186" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have an initializer.]]></Val>
|
||||
@@ -878,6 +887,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Adicione o modificador assíncrono que contém a função]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3356,15 +3368,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_symbol_95003" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract symbol]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Extrair símbolo]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_to_0_in_1_95004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1}]]></Val>
|
||||
@@ -3551,6 +3554,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_package_json_at_0_Package_ID_is_1_6190" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 'package.json' at '{0}'. Package ID is '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['package.json' encontrado em '{0}'. A ID do pacote é '{1}'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.]]></Val>
|
||||
@@ -4610,6 +4622,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[O tipo de objeto mapeado implicitamente tem um tipo de modelo 'any'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -6572,11 +6587,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_Colon_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Specify library files to be included in the compilation: ]]></Val>
|
||||
<Val><![CDATA[Specify library files to be included in the compilation.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Especifique os arquivos de biblioteca a serem incluídos na compilação: ]]></Val>
|
||||
<Val><![CDATA[Especifique os arquivos de biblioteca a serem incluídos na compilação.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<Cmt Name="Dev" />
|
||||
<Cmt Name="LcxAdmin" />
|
||||
<Cmt Name="Note" />
|
||||
<Cmt Name="Rccx" />
|
||||
<Cmt Name="RCCX" />
|
||||
</OwnedComments>
|
||||
<Settings Name="@vsLocTools@\current\default.lss" Type="LSS" />
|
||||
<Item ItemId=";String Table" ItemType="0" PsrId="306" Leaf="false">
|
||||
@@ -572,6 +572,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_a_property_name_2566" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have a property name.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Элемент rest не может иметь имя свойства.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_an_initializer_1186" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have an initializer.]]></Val>
|
||||
@@ -887,6 +896,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Добавьте модификатор async в содержащую функцию]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3365,15 +3377,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_symbol_95003" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract symbol]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Извлечь символ]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_to_0_in_1_95004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1}]]></Val>
|
||||
@@ -3560,6 +3563,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_package_json_at_0_Package_ID_is_1_6190" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 'package.json' at '{0}'. Package ID is '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Найден "package.json" в "{0}". Идентификатор пакета: "{1}".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.]]></Val>
|
||||
@@ -4619,6 +4631,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Сопоставленный объект неявно имеет тип шаблона "любой".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -6587,11 +6602,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_Colon_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Specify library files to be included in the compilation: ]]></Val>
|
||||
<Val><![CDATA[Specify library files to be included in the compilation.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Укажите файлы библиотеки для включения в компиляцию: ]]></Val>
|
||||
<Val><![CDATA[Укажите файлы библиотек для включения в компиляцию.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<Cmt Name="Dev" />
|
||||
<Cmt Name="LcxAdmin" />
|
||||
<Cmt Name="Loc" />
|
||||
<Cmt Name="Rccx" />
|
||||
<Cmt Name="RCCX" />
|
||||
</OwnedComments>
|
||||
<Settings Name="@vsLocTools@\current\default.lss" Type="LSS" />
|
||||
<Item ItemId=";String Table" ItemType="0" PsrId="306" Leaf="false">
|
||||
@@ -566,6 +566,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_a_property_name_2566" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have a property name.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Rest öğesinin özellik adı olamaz.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";A_rest_element_cannot_have_an_initializer_1186" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[A rest element cannot have an initializer.]]></Val>
|
||||
@@ -881,6 +890,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[İçeren işleve zaman uyumsuz değiştirici ekle]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3359,15 +3371,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_symbol_95003" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract symbol]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Sembolü ayıkla]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Extract_to_0_in_1_95004" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1}]]></Val>
|
||||
@@ -3554,6 +3557,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Found_package_json_at_0_Package_ID_is_1_6190" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Found 'package.json' at '{0}'. Package ID is '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['{0}' konumunda 'package.json' bulundu. Paket kimliği '{1}'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.]]></Val>
|
||||
@@ -4613,6 +4625,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Eşleştirilmiş nesne türü örtük olarak 'any' şablon türüne sahip.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -6581,11 +6596,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_Colon_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Specify_library_files_to_be_included_in_the_compilation_6079" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Specify library files to be included in the compilation: ]]></Val>
|
||||
<Val><![CDATA[Specify library files to be included in the compilation.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Derlemeye dahil edilecek kitaplık dosyalarını belirtin: ]]></Val>
|
||||
<Val><![CDATA[Derlemeye dahil edilecek kitaplık dosyalarını belirtin.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -558,8 +558,7 @@ namespace ts.server {
|
||||
const request = this.processRequest<protocol.CodeFixRequest>(CommandNames.GetCodeFixes, args);
|
||||
const response = this.processResponse<protocol.CodeFixResponse>(request);
|
||||
|
||||
// TODO: GH#20538 shouldn't need cast
|
||||
return (response.body as ReadonlyArray<protocol.CodeFixAction>).map(({ description, changes, fixId }) => ({ description, changes: this.convertChanges(changes, file), fixId }));
|
||||
return response.body.map(({ description, changes, fixId }) => ({ description, changes: this.convertChanges(changes, file), fixId }));
|
||||
}
|
||||
|
||||
getCombinedCodeFix = notImplemented;
|
||||
|
||||
@@ -198,16 +198,6 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project.
|
||||
*/
|
||||
export function combineProjectOutput<T>(projects: ReadonlyArray<Project>, action: (project: Project) => ReadonlyArray<T>, comparer?: (a: T, b: T) => number, areEqual?: (a: T, b: T) => boolean) {
|
||||
const outputs = flatMap(projects, action);
|
||||
return comparer
|
||||
? sortAndDeduplicate(outputs, comparer, areEqual)
|
||||
: deduplicate(outputs, areEqual);
|
||||
}
|
||||
|
||||
export interface HostConfiguration {
|
||||
formatCodeOptions: FormatCodeSettings;
|
||||
hostInfo: string;
|
||||
@@ -335,6 +325,11 @@ namespace ts.server {
|
||||
* Container of all known scripts
|
||||
*/
|
||||
private readonly filenameToScriptInfo = createMap<ScriptInfo>();
|
||||
/**
|
||||
* Map to the real path of the infos
|
||||
*/
|
||||
/* @internal */
|
||||
readonly realpathToScriptInfos: MultiMap<ScriptInfo> | undefined;
|
||||
/**
|
||||
* maps external project file name to list of config files that were the part of this project
|
||||
*/
|
||||
@@ -427,7 +422,9 @@ namespace ts.server {
|
||||
this.typesMapLocation = (opts.typesMapLocation === undefined) ? combinePaths(this.getExecutingFilePath(), "../typesMap.json") : opts.typesMapLocation;
|
||||
|
||||
Debug.assert(!!this.host.createHash, "'ServerHost.createHash' is required for ProjectService");
|
||||
|
||||
if (this.host.realpath) {
|
||||
this.realpathToScriptInfos = createMultiMap();
|
||||
}
|
||||
this.currentDirectory = this.host.getCurrentDirectory();
|
||||
this.toCanonicalFileName = createGetCanonicalFileName(this.host.useCaseSensitiveFileNames);
|
||||
this.throttledOperations = new ThrottledOperations(this.host, this.logger);
|
||||
@@ -727,15 +724,6 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private findContainingExternalProject(fileName: NormalizedPath): ExternalProject {
|
||||
for (const proj of this.externalProjects) {
|
||||
if (proj.containsFile(fileName)) {
|
||||
return proj;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getFormatCodeOptions(file?: NormalizedPath) {
|
||||
let formatCodeSettings: FormatCodeSettings;
|
||||
if (file) {
|
||||
@@ -768,7 +756,7 @@ namespace ts.server {
|
||||
if (info.containingProjects.length === 0) {
|
||||
// Orphan script info, remove it as we can always reload it on next open file request
|
||||
this.stopWatchingScriptInfo(info);
|
||||
this.filenameToScriptInfo.delete(info.path);
|
||||
this.deleteScriptInfo(info);
|
||||
}
|
||||
else {
|
||||
// file has been changed which might affect the set of referenced files in projects that include
|
||||
@@ -785,7 +773,7 @@ namespace ts.server {
|
||||
// TODO: handle isOpen = true case
|
||||
|
||||
if (!info.isScriptOpen()) {
|
||||
this.filenameToScriptInfo.delete(info.path);
|
||||
this.deleteScriptInfo(info);
|
||||
|
||||
// capture list of projects since detachAllProjects will wipe out original list
|
||||
const containingProjects = info.containingProjects.slice();
|
||||
@@ -910,7 +898,7 @@ namespace ts.server {
|
||||
|
||||
const project = this.getOrCreateInferredProjectForProjectRootPathIfEnabled(info, projectRootPath) ||
|
||||
this.getOrCreateSingleInferredProjectIfEnabled() ||
|
||||
this.createInferredProject(getDirectoryPath(info.path));
|
||||
this.createInferredProject(info.isDynamic ? this.currentDirectory : getDirectoryPath(info.path));
|
||||
|
||||
project.addRoot(info);
|
||||
project.updateGraph();
|
||||
@@ -1019,11 +1007,19 @@ namespace ts.server {
|
||||
if (!info.isScriptOpen() && info.isOrphan()) {
|
||||
// if there are not projects that include this script info - delete it
|
||||
this.stopWatchingScriptInfo(info);
|
||||
this.filenameToScriptInfo.delete(info.path);
|
||||
this.deleteScriptInfo(info);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private deleteScriptInfo(info: ScriptInfo) {
|
||||
this.filenameToScriptInfo.delete(info.path);
|
||||
const realpath = info.getRealpathIfDifferent();
|
||||
if (realpath) {
|
||||
this.realpathToScriptInfos.remove(realpath, info);
|
||||
}
|
||||
}
|
||||
|
||||
private configFileExists(configFileName: NormalizedPath, canonicalConfigFilePath: string, info: ScriptInfo) {
|
||||
let configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
|
||||
if (configFileExistenceInfo) {
|
||||
@@ -1499,7 +1495,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private createConfiguredProject(configFileName: NormalizedPath) {
|
||||
const cachedDirectoryStructureHost = createCachedDirectoryStructureHost(this.host);
|
||||
const cachedDirectoryStructureHost = createCachedDirectoryStructureHost(this.host, this.host.getCurrentDirectory(), this.host.useCaseSensitiveFileNames);
|
||||
const { projectOptions, configFileErrors, configFileSpecs } = this.convertConfigFileContentToProjectOptions(configFileName, cachedDirectoryStructureHost);
|
||||
this.logger.info(`Opened configuration file ${configFileName}`);
|
||||
const languageServiceEnabled = !this.exceededTotalSizeLimitForNonTsFiles(configFileName, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader);
|
||||
@@ -1659,7 +1655,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private getOrCreateInferredProjectForProjectRootPathIfEnabled(info: ScriptInfo, projectRootPath: NormalizedPath | undefined): InferredProject | undefined {
|
||||
if (!this.useInferredProjectPerProjectRoot) {
|
||||
if (info.isDynamic || !this.useInferredProjectPerProjectRoot) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1736,6 +1732,43 @@ namespace ts.server {
|
||||
return this.getScriptInfoForNormalizedPath(toNormalizedPath(uncheckedFileName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the projects that contain script info through SymLink
|
||||
* Note that this does not return projects in info.containingProjects
|
||||
*/
|
||||
/*@internal*/
|
||||
getSymlinkedProjects(info: ScriptInfo): MultiMap<Project> | undefined {
|
||||
let projects: MultiMap<Project> | undefined;
|
||||
if (this.realpathToScriptInfos) {
|
||||
const realpath = info.getRealpathIfDifferent();
|
||||
if (realpath) {
|
||||
forEach(this.realpathToScriptInfos.get(realpath), combineProjects);
|
||||
}
|
||||
forEach(this.realpathToScriptInfos.get(info.path), combineProjects);
|
||||
}
|
||||
|
||||
return projects;
|
||||
|
||||
function combineProjects(toAddInfo: ScriptInfo) {
|
||||
if (toAddInfo !== info) {
|
||||
for (const project of toAddInfo.containingProjects) {
|
||||
// Add the projects only if they can use symLink targets and not already in the list
|
||||
if (project.languageServiceEnabled &&
|
||||
!project.getCompilerOptions().preserveSymlinks &&
|
||||
!contains(info.containingProjects, project)) {
|
||||
if (!projects) {
|
||||
projects = createMultiMap();
|
||||
projects.add(toAddInfo.path, project);
|
||||
}
|
||||
else if (!forEachEntry(projects, (projs, path) => path === toAddInfo.path ? false : contains(projs, project))) {
|
||||
projects.add(toAddInfo.path, project);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private watchClosedScriptInfo(info: ScriptInfo) {
|
||||
Debug.assert(!info.fileWatcher);
|
||||
// do not watch files with mixed content - server doesn't know how to interpret it
|
||||
@@ -1767,19 +1800,19 @@ namespace ts.server {
|
||||
return this.getOrCreateScriptInfoWorker(fileName, currentDirectory, /*openedByClient*/ true, fileContent, scriptKind, hasMixedContent);
|
||||
}
|
||||
|
||||
getOrCreateScriptInfoForNormalizedPath(fileName: NormalizedPath, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, hostToQueryFileExistsOn?: DirectoryStructureHost) {
|
||||
getOrCreateScriptInfoForNormalizedPath(fileName: NormalizedPath, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, hostToQueryFileExistsOn?: { fileExists(path: string): boolean; }) {
|
||||
return this.getOrCreateScriptInfoWorker(fileName, this.currentDirectory, openedByClient, fileContent, scriptKind, hasMixedContent, hostToQueryFileExistsOn);
|
||||
}
|
||||
|
||||
private getOrCreateScriptInfoWorker(fileName: NormalizedPath, currentDirectory: string, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, hostToQueryFileExistsOn?: DirectoryStructureHost) {
|
||||
private getOrCreateScriptInfoWorker(fileName: NormalizedPath, currentDirectory: string, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, hostToQueryFileExistsOn?: { fileExists(path: string): boolean; }) {
|
||||
Debug.assert(fileContent === undefined || openedByClient, "ScriptInfo needs to be opened by client to be able to set its user defined content");
|
||||
const path = normalizedPathToPath(fileName, currentDirectory, this.toCanonicalFileName);
|
||||
let info = this.getScriptInfoForPath(path);
|
||||
if (!info) {
|
||||
const isDynamic = isDynamicFileName(fileName);
|
||||
Debug.assert(isRootedDiskPath(fileName) || isDynamic || openedByClient, "Script info with non-dynamic relative file name can only be open script info");
|
||||
Debug.assert(!isRootedDiskPath(fileName) || this.currentDirectory === currentDirectory || !this.openFilesWithNonRootedDiskPath.has(this.toCanonicalFileName(fileName)), "Open script files with non rooted disk path opened with current directory context cannot have same canonical names");
|
||||
Debug.assert(!isDynamic || this.currentDirectory === currentDirectory, "Dynamic files must always have current directory context since containing external project name will always match the script info name.");
|
||||
Debug.assert(isRootedDiskPath(fileName) || isDynamic || openedByClient, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nScript info with non-dynamic relative file name can only be open script info`);
|
||||
Debug.assert(!isRootedDiskPath(fileName) || this.currentDirectory === currentDirectory || !this.openFilesWithNonRootedDiskPath.has(this.toCanonicalFileName(fileName)), "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nOpen script files with non rooted disk path opened with current directory context cannot have same canonical names`);
|
||||
Debug.assert(!isDynamic || this.currentDirectory === currentDirectory, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nDynamic files must always have current directory context since containing external project name will always match the script info name.`);
|
||||
// If the file is not opened by client and the file doesnot exist on the disk, return
|
||||
if (!openedByClient && !isDynamic && !(hostToQueryFileExistsOn || this.host).fileExists(fileName)) {
|
||||
return;
|
||||
@@ -1994,13 +2027,24 @@ namespace ts.server {
|
||||
return this.openClientFileWithNormalizedPath(toNormalizedPath(fileName), fileContent, scriptKind, /*hasMixedContent*/ false, projectRootPath ? toNormalizedPath(projectRootPath) : undefined);
|
||||
}
|
||||
|
||||
private findExternalProjetContainingOpenScriptInfo(info: ScriptInfo): ExternalProject {
|
||||
for (const proj of this.externalProjects) {
|
||||
// Ensure project structure is uptodate to check if info is present in external project
|
||||
proj.updateGraph();
|
||||
if (proj.containsScriptInfo(info)) {
|
||||
return proj;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult {
|
||||
let configFileName: NormalizedPath;
|
||||
let sendConfigFileDiagEvent = false;
|
||||
let configFileErrors: ReadonlyArray<Diagnostic>;
|
||||
|
||||
const info = this.getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName, projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory, fileContent, scriptKind, hasMixedContent);
|
||||
let project: ConfiguredProject | ExternalProject = this.findContainingExternalProject(fileName);
|
||||
let project: ConfiguredProject | ExternalProject = this.findExternalProjetContainingOpenScriptInfo(info);
|
||||
if (!project) {
|
||||
configFileName = this.getConfigFileNameForFile(info, projectRootPath);
|
||||
if (configFileName) {
|
||||
@@ -2010,6 +2054,10 @@ namespace ts.server {
|
||||
// Send the event only if the project got created as part of this open request
|
||||
sendConfigFileDiagEvent = true;
|
||||
}
|
||||
else {
|
||||
// Ensure project is ready to check if it contains opened script info
|
||||
project.updateGraph();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (project && !project.languageServiceEnabled) {
|
||||
|
||||
+22
-27
@@ -3,7 +3,7 @@
|
||||
/// <reference path="scriptInfo.ts"/>
|
||||
/// <reference path="..\compiler\resolutionCache.ts"/>
|
||||
/// <reference path="typingsCache.ts"/>
|
||||
/// <reference path="..\compiler\builder.ts"/>
|
||||
/// <reference path="..\compiler\builderState.ts"/>
|
||||
|
||||
namespace ts.server {
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace ts.server {
|
||||
/*@internal*/
|
||||
resolutionCache: ResolutionCache;
|
||||
|
||||
private builder: Builder;
|
||||
private builderState: BuilderState | undefined;
|
||||
/**
|
||||
* Set of files names that were updated since the last call to getChangesSinceVersion.
|
||||
*/
|
||||
@@ -202,6 +202,9 @@ namespace ts.server {
|
||||
/*@internal*/
|
||||
readonly currentDirectory: string;
|
||||
|
||||
/*@internal*/
|
||||
public directoryStructureHost: DirectoryStructureHost;
|
||||
|
||||
/*@internal*/
|
||||
constructor(
|
||||
/*@internal*/readonly projectName: string,
|
||||
@@ -212,8 +215,9 @@ namespace ts.server {
|
||||
languageServiceEnabled: boolean,
|
||||
private compilerOptions: CompilerOptions,
|
||||
public compileOnSaveEnabled: boolean,
|
||||
/*@internal*/public directoryStructureHost: DirectoryStructureHost,
|
||||
directoryStructureHost: DirectoryStructureHost,
|
||||
currentDirectory: string | undefined) {
|
||||
this.directoryStructureHost = directoryStructureHost;
|
||||
this.currentDirectory = this.projectService.getNormalizedAbsolutePath(currentDirectory || "");
|
||||
|
||||
this.cancellationToken = new ThrottledCancellationToken(this.projectService.cancellationToken, this.projectService.throttleWaitMilliseconds);
|
||||
@@ -238,7 +242,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
// Use the current directory as resolution root only if the project created using current directory string
|
||||
this.resolutionCache = createResolutionCache(this, currentDirectory && this.currentDirectory);
|
||||
this.resolutionCache = createResolutionCache(this, currentDirectory && this.currentDirectory, /*logChangesWhenResolvingModule*/ true);
|
||||
this.languageService = createLanguageService(this, this.documentRegistry);
|
||||
if (!languageServiceEnabled) {
|
||||
this.disableLanguageService();
|
||||
@@ -267,7 +271,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
getNewLine() {
|
||||
return this.directoryStructureHost.newLine;
|
||||
return this.projectService.host.newLine;
|
||||
}
|
||||
|
||||
getProjectVersion() {
|
||||
@@ -335,7 +339,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
useCaseSensitiveFileNames() {
|
||||
return this.directoryStructureHost.useCaseSensitiveFileNames;
|
||||
return this.projectService.host.useCaseSensitiveFileNames;
|
||||
}
|
||||
|
||||
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[] {
|
||||
@@ -343,7 +347,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
readFile(fileName: string): string | undefined {
|
||||
return this.directoryStructureHost.readFile(fileName);
|
||||
return this.projectService.host.readFile(fileName);
|
||||
}
|
||||
|
||||
fileExists(file: string): boolean {
|
||||
@@ -354,7 +358,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModuleFull[] {
|
||||
return this.resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames, /*logChanges*/ true);
|
||||
return this.resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames);
|
||||
}
|
||||
|
||||
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[] {
|
||||
@@ -369,6 +373,11 @@ namespace ts.server {
|
||||
return this.directoryStructureHost.getDirectories(path);
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getCachedDirectoryStructureHost(): CachedDirectoryStructureHost {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
toPath(fileName: string) {
|
||||
return toPath(fileName, this.currentDirectory, this.projectService.toCanonicalFileName);
|
||||
@@ -443,15 +452,6 @@ namespace ts.server {
|
||||
return this.languageService;
|
||||
}
|
||||
|
||||
private ensureBuilder() {
|
||||
if (!this.builder) {
|
||||
this.builder = createBuilder({
|
||||
getCanonicalFileName: this.projectService.toCanonicalFileName,
|
||||
computeHash: data => this.projectService.host.createHash(data)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private shouldEmitFile(scriptInfo: ScriptInfo) {
|
||||
return scriptInfo && !scriptInfo.isDynamicOrHasMixedContent();
|
||||
}
|
||||
@@ -461,8 +461,8 @@ namespace ts.server {
|
||||
return [];
|
||||
}
|
||||
this.updateGraph();
|
||||
this.ensureBuilder();
|
||||
return mapDefined(this.builder.getFilesAffectedBy(this.program, scriptInfo.path),
|
||||
this.builderState = BuilderState.create(this.program, this.projectService.toCanonicalFileName, this.builderState);
|
||||
return mapDefined(BuilderState.getFilesAffectedBy(this.builderState, this.program, scriptInfo.path, this.cancellationToken, data => this.projectService.host.createHash(data)),
|
||||
sourceFile => this.shouldEmitFile(this.projectService.getScriptInfoForPath(sourceFile.path)) ? sourceFile.fileName : undefined);
|
||||
}
|
||||
|
||||
@@ -498,6 +498,7 @@ namespace ts.server {
|
||||
}
|
||||
this.languageService.cleanupSemanticCache();
|
||||
this.languageServiceEnabled = false;
|
||||
this.builderState = undefined;
|
||||
this.resolutionCache.closeTypeRootsWatch();
|
||||
this.projectService.onUpdateLanguageServiceStateForProject(this, /*languageServiceEnabled*/ false);
|
||||
}
|
||||
@@ -557,7 +558,7 @@ namespace ts.server {
|
||||
this.rootFilesMap = undefined;
|
||||
this.externalFiles = undefined;
|
||||
this.program = undefined;
|
||||
this.builder = undefined;
|
||||
this.builderState = undefined;
|
||||
this.resolutionCache.clear();
|
||||
this.resolutionCache = undefined;
|
||||
this.cachedUnresolvedImportsPerFile = undefined;
|
||||
@@ -813,15 +814,9 @@ namespace ts.server {
|
||||
if (this.setTypings(cachedTypings)) {
|
||||
hasChanges = this.updateGraphWorker() || hasChanges;
|
||||
}
|
||||
if (this.builder) {
|
||||
this.builder.updateProgram(this.program);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.lastCachedUnresolvedImportsList = undefined;
|
||||
if (this.builder) {
|
||||
this.builder.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (hasChanges) {
|
||||
@@ -921,7 +916,7 @@ namespace ts.server {
|
||||
missingFilePath,
|
||||
(fileName, eventKind) => {
|
||||
if (this.projectKind === ProjectKind.Configured) {
|
||||
(this.directoryStructureHost as CachedDirectoryStructureHost).addOrDeleteFile(fileName, missingFilePath, eventKind);
|
||||
this.getCachedDirectoryStructureHost().addOrDeleteFile(fileName, missingFilePath, eventKind);
|
||||
}
|
||||
|
||||
if (eventKind === FileWatcherEventKind.Created && this.missingFilesMap.has(missingFilePath)) {
|
||||
|
||||
+1
-15
@@ -102,8 +102,6 @@ namespace ts.server.protocol {
|
||||
GetCodeFixes = "getCodeFixes",
|
||||
/* @internal */
|
||||
GetCodeFixesFull = "getCodeFixes-full",
|
||||
// TODO: GH#20538
|
||||
/* @internal */
|
||||
GetCombinedCodeFix = "getCombinedCodeFix",
|
||||
/* @internal */
|
||||
GetCombinedCodeFixFull = "getCombinedCodeFix-full",
|
||||
@@ -557,15 +555,11 @@ namespace ts.server.protocol {
|
||||
arguments: CodeFixRequestArgs;
|
||||
}
|
||||
|
||||
// TODO: GH#20538
|
||||
/* @internal */
|
||||
export interface GetCombinedCodeFixRequest extends Request {
|
||||
command: CommandTypes.GetCombinedCodeFix;
|
||||
arguments: GetCombinedCodeFixRequestArgs;
|
||||
}
|
||||
|
||||
// TODO: GH#20538
|
||||
/* @internal */
|
||||
export interface GetCombinedCodeFixResponse extends Response {
|
||||
body: CombinedCodeActions;
|
||||
}
|
||||
@@ -622,15 +616,11 @@ namespace ts.server.protocol {
|
||||
errorCodes?: ReadonlyArray<number>;
|
||||
}
|
||||
|
||||
// TODO: GH#20538
|
||||
/* @internal */
|
||||
export interface GetCombinedCodeFixRequestArgs {
|
||||
scope: GetCombinedCodeFixScope;
|
||||
fixId: {};
|
||||
}
|
||||
|
||||
// TODO: GH#20538
|
||||
/* @internal */
|
||||
export interface GetCombinedCodeFixScope {
|
||||
type: "file";
|
||||
args: FileRequestArgs;
|
||||
@@ -1619,7 +1609,7 @@ namespace ts.server.protocol {
|
||||
|
||||
export interface CodeFixResponse extends Response {
|
||||
/** The code actions that are available */
|
||||
body?: CodeAction[]; // TODO: GH#20538 CodeFixAction[]
|
||||
body?: CodeFixAction[];
|
||||
}
|
||||
|
||||
export interface CodeAction {
|
||||
@@ -1631,15 +1621,11 @@ namespace ts.server.protocol {
|
||||
commands?: {}[];
|
||||
}
|
||||
|
||||
// TODO: GH#20538
|
||||
/* @internal */
|
||||
export interface CombinedCodeActions {
|
||||
changes: ReadonlyArray<FileCodeEdits>;
|
||||
commands?: ReadonlyArray<{}>;
|
||||
}
|
||||
|
||||
// TODO: GH#20538
|
||||
/* @internal */
|
||||
export interface CodeFixAction extends CodeAction {
|
||||
/**
|
||||
* If present, one may call 'getCombinedCodeFix' with this fixId.
|
||||
|
||||
@@ -196,7 +196,7 @@ namespace ts.server {
|
||||
|
||||
/*@internal*/
|
||||
export function isDynamicFileName(fileName: NormalizedPath) {
|
||||
return getBaseFileName(fileName)[0] === "^";
|
||||
return fileName[0] === "^" || getBaseFileName(fileName)[0] === "^";
|
||||
}
|
||||
|
||||
export class ScriptInfo {
|
||||
@@ -213,6 +213,10 @@ namespace ts.server {
|
||||
/*@internal*/
|
||||
readonly isDynamic: boolean;
|
||||
|
||||
/*@internal*/
|
||||
/** Set to real path if path is different from info.path */
|
||||
private realpath: Path | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly host: ServerHost,
|
||||
readonly fileName: NormalizedPath,
|
||||
@@ -224,6 +228,7 @@ namespace ts.server {
|
||||
this.textStorage = new TextStorage(host, fileName);
|
||||
if (hasMixedContent || this.isDynamic) {
|
||||
this.textStorage.reload("");
|
||||
this.realpath = this.path;
|
||||
}
|
||||
this.scriptKind = scriptKind
|
||||
? scriptKind
|
||||
@@ -264,6 +269,30 @@ namespace ts.server {
|
||||
return this.textStorage.getSnapshot();
|
||||
}
|
||||
|
||||
private ensureRealPath() {
|
||||
if (this.realpath === undefined) {
|
||||
// Default is just the path
|
||||
this.realpath = this.path;
|
||||
if (this.host.realpath) {
|
||||
Debug.assert(!!this.containingProjects.length);
|
||||
const project = this.containingProjects[0];
|
||||
const realpath = this.host.realpath(this.path);
|
||||
if (realpath) {
|
||||
this.realpath = project.toPath(realpath);
|
||||
// If it is different from this.path, add to the map
|
||||
if (this.realpath !== this.path) {
|
||||
project.projectService.realpathToScriptInfos.add(this.realpath, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getRealpathIfDifferent(): Path | undefined {
|
||||
return this.realpath && this.realpath !== this.path ? this.realpath : undefined;
|
||||
}
|
||||
|
||||
getFormatCodeSettings() {
|
||||
return this.formatCodeSettings;
|
||||
}
|
||||
@@ -272,6 +301,9 @@ namespace ts.server {
|
||||
const isNew = !this.isAttached(project);
|
||||
if (isNew) {
|
||||
this.containingProjects.push(project);
|
||||
if (!project.getCompilerOptions().preserveSymlinks) {
|
||||
this.ensureRealPath();
|
||||
}
|
||||
}
|
||||
return isNew;
|
||||
}
|
||||
@@ -313,7 +345,7 @@ namespace ts.server {
|
||||
detachAllProjects() {
|
||||
for (const p of this.containingProjects) {
|
||||
if (p.projectKind === ProjectKind.Configured) {
|
||||
(p.directoryStructureHost as CachedDirectoryStructureHost).addOrDeleteFile(this.fileName, this.path, FileWatcherEventKind.Deleted);
|
||||
p.getCachedDirectoryStructureHost().addOrDeleteFile(this.fileName, this.path, FileWatcherEventKind.Deleted);
|
||||
}
|
||||
const isInfoRoot = p.isRoot(this);
|
||||
// detach is unnecessary since we'll clean the list of containing projects anyways
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace ts.server {
|
||||
const os: {
|
||||
homedir?(): string;
|
||||
tmpdir(): string;
|
||||
platform(): string;
|
||||
} = require("os");
|
||||
|
||||
interface NodeSocket {
|
||||
@@ -824,8 +825,9 @@ namespace ts.server {
|
||||
const logger = createLogger();
|
||||
|
||||
const sys = <ServerHost>ts.sys;
|
||||
const nodeVersion = getNodeMajorVersion();
|
||||
// use watchGuard process on Windows when node version is 4 or later
|
||||
const useWatchGuard = process.platform === "win32" && getNodeMajorVersion() >= 4;
|
||||
const useWatchGuard = process.platform === "win32" && nodeVersion >= 4;
|
||||
const originalWatchDirectory: ServerHost["watchDirectory"] = sys.watchDirectory.bind(sys);
|
||||
const noopWatcher: FileWatcher = { close: noop };
|
||||
// This is the function that catches the exceptions when watching directory, and yet lets project service continue to function
|
||||
@@ -980,8 +982,9 @@ namespace ts.server {
|
||||
};
|
||||
|
||||
logger.info(`Starting TS Server`);
|
||||
logger.info(`Version: ${versionMajorMinor}`);
|
||||
logger.info(`Version: ${version}`);
|
||||
logger.info(`Arguments: ${process.argv.join(" ")}`);
|
||||
logger.info(`Platform: ${os.platform()} NodeVersion: ${nodeVersion} CaseSensitive: ${sys.useCaseSensitiveFileNames}`);
|
||||
|
||||
const ioSession = new IOSession(options);
|
||||
process.on("uncaughtException", err => {
|
||||
|
||||
+79
-25
@@ -255,6 +255,32 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
type Projects = ReadonlyArray<Project> | {
|
||||
projects: ReadonlyArray<Project>;
|
||||
symLinkedProjects: MultiMap<Project>;
|
||||
};
|
||||
|
||||
function isProjectsArray(projects: Projects): projects is ReadonlyArray<Project> {
|
||||
return !!(<ReadonlyArray<Project>>projects).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project.
|
||||
*/
|
||||
function combineProjectOutput<T, U>(defaultValue: T, getValue: (path: Path) => T, projects: Projects, action: (project: Project, value: T) => ReadonlyArray<U> | U | undefined, comparer?: (a: U, b: U) => number, areEqual?: (a: U, b: U) => boolean) {
|
||||
const outputs = flatMap(isProjectsArray(projects) ? projects : projects.projects, project => action(project, defaultValue));
|
||||
if (!isProjectsArray(projects) && projects.symLinkedProjects) {
|
||||
projects.symLinkedProjects.forEach((projects, path) => {
|
||||
const value = getValue(path as Path);
|
||||
outputs.push(...flatMap(projects, project => action(project, value)));
|
||||
});
|
||||
}
|
||||
|
||||
return comparer
|
||||
? sortAndDeduplicate(outputs, comparer, areEqual)
|
||||
: deduplicate(outputs, areEqual);
|
||||
}
|
||||
|
||||
export interface SessionOptions {
|
||||
host: ServerHost;
|
||||
cancellationToken: ServerCancellationToken;
|
||||
@@ -789,8 +815,9 @@ namespace ts.server {
|
||||
return project.getLanguageService().getRenameInfo(file, position);
|
||||
}
|
||||
|
||||
private getProjects(args: protocol.FileRequestArgs) {
|
||||
let projects: Project[];
|
||||
private getProjects(args: protocol.FileRequestArgs): Projects {
|
||||
let projects: ReadonlyArray<Project>;
|
||||
let symLinkedProjects: MultiMap<Project> | undefined;
|
||||
if (args.projectFileName) {
|
||||
const project = this.getProject(args.projectFileName);
|
||||
if (project) {
|
||||
@@ -800,13 +827,14 @@ namespace ts.server {
|
||||
else {
|
||||
const scriptInfo = this.projectService.getScriptInfo(args.file);
|
||||
projects = scriptInfo.containingProjects;
|
||||
symLinkedProjects = this.projectService.getSymlinkedProjects(scriptInfo);
|
||||
}
|
||||
// filter handles case when 'projects' is undefined
|
||||
projects = filter(projects, p => p.languageServiceEnabled);
|
||||
if (!projects || !projects.length) {
|
||||
if ((!projects || !projects.length) && !symLinkedProjects) {
|
||||
return Errors.ThrowNoProject();
|
||||
}
|
||||
return projects;
|
||||
return symLinkedProjects ? { projects, symLinkedProjects } : projects;
|
||||
}
|
||||
|
||||
private getDefaultProject(args: protocol.FileRequestArgs) {
|
||||
@@ -841,8 +869,10 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
const fileSpans = combineProjectOutput(
|
||||
file,
|
||||
path => this.projectService.getScriptInfoForPath(path).fileName,
|
||||
projects,
|
||||
(project: Project) => {
|
||||
(project, file) => {
|
||||
const renameLocations = project.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments);
|
||||
if (!renameLocations) {
|
||||
return emptyArray;
|
||||
@@ -881,8 +911,10 @@ namespace ts.server {
|
||||
}
|
||||
else {
|
||||
return combineProjectOutput(
|
||||
file,
|
||||
path => this.projectService.getScriptInfoForPath(path).fileName,
|
||||
projects,
|
||||
p => p.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments),
|
||||
(p, file) => p.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments),
|
||||
/*comparer*/ undefined,
|
||||
renameLocationIsEqualTo
|
||||
);
|
||||
@@ -938,9 +970,11 @@ namespace ts.server {
|
||||
const nameSpan = nameInfo.textSpan;
|
||||
const nameColStart = scriptInfo.positionToLineOffset(nameSpan.start).offset;
|
||||
const nameText = scriptInfo.getSnapshot().getText(nameSpan.start, textSpanEnd(nameSpan));
|
||||
const refs = combineProjectOutput<protocol.ReferencesResponseItem>(
|
||||
const refs = combineProjectOutput<NormalizedPath, protocol.ReferencesResponseItem>(
|
||||
file,
|
||||
path => this.projectService.getScriptInfoForPath(path).fileName,
|
||||
projects,
|
||||
(project: Project) => {
|
||||
(project, file) => {
|
||||
const references = project.getLanguageService().getReferencesAtPosition(file, position);
|
||||
if (!references) {
|
||||
return emptyArray;
|
||||
@@ -974,8 +1008,10 @@ namespace ts.server {
|
||||
}
|
||||
else {
|
||||
return combineProjectOutput(
|
||||
file,
|
||||
path => this.projectService.getScriptInfoForPath(path).fileName,
|
||||
projects,
|
||||
project => project.getLanguageService().findReferences(file, position),
|
||||
(project, file) => project.getLanguageService().findReferences(file, position),
|
||||
/*comparer*/ undefined,
|
||||
equateValues
|
||||
);
|
||||
@@ -1240,20 +1276,25 @@ namespace ts.server {
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
const result: protocol.CompileOnSaveAffectedFileListSingleProject[] = [];
|
||||
|
||||
// if specified a project, we only return affected file list in this project
|
||||
const projectsToSearch = args.projectFileName ? [this.projectService.findProject(args.projectFileName)] : info.containingProjects;
|
||||
for (const project of projectsToSearch) {
|
||||
if (project.compileOnSaveEnabled && project.languageServiceEnabled && !project.getCompilationSettings().noEmit) {
|
||||
result.push({
|
||||
projectFileName: project.getProjectName(),
|
||||
fileNames: project.getCompileOnSaveAffectedFileList(info),
|
||||
projectUsesOutFile: !!project.getCompilationSettings().outFile || !!project.getCompilationSettings().out
|
||||
});
|
||||
const projects = args.projectFileName ? [this.projectService.findProject(args.projectFileName)] : info.containingProjects;
|
||||
const symLinkedProjects = !args.projectFileName && this.projectService.getSymlinkedProjects(info);
|
||||
return combineProjectOutput(
|
||||
info,
|
||||
path => this.projectService.getScriptInfoForPath(path),
|
||||
symLinkedProjects ? { projects, symLinkedProjects } : projects,
|
||||
(project, info) => {
|
||||
let result: protocol.CompileOnSaveAffectedFileListSingleProject;
|
||||
if (project.compileOnSaveEnabled && project.languageServiceEnabled && !project.getCompilationSettings().noEmit) {
|
||||
result = {
|
||||
projectFileName: project.getProjectName(),
|
||||
fileNames: project.getCompileOnSaveAffectedFileList(info),
|
||||
projectUsesOutFile: !!project.getCompilationSettings().outFile || !!project.getCompilationSettings().out
|
||||
};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
);
|
||||
}
|
||||
|
||||
private emitFile(args: protocol.CompileOnSaveEmitFileRequestArgs) {
|
||||
@@ -1406,8 +1447,14 @@ namespace ts.server {
|
||||
const fileName = args.currentFileOnly ? args.file && normalizeSlashes(args.file) : undefined;
|
||||
if (simplifiedResult) {
|
||||
return combineProjectOutput(
|
||||
fileName,
|
||||
() => undefined,
|
||||
projects,
|
||||
project => {
|
||||
(project, file) => {
|
||||
if (fileName && !file) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject());
|
||||
if (!navItems) {
|
||||
return emptyArray;
|
||||
@@ -1443,8 +1490,15 @@ namespace ts.server {
|
||||
}
|
||||
else {
|
||||
return combineProjectOutput(
|
||||
fileName,
|
||||
() => undefined,
|
||||
projects,
|
||||
project => project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject()),
|
||||
(project, file) => {
|
||||
if (fileName && !file) {
|
||||
return undefined;
|
||||
}
|
||||
return project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject());
|
||||
},
|
||||
/*comparer*/ undefined,
|
||||
navigateToItemIsEqualTo);
|
||||
}
|
||||
@@ -1611,9 +1665,9 @@ namespace ts.server {
|
||||
return { startPosition, endPosition };
|
||||
}
|
||||
|
||||
private mapCodeAction(project: Project, { description, changes: unmappedChanges, commands }: CodeAction): protocol.CodeAction {
|
||||
private mapCodeAction(project: Project, { description, changes: unmappedChanges, commands, fixId }: CodeFixAction): protocol.CodeFixAction {
|
||||
const changes = unmappedChanges.map(change => this.mapTextChangesToCodeEditsUsingScriptinfo(change, project.getScriptInfoForNormalizedPath(toNormalizedPath(change.fileName))));
|
||||
return { description, changes, commands };
|
||||
return { description, changes, commands, fixId };
|
||||
}
|
||||
|
||||
private mapTextChangesToCodeEdits(project: Project, textChanges: ReadonlyArray<FileTextChanges>): protocol.FileCodeEdits[] {
|
||||
|
||||
+3
-1
@@ -11,6 +11,8 @@ declare namespace ts.server {
|
||||
|
||||
type RequireResult = { module: {}, error: undefined } | { module: undefined, error: { stack?: string, message?: string } };
|
||||
export interface ServerHost extends System {
|
||||
watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
clearTimeout(timeoutId: any): void;
|
||||
setImmediate(callback: (...args: any[]) => void, ...args: any[]): any;
|
||||
@@ -129,4 +131,4 @@ declare namespace ts.server {
|
||||
createDirectory(path: string): void;
|
||||
watchFile?(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+38
-29
@@ -619,37 +619,46 @@ namespace ts {
|
||||
return start;
|
||||
}
|
||||
|
||||
// Don't bother with newlines/whitespace.
|
||||
if (kind === SyntaxKind.NewLineTrivia || kind === SyntaxKind.WhitespaceTrivia) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only bother with the trivia if it at least intersects the span of interest.
|
||||
if (isComment(kind)) {
|
||||
classifyComment(token, kind, start, width);
|
||||
|
||||
// Classifying a comment might cause us to reuse the trivia scanner
|
||||
// (because of jsdoc comments). So after we classify the comment make
|
||||
// sure we set the scanner position back to where it needs to be.
|
||||
triviaScanner.setTextPos(end);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (kind === SyntaxKind.ConflictMarkerTrivia) {
|
||||
const text = sourceFile.text;
|
||||
const ch = text.charCodeAt(start);
|
||||
|
||||
// for the <<<<<<< and >>>>>>> markers, we just add them in as comments
|
||||
// in the classification stream.
|
||||
if (ch === CharacterCodes.lessThan || ch === CharacterCodes.greaterThan) {
|
||||
pushClassification(start, width, ClassificationType.comment);
|
||||
switch (kind) {
|
||||
case SyntaxKind.NewLineTrivia:
|
||||
case SyntaxKind.WhitespaceTrivia:
|
||||
// Don't bother with newlines/whitespace.
|
||||
continue;
|
||||
}
|
||||
|
||||
// for the ||||||| and ======== markers, add a comment for the first line,
|
||||
// and then lex all subsequent lines up until the end of the conflict marker.
|
||||
Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals);
|
||||
classifyDisabledMergeCode(text, start, end);
|
||||
case SyntaxKind.SingleLineCommentTrivia:
|
||||
case SyntaxKind.MultiLineCommentTrivia:
|
||||
// Only bother with the trivia if it at least intersects the span of interest.
|
||||
classifyComment(token, kind, start, width);
|
||||
|
||||
// Classifying a comment might cause us to reuse the trivia scanner
|
||||
// (because of jsdoc comments). So after we classify the comment make
|
||||
// sure we set the scanner position back to where it needs to be.
|
||||
triviaScanner.setTextPos(end);
|
||||
continue;
|
||||
|
||||
case SyntaxKind.ConflictMarkerTrivia:
|
||||
const text = sourceFile.text;
|
||||
const ch = text.charCodeAt(start);
|
||||
|
||||
// for the <<<<<<< and >>>>>>> markers, we just add them in as comments
|
||||
// in the classification stream.
|
||||
if (ch === CharacterCodes.lessThan || ch === CharacterCodes.greaterThan) {
|
||||
pushClassification(start, width, ClassificationType.comment);
|
||||
continue;
|
||||
}
|
||||
|
||||
// for the ||||||| and ======== markers, add a comment for the first line,
|
||||
// and then lex all subsequent lines up until the end of the conflict marker.
|
||||
Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals);
|
||||
classifyDisabledMergeCode(text, start, end);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ShebangTrivia:
|
||||
// TODO: Maybe we should classify these.
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.assertNever(kind);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ namespace ts {
|
||||
export interface CodeFixContextBase extends textChanges.TextChangesContext {
|
||||
sourceFile: SourceFile;
|
||||
program: Program;
|
||||
host: LanguageServiceHost;
|
||||
cancellationToken: CancellationToken;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,49 +1,53 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
const fixId = "disableJsDiagnostics";
|
||||
const errorCodes = mapDefined(Object.keys(Diagnostics), key => {
|
||||
const diag = (Diagnostics as MapLike<DiagnosticMessage>)[key];
|
||||
const errorCodes = mapDefined(Object.keys(Diagnostics) as ReadonlyArray<keyof typeof Diagnostics>, key => {
|
||||
const diag = Diagnostics[key];
|
||||
return diag.category === DiagnosticCategory.Error ? diag.code : undefined;
|
||||
});
|
||||
|
||||
registerCodeFix({
|
||||
errorCodes,
|
||||
getCodeActions(context) {
|
||||
const { sourceFile, program, newLineCharacter, span } = context;
|
||||
const { sourceFile, program, span } = context;
|
||||
|
||||
if (!isInJavaScriptFile(sourceFile) || !isCheckJsEnabledForFile(sourceFile, program.getCompilerOptions())) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const newLineCharacter = getNewLineOrDefaultFromHost(context.host, context.formatContext.options);
|
||||
|
||||
return [{
|
||||
description: getLocaleSpecificMessage(Diagnostics.Ignore_this_error_message),
|
||||
changes: [createFileTextChanges(sourceFile.fileName, [getIgnoreCommentLocationForLocation(sourceFile, span.start, newLineCharacter)])],
|
||||
changes: [createFileTextChanges(sourceFile.fileName, [getIgnoreCommentLocationForLocation(sourceFile, span.start, newLineCharacter).change])],
|
||||
fixId,
|
||||
},
|
||||
{
|
||||
description: getLocaleSpecificMessage(Diagnostics.Disable_checking_for_this_file),
|
||||
changes: [createFileTextChanges(sourceFile.fileName, [{
|
||||
span: {
|
||||
start: sourceFile.checkJsDirective ? sourceFile.checkJsDirective.pos : 0,
|
||||
length: sourceFile.checkJsDirective ? sourceFile.checkJsDirective.end - sourceFile.checkJsDirective.pos : 0
|
||||
},
|
||||
newText: `// @ts-nocheck${newLineCharacter}`
|
||||
}])],
|
||||
changes: [createFileTextChanges(sourceFile.fileName, [
|
||||
createTextChange(sourceFile.checkJsDirective ? createTextSpanFromBounds(sourceFile.checkJsDirective.pos, sourceFile.checkJsDirective.end) : createTextSpan(0, 0), `// @ts-nocheck${newLineCharacter}`),
|
||||
])],
|
||||
// fixId unnecessary because adding `// @ts-nocheck` even once will ignore every error in the file.
|
||||
fixId: undefined,
|
||||
}];
|
||||
},
|
||||
fixIds: [fixId], // No point applying as a group, doing it once will fix all errors
|
||||
getAllCodeActions: context => codeFixAllWithTextChanges(context, errorCodes, (changes, err) => {
|
||||
if (err.start !== undefined) {
|
||||
changes.push(getIgnoreCommentLocationForLocation(err.file!, err.start, context.newLineCharacter));
|
||||
}
|
||||
}),
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => {
|
||||
const seenLines = createMap<true>(); // Only need to add `// @ts-ignore` for a line once.
|
||||
return codeFixAllWithTextChanges(context, errorCodes, (changes, err) => {
|
||||
if (err.start !== undefined) {
|
||||
const { lineNumber, change } = getIgnoreCommentLocationForLocation(err.file!, err.start, getNewLineOrDefaultFromHost(context.host, context.formatContext.options));
|
||||
if (addToSeen(seenLines, lineNumber)) {
|
||||
changes.push(change);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
function getIgnoreCommentLocationForLocation(sourceFile: SourceFile, position: number, newLineCharacter: string): TextChange {
|
||||
const { line } = getLineAndCharacterOfPosition(sourceFile, position);
|
||||
const lineStartPosition = getStartPositionOfLine(line, sourceFile);
|
||||
function getIgnoreCommentLocationForLocation(sourceFile: SourceFile, position: number, newLineCharacter: string): { lineNumber: number, change: TextChange } {
|
||||
const { line: lineNumber } = getLineAndCharacterOfPosition(sourceFile, position);
|
||||
const lineStartPosition = getStartPositionOfLine(lineNumber, sourceFile);
|
||||
const startPosition = getFirstNonSpaceCharacterPosition(sourceFile.text, lineStartPosition);
|
||||
|
||||
// First try to see if we can put the '// @ts-ignore' on the previous line.
|
||||
@@ -52,19 +56,13 @@ namespace ts.codefix {
|
||||
// if so, we do not want to separate the node from its comment if we can.
|
||||
if (!isInComment(sourceFile, startPosition) && !isInString(sourceFile, startPosition) && !isInTemplateString(sourceFile, startPosition)) {
|
||||
const token = getTouchingToken(sourceFile, startPosition, /*includeJsDocComment*/ false);
|
||||
const tokenLeadingCommnets = getLeadingCommentRangesOfNode(token, sourceFile);
|
||||
if (!tokenLeadingCommnets || !tokenLeadingCommnets.length || tokenLeadingCommnets[0].pos >= startPosition) {
|
||||
return {
|
||||
span: { start: startPosition, length: 0 },
|
||||
newText: `// @ts-ignore${newLineCharacter}`
|
||||
};
|
||||
const tokenLeadingComments = getLeadingCommentRangesOfNode(token, sourceFile);
|
||||
if (!tokenLeadingComments || !tokenLeadingComments.length || tokenLeadingComments[0].pos >= startPosition) {
|
||||
return { lineNumber, change: createTextChangeFromStartLength(startPosition, 0, `// @ts-ignore${newLineCharacter}`) };
|
||||
}
|
||||
}
|
||||
|
||||
// If all fails, add an extra new line immediately before the error span.
|
||||
return {
|
||||
span: { start: position, length: 0 },
|
||||
newText: `${position === startPosition ? "" : newLineCharacter}// @ts-ignore${newLineCharacter}`
|
||||
};
|
||||
return { lineNumber, change: createTextChangeFromStartLength(position, 0, `${position === startPosition ? "" : newLineCharacter}// @ts-ignore${newLineCharacter}`) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ namespace ts.codefix {
|
||||
return typeNode || createKeywordTypeNode(SyntaxKind.AnyKeyword);
|
||||
}
|
||||
|
||||
function createAddPropertyDeclarationAction(context: textChanges.TextChangesContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, makeStatic: boolean, tokenName: string, typeNode: TypeNode): CodeFixAction {
|
||||
function createAddPropertyDeclarationAction(context: CodeFixContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, makeStatic: boolean, tokenName: string, typeNode: TypeNode): CodeFixAction {
|
||||
const description = formatStringFromArgs(getLocaleSpecificMessage(makeStatic ? Diagnostics.Declare_static_property_0 : Diagnostics.Declare_property_0), [tokenName]);
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addPropertyDeclaration(t, classDeclarationSourceFile, classDeclaration, tokenName, typeNode, makeStatic));
|
||||
return { description, changes, fixId };
|
||||
@@ -159,7 +159,7 @@ namespace ts.codefix {
|
||||
changeTracker.insertNodeAtClassStart(classDeclarationSourceFile, classDeclaration, property);
|
||||
}
|
||||
|
||||
function createAddIndexSignatureAction(context: textChanges.TextChangesContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, tokenName: string, typeNode: TypeNode): CodeFixAction {
|
||||
function createAddIndexSignatureAction(context: CodeFixContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, tokenName: string, typeNode: TypeNode): CodeFixAction {
|
||||
// Index signatures cannot have the static modifier.
|
||||
const stringTypeNode = createKeywordTypeNode(SyntaxKind.StringKeyword);
|
||||
const indexingParameter = createParameter(
|
||||
@@ -181,7 +181,7 @@ namespace ts.codefix {
|
||||
return { description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_property_0), [tokenName]), changes, fixId: undefined };
|
||||
}
|
||||
|
||||
function getActionForMethodDeclaration(context: textChanges.TextChangesContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, token: Identifier, callExpression: CallExpression, makeStatic: boolean, inJs: boolean): CodeFixAction | undefined {
|
||||
function getActionForMethodDeclaration(context: CodeFixContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, token: Identifier, callExpression: CallExpression, makeStatic: boolean, inJs: boolean): CodeFixAction | undefined {
|
||||
const description = formatStringFromArgs(getLocaleSpecificMessage(makeStatic ? Diagnostics.Declare_static_method_0 : Diagnostics.Declare_method_0), [token.text]);
|
||||
const changes = textChanges.ChangeTracker.with(context, t => addMethodDeclaration(t, classDeclarationSourceFile, classDeclaration, token, callExpression, makeStatic, inJs));
|
||||
return { description, changes, fixId };
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
function createChange(declaration: TypeNode, sourceFile: SourceFile, newText: string): TextChange {
|
||||
return { span: createTextSpanFromBounds(declaration.getStart(sourceFile), declaration.getEnd()), newText };
|
||||
return createTextChange(createTextSpanFromNode(declaration, sourceFile), newText);
|
||||
}
|
||||
|
||||
function typeString(type: Type, checker: TypeChecker): string {
|
||||
|
||||
@@ -121,9 +121,26 @@ namespace ts.codefix {
|
||||
break;
|
||||
|
||||
case SyntaxKind.Parameter:
|
||||
const functionDeclaration = <FunctionDeclaration>parent.parent;
|
||||
if (functionDeclaration.parameters.length === 1) {
|
||||
changes.deleteNode(sourceFile, parent);
|
||||
const oldFunction = parent.parent;
|
||||
if (isArrowFunction(oldFunction) && oldFunction.parameters.length === 1) {
|
||||
// Lambdas with exactly one parameter are special because, after removal, there
|
||||
// must be an empty parameter list (i.e. `()`) and this won't necessarily be the
|
||||
// case if the parameter is simply removed (e.g. in `x => 1`).
|
||||
const newFunction = updateArrowFunction(
|
||||
oldFunction,
|
||||
oldFunction.modifiers,
|
||||
oldFunction.typeParameters,
|
||||
/*parameters*/ undefined,
|
||||
oldFunction.type,
|
||||
oldFunction.equalsGreaterThanToken,
|
||||
oldFunction.body);
|
||||
|
||||
// Drop leading and trailing trivia of the new function because we're only going
|
||||
// to replace the span (vs the full span) of the old function - the old leading
|
||||
// and trailing trivia will remain.
|
||||
suppressLeadingAndTrailingTrivia(newFunction);
|
||||
|
||||
changes.replaceRange(sourceFile, { pos: oldFunction.getStart(), end: oldFunction.end }, newFunction);
|
||||
}
|
||||
else {
|
||||
changes.deleteNodeInList(sourceFile, parent);
|
||||
|
||||
@@ -29,12 +29,8 @@ namespace ts.codefix {
|
||||
symbolName: string;
|
||||
}
|
||||
|
||||
interface SymbolAndTokenContext extends SymbolContext {
|
||||
interface ImportCodeFixContext extends SymbolContext {
|
||||
symbolToken: Identifier | undefined;
|
||||
}
|
||||
|
||||
interface ImportCodeFixContext extends SymbolAndTokenContext {
|
||||
host: LanguageServiceHost;
|
||||
program: Program;
|
||||
checker: TypeChecker;
|
||||
compilerOptions: CompilerOptions;
|
||||
@@ -173,7 +169,6 @@ namespace ts.codefix {
|
||||
const symbolToken = cast(getTokenAtPosition(context.sourceFile, context.span.start, /*includeJsDocComment*/ false), isIdentifier);
|
||||
return {
|
||||
host: context.host,
|
||||
newLineCharacter: context.newLineCharacter,
|
||||
formatContext: context.formatContext,
|
||||
sourceFile: context.sourceFile,
|
||||
program,
|
||||
@@ -395,7 +390,7 @@ namespace ts.codefix {
|
||||
In this case we should prefer using the relative path "../a" instead of the baseUrl path "foo/a".
|
||||
*/
|
||||
const pathFromSourceToBaseUrl = getRelativePath(baseUrl, sourceDirectory, getCanonicalFileName);
|
||||
const relativeFirst = getRelativePathNParents(pathFromSourceToBaseUrl) < getRelativePathNParents(relativePath);
|
||||
const relativeFirst = getRelativePathNParents(relativePath) < getRelativePathNParents(pathFromSourceToBaseUrl);
|
||||
return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath];
|
||||
}));
|
||||
// Only return results for the re-export with the shortest possible path (and also give the other path even if that's long.)
|
||||
@@ -472,7 +467,7 @@ namespace ts.codefix {
|
||||
addJsExtension: boolean,
|
||||
): string | undefined {
|
||||
const roots = getEffectiveTypeRoots(options, host);
|
||||
return roots && firstDefined(roots, unNormalizedTypeRoot => {
|
||||
return firstDefined(roots, unNormalizedTypeRoot => {
|
||||
const typeRoot = toPath(unNormalizedTypeRoot, /*basePath*/ undefined, getCanonicalFileName);
|
||||
if (startsWith(moduleFileName, typeRoot)) {
|
||||
return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), options, addJsExtension);
|
||||
|
||||
@@ -191,7 +191,7 @@ namespace ts.codefix {
|
||||
|
||||
function makeChange(declaration: Declaration, start: number, type: Type | undefined, program: Program): TextChange | undefined {
|
||||
const typeString = type && typeToString(type, declaration, program.getTypeChecker());
|
||||
return typeString === undefined ? undefined : { span: createTextSpan(start, 0), newText: `: ${typeString}` };
|
||||
return typeString === undefined ? undefined : createTextChangeFromStartLength(start, 0, `: ${typeString}`);
|
||||
}
|
||||
|
||||
function getReferences(token: PropertyName | Token<SyntaxKind.ConstructorKeyword>, sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): Identifier[] {
|
||||
|
||||
+135
-70
@@ -4,7 +4,9 @@
|
||||
namespace ts.Completions {
|
||||
export type Log = (message: string) => void;
|
||||
|
||||
interface SymbolOriginInfo {
|
||||
type SymbolOriginInfo = { type: "this-type" } | SymbolOriginInfoExport;
|
||||
interface SymbolOriginInfoExport {
|
||||
type: "export";
|
||||
moduleSymbol: Symbol;
|
||||
isDefaultExport: boolean;
|
||||
}
|
||||
@@ -18,6 +20,8 @@ namespace ts.Completions {
|
||||
None,
|
||||
ClassElementKeywords, // Keywords at class keyword
|
||||
ConstructorParameterKeywords, // Keywords at constructor parameter
|
||||
FunctionLikeBodyKeywords, // Keywords at function like body
|
||||
TypeKeywords,
|
||||
}
|
||||
|
||||
export function getCompletionsAtPosition(
|
||||
@@ -74,7 +78,7 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
function completionInfoFromData(sourceFile: SourceFile, typeChecker: TypeChecker, compilerOptions: CompilerOptions, log: Log, completionData: CompletionData, includeInsertTextCompletions: boolean): CompletionInfo {
|
||||
const { symbols, completionKind, isNewIdentifierLocation, location, propertyAccessToConvert, keywordFilters, symbolToOriginInfoMap, recommendedCompletion } = completionData;
|
||||
const { symbols, completionKind, isNewIdentifierLocation, location, propertyAccessToConvert, keywordFilters, symbolToOriginInfoMap, recommendedCompletion, isJsxInitializer } = completionData;
|
||||
|
||||
if (sourceFile.languageVariant === LanguageVariant.JSX && location && location.parent && isJsxClosingElement(location.parent)) {
|
||||
// In the TypeScript JSX element, if such element is not defined. When users query for completion at closing tag,
|
||||
@@ -95,7 +99,7 @@ namespace ts.Completions {
|
||||
const entries: CompletionEntry[] = [];
|
||||
|
||||
if (isSourceFileJavaScript(sourceFile)) {
|
||||
const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, sourceFile, typeChecker, compilerOptions.target, log, completionKind, includeInsertTextCompletions, propertyAccessToConvert, recommendedCompletion, symbolToOriginInfoMap);
|
||||
const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, sourceFile, typeChecker, compilerOptions.target, log, completionKind, includeInsertTextCompletions, propertyAccessToConvert, isJsxInitializer, recommendedCompletion, symbolToOriginInfoMap);
|
||||
getJavaScriptCompletionEntries(sourceFile, location.pos, uniqueNames, compilerOptions.target, entries);
|
||||
}
|
||||
else {
|
||||
@@ -103,7 +107,7 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getCompletionEntriesFromSymbols(symbols, entries, location, sourceFile, typeChecker, compilerOptions.target, log, completionKind, includeInsertTextCompletions, propertyAccessToConvert, recommendedCompletion, symbolToOriginInfoMap);
|
||||
getCompletionEntriesFromSymbols(symbols, entries, location, sourceFile, typeChecker, compilerOptions.target, log, completionKind, includeInsertTextCompletions, propertyAccessToConvert, isJsxInitializer, recommendedCompletion, symbolToOriginInfoMap);
|
||||
}
|
||||
|
||||
// TODO add filter for keyword based on type/value/namespace and also location
|
||||
@@ -163,6 +167,7 @@ namespace ts.Completions {
|
||||
origin: SymbolOriginInfo | undefined,
|
||||
recommendedCompletion: Symbol | undefined,
|
||||
propertyAccessToConvert: PropertyAccessExpression | undefined,
|
||||
isJsxInitializer: boolean,
|
||||
includeInsertTextCompletions: boolean,
|
||||
): CompletionEntry | undefined {
|
||||
const info = getCompletionEntryDisplayNameForSymbol(symbol, target, origin, kind);
|
||||
@@ -170,8 +175,26 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
const { name, needsConvertPropertyAccess } = info;
|
||||
Debug.assert(!(needsConvertPropertyAccess && !propertyAccessToConvert));
|
||||
if (needsConvertPropertyAccess && !includeInsertTextCompletions) {
|
||||
|
||||
let insertText: string | undefined;
|
||||
let replacementSpan: TextSpan | undefined;
|
||||
if (includeInsertTextCompletions) {
|
||||
if (origin && origin.type === "this-type") {
|
||||
insertText = needsConvertPropertyAccess ? `this["${name}"]` : `this.${name}`;
|
||||
}
|
||||
else if (needsConvertPropertyAccess) {
|
||||
// TODO: GH#20619 Use configured quote style
|
||||
insertText = `["${name}"]`;
|
||||
replacementSpan = createTextSpanFromBounds(findChildOfKind(propertyAccessToConvert!, SyntaxKind.DotToken, sourceFile)!.getStart(sourceFile), propertyAccessToConvert!.name.end);
|
||||
}
|
||||
|
||||
if (isJsxInitializer) {
|
||||
if (insertText === undefined) insertText = name;
|
||||
insertText = `{${insertText}}`;
|
||||
}
|
||||
}
|
||||
|
||||
if (insertText !== undefined && !includeInsertTextCompletions) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -189,13 +212,10 @@ namespace ts.Completions {
|
||||
kindModifiers: SymbolDisplay.getSymbolModifiers(symbol),
|
||||
sortText: "0",
|
||||
source: getSourceFromOrigin(origin),
|
||||
// TODO: GH#20619 Use configured quote style
|
||||
insertText: needsConvertPropertyAccess ? `["${name}"]` : undefined,
|
||||
replacementSpan: needsConvertPropertyAccess
|
||||
? createTextSpanFromBounds(findChildOfKind(propertyAccessToConvert, SyntaxKind.DotToken, sourceFile)!.getStart(sourceFile), propertyAccessToConvert.name.end)
|
||||
: undefined,
|
||||
hasAction: trueOrUndefined(needsConvertPropertyAccess || origin !== undefined),
|
||||
hasAction: trueOrUndefined(!!origin && origin.type === "export"),
|
||||
isRecommended: trueOrUndefined(isRecommendedCompletionMatch(symbol, recommendedCompletion, typeChecker)),
|
||||
insertText,
|
||||
replacementSpan,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -210,7 +230,7 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
function getSourceFromOrigin(origin: SymbolOriginInfo | undefined): string | undefined {
|
||||
return origin && stripQuotes(origin.moduleSymbol.name);
|
||||
return origin && origin.type === "export" ? stripQuotes(origin.moduleSymbol.name) : undefined;
|
||||
}
|
||||
|
||||
function getCompletionEntriesFromSymbols(
|
||||
@@ -224,6 +244,7 @@ namespace ts.Completions {
|
||||
kind: CompletionKind,
|
||||
includeInsertTextCompletions?: boolean,
|
||||
propertyAccessToConvert?: PropertyAccessExpression | undefined,
|
||||
isJsxInitializer?: boolean,
|
||||
recommendedCompletion?: Symbol,
|
||||
symbolToOriginInfoMap?: SymbolOriginInfoMap,
|
||||
): Map<true> {
|
||||
@@ -235,7 +256,7 @@ namespace ts.Completions {
|
||||
const uniques = createMap<true>();
|
||||
for (const symbol of symbols) {
|
||||
const origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[getSymbolId(symbol)] : undefined;
|
||||
const entry = createCompletionEntry(symbol, location, sourceFile, typeChecker, target, kind, origin, recommendedCompletion, propertyAccessToConvert, includeInsertTextCompletions);
|
||||
const entry = createCompletionEntry(symbol, location, sourceFile, typeChecker, target, kind, origin, recommendedCompletion, propertyAccessToConvert, isJsxInitializer, includeInsertTextCompletions);
|
||||
if (!entry) {
|
||||
continue;
|
||||
}
|
||||
@@ -472,6 +493,7 @@ namespace ts.Completions {
|
||||
location: Node;
|
||||
symbolToOriginInfoMap: SymbolOriginInfoMap;
|
||||
previousToken: Node;
|
||||
readonly isJsxInitializer: boolean;
|
||||
}
|
||||
function getSymbolCompletionFromEntryId(
|
||||
typeChecker: TypeChecker,
|
||||
@@ -490,7 +512,7 @@ namespace ts.Completions {
|
||||
return { type: "request", request: completionData };
|
||||
}
|
||||
|
||||
const { symbols, location, completionKind, symbolToOriginInfoMap, previousToken } = completionData;
|
||||
const { symbols, location, completionKind, symbolToOriginInfoMap, previousToken, isJsxInitializer } = completionData;
|
||||
|
||||
// Find the symbol with the matching entry name.
|
||||
// We don't need to perform character checks here because we're only comparing the
|
||||
@@ -499,12 +521,12 @@ namespace ts.Completions {
|
||||
return firstDefined<Symbol, SymbolCompletion>(symbols, (symbol): SymbolCompletion => { // TODO: Shouldn't need return type annotation (GH#12632)
|
||||
const origin = symbolToOriginInfoMap[getSymbolId(symbol)];
|
||||
const info = getCompletionEntryDisplayNameForSymbol(symbol, compilerOptions.target, origin, completionKind);
|
||||
return info && info.name === name && getSourceFromOrigin(origin) === source ? { type: "symbol" as "symbol", symbol, location, symbolToOriginInfoMap, previousToken } : undefined;
|
||||
return info && info.name === name && getSourceFromOrigin(origin) === source ? { type: "symbol" as "symbol", symbol, location, symbolToOriginInfoMap, previousToken, isJsxInitializer } : undefined;
|
||||
}) || { type: "none" };
|
||||
}
|
||||
|
||||
function getSymbolName(symbol: Symbol, origin: SymbolOriginInfo | undefined, target: ScriptTarget): string {
|
||||
return origin && origin.isDefaultExport && symbol.escapedName === InternalSymbolName.Default
|
||||
return origin && origin.type === "export" && origin.isDefaultExport && symbol.escapedName === InternalSymbolName.Default
|
||||
// Name of "export default foo;" is "foo". Name of "export default 0" is the filename converted to camelCase.
|
||||
? firstDefined(symbol.declarations, d => isExportAssignment(d) && isIdentifier(d.expression) ? d.expression.text : undefined)
|
||||
|| codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target)
|
||||
@@ -555,7 +577,7 @@ namespace ts.Completions {
|
||||
}
|
||||
case "none": {
|
||||
// Didn't find a symbol with this name. See if we can find a keyword instead.
|
||||
if (some(getKeywordCompletions(KeywordCompletionFilters.None), c => c.name === name)) {
|
||||
if (allKeywordsCompletions().some(c => c.name === name)) {
|
||||
return {
|
||||
name,
|
||||
kind: ScriptElementKind.keyword,
|
||||
@@ -590,13 +612,13 @@ namespace ts.Completions {
|
||||
allSourceFiles: ReadonlyArray<SourceFile>,
|
||||
): CodeActionsAndSourceDisplay {
|
||||
const symbolOriginInfo = symbolToOriginInfoMap[getSymbolId(symbol)];
|
||||
return symbolOriginInfo
|
||||
return symbolOriginInfo && symbolOriginInfo.type === "export"
|
||||
? getCodeActionsAndSourceDisplayForImport(symbolOriginInfo, symbol, program, checker, host, compilerOptions, sourceFile, previousToken, formatContext, getCanonicalFileName, allSourceFiles)
|
||||
: { codeActions: undefined, sourceDisplay: undefined };
|
||||
}
|
||||
|
||||
function getCodeActionsAndSourceDisplayForImport(
|
||||
symbolOriginInfo: SymbolOriginInfo,
|
||||
symbolOriginInfo: SymbolOriginInfoExport,
|
||||
symbol: Symbol,
|
||||
program: Program,
|
||||
checker: TypeChecker,
|
||||
@@ -618,7 +640,6 @@ namespace ts.Completions {
|
||||
host,
|
||||
program,
|
||||
checker,
|
||||
newLineCharacter: host.getNewLine(),
|
||||
compilerOptions,
|
||||
sourceFile,
|
||||
formatContext,
|
||||
@@ -668,11 +689,13 @@ namespace ts.Completions {
|
||||
readonly symbolToOriginInfoMap: SymbolOriginInfoMap;
|
||||
readonly recommendedCompletion: Symbol | undefined;
|
||||
readonly previousToken: Node | undefined;
|
||||
readonly isJsxInitializer: boolean;
|
||||
}
|
||||
type Request = { readonly kind: CompletionDataKind.JsDocTagName | CompletionDataKind.JsDocTag } | { readonly kind: CompletionDataKind.JsDocParameterName, tag: JSDocParameterTag };
|
||||
|
||||
const enum CompletionKind {
|
||||
ObjectPropertyDeclaration,
|
||||
/** Note that sometimes we access completions from global scope, but use "None" instead of this. See isGlobalCompletionScope. */
|
||||
Global,
|
||||
PropertyAccess,
|
||||
MemberLike,
|
||||
@@ -848,6 +871,7 @@ namespace ts.Completions {
|
||||
let isRightOfDot = false;
|
||||
let isRightOfOpenTag = false;
|
||||
let isStartingCloseTag = false;
|
||||
let isJsxInitializer = false;
|
||||
|
||||
let location = getTouchingPropertyName(sourceFile, position, insideJsDocTagTypeExpression); // TODO: GH#15853
|
||||
if (contextToken) {
|
||||
@@ -906,6 +930,10 @@ namespace ts.Completions {
|
||||
location = contextToken;
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.JsxAttribute:
|
||||
isJsxInitializer = previousToken.kind === SyntaxKind.EqualsToken;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -951,7 +979,7 @@ namespace ts.Completions {
|
||||
log("getCompletionData: Semantic work: " + (timestamp() - semanticStart));
|
||||
|
||||
const recommendedCompletion = previousToken && getRecommendedCompletion(previousToken, typeChecker);
|
||||
return { kind: CompletionDataKind.Data, symbols, completionKind, propertyAccessToConvert, isNewIdentifierLocation, location, keywordFilters, symbolToOriginInfoMap, recommendedCompletion, previousToken };
|
||||
return { kind: CompletionDataKind.Data, symbols, completionKind, propertyAccessToConvert, isNewIdentifierLocation, location, keywordFilters, symbolToOriginInfoMap, recommendedCompletion, previousToken, isJsxInitializer };
|
||||
|
||||
type JSDocTagWithTypeExpression = JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag;
|
||||
|
||||
@@ -1052,6 +1080,10 @@ namespace ts.Completions {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tryGetFunctionLikeBodyCompletionContainer(contextToken)) {
|
||||
keywordFilters = KeywordCompletionFilters.FunctionLikeBodyKeywords;
|
||||
}
|
||||
|
||||
if (classLikeContainer = tryGetClassLikeCompletionContainer(contextToken)) {
|
||||
// cursor inside class declaration
|
||||
getGetClassLikeCompletionSymbols(classLikeContainer);
|
||||
@@ -1117,6 +1149,18 @@ namespace ts.Completions {
|
||||
const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias;
|
||||
|
||||
symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings);
|
||||
|
||||
// Need to insert 'this.' before properties of `this` type, so only do that if `includeInsertTextCompletions`
|
||||
if (options.includeInsertTextCompletions && scopeNode.kind !== SyntaxKind.SourceFile) {
|
||||
const thisType = typeChecker.tryGetThisTypeAt(scopeNode);
|
||||
if (thisType) {
|
||||
for (const symbol of getPropertiesForCompletion(thisType, typeChecker, /*isForAccess*/ true)) {
|
||||
symbolToOriginInfoMap[getSymbolId(symbol)] = { type: "this-type" };
|
||||
symbols.push(symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (options.includeExternalModuleExports) {
|
||||
getSymbolsFromOtherSourceFileExports(symbols, previousToken && isIdentifier(previousToken) ? previousToken.text : "", target);
|
||||
}
|
||||
@@ -1138,6 +1182,9 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
function filterGlobalCompletion(symbols: Symbol[]): void {
|
||||
const isTypeCompletion = insideJsDocTagTypeExpression || !isContextTokenValueLocation(contextToken) && (isPartOfTypeNode(location) || isContextTokenTypeLocation(contextToken));
|
||||
if (isTypeCompletion) keywordFilters = KeywordCompletionFilters.TypeKeywords;
|
||||
|
||||
filterMutate(symbols, symbol => {
|
||||
if (!isSourceFile(location)) {
|
||||
// export = /**/ here we want to get all meanings, so any symbol is ok
|
||||
@@ -1145,19 +1192,14 @@ namespace ts.Completions {
|
||||
return true;
|
||||
}
|
||||
|
||||
// This is an alias, follow what it aliases
|
||||
if (symbol && symbol.flags & SymbolFlags.Alias) {
|
||||
symbol = typeChecker.getAliasedSymbol(symbol);
|
||||
}
|
||||
symbol = skipAlias(symbol, typeChecker);
|
||||
|
||||
// import m = /**/ <-- It can only access namespace (if typing import = x. this would get member symbols and not namespace)
|
||||
if (isInRightSideOfInternalImportEqualsDeclaration(location)) {
|
||||
return !!(symbol.flags & SymbolFlags.Namespace);
|
||||
}
|
||||
|
||||
if (insideJsDocTagTypeExpression ||
|
||||
(!isContextTokenValueLocation(contextToken) &&
|
||||
(isPartOfTypeNode(location) || isContextTokenTypeLocation(contextToken)))) {
|
||||
if (isTypeCompletion) {
|
||||
// Its a type, but you can reach it by namespace.type as well
|
||||
return symbolCanBeReferencedAtTypeLocation(symbol);
|
||||
}
|
||||
@@ -1174,7 +1216,7 @@ namespace ts.Completions {
|
||||
contextToken.parent.kind === SyntaxKind.TypeQuery;
|
||||
}
|
||||
|
||||
function isContextTokenTypeLocation(contextToken: Node) {
|
||||
function isContextTokenTypeLocation(contextToken: Node): boolean {
|
||||
if (contextToken) {
|
||||
const parentKind = contextToken.parent.kind;
|
||||
switch (contextToken.kind) {
|
||||
@@ -1192,6 +1234,7 @@ namespace ts.Completions {
|
||||
return parentKind === SyntaxKind.AsExpression;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function symbolCanBeReferencedAtTypeLocation(symbol: Symbol): boolean {
|
||||
@@ -1230,10 +1273,10 @@ namespace ts.Completions {
|
||||
symbol = getLocalSymbolForExportDefault(symbol) || symbol;
|
||||
}
|
||||
|
||||
const origin: SymbolOriginInfo = { moduleSymbol, isDefaultExport };
|
||||
const origin: SymbolOriginInfo = { type: "export", moduleSymbol, isDefaultExport };
|
||||
if (stringContainsCharactersInOrder(getSymbolName(symbol, origin, target).toLowerCase(), tokenTextLowerCase)) {
|
||||
symbols.push(symbol);
|
||||
symbolToOriginInfoMap[getSymbolId(symbol)] = { moduleSymbol, isDefaultExport };
|
||||
symbolToOriginInfoMap[getSymbolId(symbol)] = origin;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1668,6 +1711,22 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function tryGetFunctionLikeBodyCompletionContainer(contextToken: Node): FunctionLikeDeclaration {
|
||||
if (contextToken) {
|
||||
let prev: Node;
|
||||
const container = findAncestor(contextToken.parent, (node: Node) => {
|
||||
if (isClassLike(node)) {
|
||||
return "quit";
|
||||
}
|
||||
if (isFunctionLikeDeclaration(node) && prev === node.body) {
|
||||
return true;
|
||||
}
|
||||
prev = node;
|
||||
});
|
||||
return container && container as FunctionLikeDeclaration;
|
||||
}
|
||||
}
|
||||
|
||||
function tryGetContainingJsxElement(contextToken: Node): JsxOpeningLikeElement {
|
||||
if (contextToken) {
|
||||
const parent = contextToken.parent;
|
||||
@@ -2071,14 +2130,14 @@ namespace ts.Completions {
|
||||
const validIdentiferResult: CompletionEntryDisplayNameForSymbol = { name, needsConvertPropertyAccess: false };
|
||||
if (isIdentifierText(name, target)) return validIdentiferResult;
|
||||
switch (kind) {
|
||||
case CompletionKind.None:
|
||||
case CompletionKind.Global:
|
||||
case CompletionKind.MemberLike:
|
||||
return undefined;
|
||||
case CompletionKind.ObjectPropertyDeclaration:
|
||||
// TODO: GH#18169
|
||||
return { name: JSON.stringify(name), needsConvertPropertyAccess: false };
|
||||
case CompletionKind.PropertyAccess:
|
||||
case CompletionKind.None:
|
||||
case CompletionKind.Global:
|
||||
// Don't add a completion for a name starting with a space. See https://github.com/Microsoft/TypeScript/pull/20547
|
||||
return name.charCodeAt(0) === CharacterCodes.space ? undefined : { name, needsConvertPropertyAccess: true };
|
||||
case CompletionKind.String:
|
||||
@@ -2089,49 +2148,38 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
// A cache of completion entries for keywords, these do not change between sessions
|
||||
const _keywordCompletions: CompletionEntry[][] = [];
|
||||
function getKeywordCompletions(keywordFilter: KeywordCompletionFilters): CompletionEntry[] {
|
||||
const completions = _keywordCompletions[keywordFilter];
|
||||
if (completions) {
|
||||
return completions;
|
||||
const _keywordCompletions: ReadonlyArray<CompletionEntry>[] = [];
|
||||
const allKeywordsCompletions: () => ReadonlyArray<CompletionEntry> = ts.memoize(() => {
|
||||
const res: CompletionEntry[] = [];
|
||||
for (let i = SyntaxKind.FirstKeyword; i <= SyntaxKind.LastKeyword; i++) {
|
||||
res.push({
|
||||
name: tokenToString(i),
|
||||
kind: ScriptElementKind.keyword,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
sortText: "0"
|
||||
});
|
||||
}
|
||||
return _keywordCompletions[keywordFilter] = generateKeywordCompletions(keywordFilter);
|
||||
|
||||
type FilterKeywordCompletions = (entryName: string) => boolean;
|
||||
function generateKeywordCompletions(keywordFilter: KeywordCompletionFilters): CompletionEntry[] {
|
||||
return res;
|
||||
});
|
||||
function getKeywordCompletions(keywordFilter: KeywordCompletionFilters): ReadonlyArray<CompletionEntry> {
|
||||
return _keywordCompletions[keywordFilter] || (_keywordCompletions[keywordFilter] = allKeywordsCompletions().filter(entry => {
|
||||
const kind = stringToToken(entry.name);
|
||||
switch (keywordFilter) {
|
||||
case KeywordCompletionFilters.None:
|
||||
return getAllKeywordCompletions();
|
||||
// "undefined" is a global variable, so don't need a keyword completion for it.
|
||||
return kind !== SyntaxKind.UndefinedKeyword;
|
||||
case KeywordCompletionFilters.ClassElementKeywords:
|
||||
return getFilteredKeywordCompletions(isClassMemberCompletionKeywordText);
|
||||
return isClassMemberCompletionKeyword(kind);
|
||||
case KeywordCompletionFilters.ConstructorParameterKeywords:
|
||||
return getFilteredKeywordCompletions(isConstructorParameterCompletionKeywordText);
|
||||
return isConstructorParameterCompletionKeyword(kind);
|
||||
case KeywordCompletionFilters.FunctionLikeBodyKeywords:
|
||||
return isFunctionLikeBodyCompletionKeyword(kind);
|
||||
case KeywordCompletionFilters.TypeKeywords:
|
||||
return isTypeKeyword(kind);
|
||||
default:
|
||||
Debug.assertNever(keywordFilter);
|
||||
return Debug.assertNever(keywordFilter);
|
||||
}
|
||||
}
|
||||
|
||||
function getAllKeywordCompletions() {
|
||||
const allKeywordsCompletions: CompletionEntry[] = [];
|
||||
for (let i = SyntaxKind.FirstKeyword; i <= SyntaxKind.LastKeyword; i++) {
|
||||
// "undefined" is a global variable, so don't need a keyword completion for it.
|
||||
if (i === SyntaxKind.UndefinedKeyword) continue;
|
||||
allKeywordsCompletions.push({
|
||||
name: tokenToString(i),
|
||||
kind: ScriptElementKind.keyword,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
sortText: "0"
|
||||
});
|
||||
}
|
||||
return allKeywordsCompletions;
|
||||
}
|
||||
|
||||
function getFilteredKeywordCompletions(filterFn: FilterKeywordCompletions) {
|
||||
return filter(
|
||||
getKeywordCompletions(KeywordCompletionFilters.None),
|
||||
entry => filterFn(entry.name)
|
||||
);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
function isClassMemberCompletionKeyword(kind: SyntaxKind) {
|
||||
@@ -2168,6 +2216,23 @@ namespace ts.Completions {
|
||||
return isConstructorParameterCompletionKeyword(stringToToken(text));
|
||||
}
|
||||
|
||||
function isFunctionLikeBodyCompletionKeyword(kind: SyntaxKind) {
|
||||
switch (kind) {
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.ReadonlyKeyword:
|
||||
case SyntaxKind.ConstructorKeyword:
|
||||
case SyntaxKind.StaticKeyword:
|
||||
case SyntaxKind.AbstractKeyword:
|
||||
case SyntaxKind.GetKeyword:
|
||||
case SyntaxKind.SetKeyword:
|
||||
case SyntaxKind.UndefinedKeyword:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function isEqualityOperatorKind(kind: ts.SyntaxKind): kind is EqualityOperator {
|
||||
switch (kind) {
|
||||
case ts.SyntaxKind.EqualsEqualsEqualsToken:
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace ts.FindAllReferences {
|
||||
export function findReferencedSymbols(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray<SourceFile>, sourceFile: SourceFile, position: number): ReferencedSymbol[] | undefined {
|
||||
const referencedSymbols = findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position);
|
||||
const checker = program.getTypeChecker();
|
||||
return !referencedSymbols || !referencedSymbols.length ? undefined : mapDefined(referencedSymbols, ({ definition, references }) =>
|
||||
return !referencedSymbols || !referencedSymbols.length ? undefined : mapDefined<SymbolAndEntries, ReferencedSymbol>(referencedSymbols, ({ definition, references }) =>
|
||||
// Only include referenced symbols that have a valid definition.
|
||||
definition && { definition: definitionToReferencedSymbolDefinitionInfo(definition, checker), references: references.map(toReferenceEntry) });
|
||||
}
|
||||
@@ -356,7 +356,7 @@ namespace ts.FindAllReferences.Core {
|
||||
|
||||
/** Core find-all-references algorithm for a normal symbol. */
|
||||
function getReferencedSymbolsForSymbol(symbol: Symbol, node: Node, sourceFiles: ReadonlyArray<SourceFile>, checker: TypeChecker, cancellationToken: CancellationToken, options: Options): SymbolAndEntries[] {
|
||||
symbol = skipPastExportOrImportSpecifier(symbol, node, checker);
|
||||
symbol = skipPastExportOrImportSpecifierOrUnion(symbol, node, checker);
|
||||
|
||||
// Compute the meaning from the location and the symbol it references
|
||||
const searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), symbol.declarations);
|
||||
@@ -405,7 +405,7 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
|
||||
/** Handle a few special cases relating to export/import specifiers. */
|
||||
function skipPastExportOrImportSpecifier(symbol: Symbol, node: Node, checker: TypeChecker): Symbol {
|
||||
function skipPastExportOrImportSpecifierOrUnion(symbol: Symbol, node: Node, checker: TypeChecker): Symbol {
|
||||
const { parent } = node;
|
||||
if (isExportSpecifier(parent)) {
|
||||
return getLocalSymbolForExportSpecifier(node as Identifier, symbol, parent, checker);
|
||||
@@ -415,7 +415,11 @@ namespace ts.FindAllReferences.Core {
|
||||
return checker.getImmediateAliasedSymbol(symbol);
|
||||
}
|
||||
|
||||
return symbol;
|
||||
// If the symbol is declared as part of a declaration like `{ type: "a" } | { type: "b" }`, use the property on the union type to get more references.
|
||||
return firstDefined(symbol.declarations, decl =>
|
||||
isTypeLiteralNode(decl.parent) && isUnionTypeNode(decl.parent.parent)
|
||||
? checker.getPropertyOfType(checker.getTypeFromTypeNode(decl.parent.parent), symbol.name)
|
||||
: undefined) || symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,10 +14,14 @@ namespace ts.formatting {
|
||||
kind: SyntaxKind;
|
||||
}
|
||||
|
||||
export interface TextRangeWithTriviaKind extends TextRange {
|
||||
kind: TriviaKind;
|
||||
}
|
||||
|
||||
export interface TokenInfo {
|
||||
leadingTrivia: TextRangeWithKind[];
|
||||
leadingTrivia: TextRangeWithTriviaKind[];
|
||||
token: TextRangeWithKind;
|
||||
trailingTrivia: TextRangeWithKind[];
|
||||
trailingTrivia: TextRangeWithTriviaKind[];
|
||||
}
|
||||
|
||||
const enum Constants {
|
||||
@@ -66,11 +70,6 @@ namespace ts.formatting {
|
||||
recomputeIndentation(lineAddedByFormatting: boolean): void;
|
||||
}
|
||||
|
||||
interface Indentation {
|
||||
indentation: number;
|
||||
delta: number;
|
||||
}
|
||||
|
||||
export function formatOnEnter(position: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] {
|
||||
const line = sourceFile.getLineAndCharacterOfPosition(position).line;
|
||||
if (line === 0) {
|
||||
@@ -469,39 +468,35 @@ namespace ts.formatting {
|
||||
inheritedIndentation: number,
|
||||
parent: Node,
|
||||
parentDynamicIndentation: DynamicIndentation,
|
||||
effectiveParentStartLine: number): Indentation {
|
||||
|
||||
let indentation = inheritedIndentation;
|
||||
let delta = SmartIndenter.shouldIndentChildNode(node) ? options.indentSize : 0;
|
||||
effectiveParentStartLine: number
|
||||
): { indentation: number, delta: number } {
|
||||
const delta = SmartIndenter.shouldIndentChildNode(node) ? options.indentSize : 0;
|
||||
|
||||
if (effectiveParentStartLine === startLine) {
|
||||
// if node is located on the same line with the parent
|
||||
// - inherit indentation from the parent
|
||||
// - push children if either parent of node itself has non-zero delta
|
||||
indentation = startLine === lastIndentedLine
|
||||
? indentationOnLastIndentedLine
|
||||
: parentDynamicIndentation.getIndentation();
|
||||
delta = Math.min(options.indentSize, parentDynamicIndentation.getDelta(node) + delta);
|
||||
return {
|
||||
indentation: startLine === lastIndentedLine ? indentationOnLastIndentedLine : parentDynamicIndentation.getIndentation(),
|
||||
delta: Math.min(options.indentSize, parentDynamicIndentation.getDelta(node) + delta)
|
||||
};
|
||||
}
|
||||
else if (indentation === Constants.Unknown) {
|
||||
else if (inheritedIndentation === Constants.Unknown) {
|
||||
if (node.kind === SyntaxKind.OpenParenToken && startLine === lastIndentedLine) {
|
||||
// the is used for chaining methods formatting
|
||||
// - we need to get the indentation on last line and the delta of parent
|
||||
indentation = indentationOnLastIndentedLine;
|
||||
delta = parentDynamicIndentation.getDelta(node);
|
||||
return { indentation: indentationOnLastIndentedLine, delta: parentDynamicIndentation.getDelta(node) };
|
||||
}
|
||||
else if (SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) {
|
||||
indentation = parentDynamicIndentation.getIndentation();
|
||||
return { indentation: parentDynamicIndentation.getIndentation(), delta };
|
||||
}
|
||||
else {
|
||||
indentation = parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta(node);
|
||||
return { indentation: parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta(node), delta };
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
indentation,
|
||||
delta
|
||||
};
|
||||
else {
|
||||
return { indentation: inheritedIndentation, delta };
|
||||
}
|
||||
}
|
||||
|
||||
function getFirstNonDecoratorTokenOfNode(node: Node) {
|
||||
@@ -537,70 +532,56 @@ namespace ts.formatting {
|
||||
case SyntaxKind.CloseBraceToken:
|
||||
case SyntaxKind.CloseBracketToken:
|
||||
case SyntaxKind.CloseParenToken:
|
||||
return indentation + getEffectiveDelta(delta, container);
|
||||
return indentation + getDelta(container);
|
||||
}
|
||||
return tokenIndentation !== Constants.Unknown ? tokenIndentation : indentation;
|
||||
},
|
||||
getIndentationForToken: (line, kind, container) => {
|
||||
if (nodeStartLine !== line && node.decorators) {
|
||||
if (kind === getFirstNonDecoratorTokenOfNode(node)) {
|
||||
// if this token is the first token following the list of decorators, we do not need to indent
|
||||
return indentation;
|
||||
}
|
||||
}
|
||||
switch (kind) {
|
||||
// open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent
|
||||
case SyntaxKind.OpenBraceToken:
|
||||
case SyntaxKind.CloseBraceToken:
|
||||
case SyntaxKind.OpenParenToken:
|
||||
case SyntaxKind.CloseParenToken:
|
||||
case SyntaxKind.ElseKeyword:
|
||||
case SyntaxKind.WhileKeyword:
|
||||
case SyntaxKind.AtToken:
|
||||
return indentation;
|
||||
case SyntaxKind.SlashToken:
|
||||
case SyntaxKind.GreaterThanToken: {
|
||||
if (container.kind === SyntaxKind.JsxOpeningElement ||
|
||||
container.kind === SyntaxKind.JsxClosingElement ||
|
||||
container.kind === SyntaxKind.JsxSelfClosingElement
|
||||
) {
|
||||
return indentation;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SyntaxKind.OpenBracketToken:
|
||||
case SyntaxKind.CloseBracketToken: {
|
||||
if (container.kind !== SyntaxKind.MappedType) {
|
||||
return indentation;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if token line equals to the line of containing node (this is a first token in the node) - use node indentation
|
||||
return nodeStartLine !== line ? indentation + getEffectiveDelta(delta, container) : indentation;
|
||||
},
|
||||
getIndentationForToken: (line, kind, container) =>
|
||||
shouldAddDelta(line, kind, container) ? indentation + getDelta(container) : indentation,
|
||||
getIndentation: () => indentation,
|
||||
getDelta: child => getEffectiveDelta(delta, child),
|
||||
getDelta,
|
||||
recomputeIndentation: lineAdded => {
|
||||
if (node.parent && SmartIndenter.shouldIndentChildNode(node.parent, node)) {
|
||||
if (lineAdded) {
|
||||
indentation += options.indentSize;
|
||||
}
|
||||
else {
|
||||
indentation -= options.indentSize;
|
||||
}
|
||||
|
||||
if (SmartIndenter.shouldIndentChildNode(node)) {
|
||||
delta = options.indentSize;
|
||||
}
|
||||
else {
|
||||
delta = 0;
|
||||
}
|
||||
indentation += lineAdded ? options.indentSize : -options.indentSize;
|
||||
delta = SmartIndenter.shouldIndentChildNode(node) ? options.indentSize : 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function getEffectiveDelta(delta: number, child: TextRangeWithKind) {
|
||||
function shouldAddDelta(line: number, kind: SyntaxKind, container: Node): boolean {
|
||||
switch (kind) {
|
||||
// open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent
|
||||
case SyntaxKind.OpenBraceToken:
|
||||
case SyntaxKind.CloseBraceToken:
|
||||
case SyntaxKind.OpenParenToken:
|
||||
case SyntaxKind.CloseParenToken:
|
||||
case SyntaxKind.ElseKeyword:
|
||||
case SyntaxKind.WhileKeyword:
|
||||
case SyntaxKind.AtToken:
|
||||
return false;
|
||||
case SyntaxKind.SlashToken:
|
||||
case SyntaxKind.GreaterThanToken:
|
||||
switch (container.kind) {
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
case SyntaxKind.JsxClosingElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.OpenBracketToken:
|
||||
case SyntaxKind.CloseBracketToken:
|
||||
if (container.kind !== SyntaxKind.MappedType) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// if token line equals to the line of containing node (this is a first token in the node) - use node indentation
|
||||
return nodeStartLine !== line
|
||||
// if this token is the first token following the list of decorators, we do not need to indent
|
||||
&& !(node.decorators && kind === getFirstNonDecoratorTokenOfNode(node));
|
||||
}
|
||||
|
||||
function getDelta(child: TextRangeWithKind) {
|
||||
// Delta value should be zero when the node explicitly prevents indentation of the child node
|
||||
return SmartIndenter.nodeWillIndentChild(node, child, /*indentByDefault*/ true) ? delta : 0;
|
||||
}
|
||||
@@ -922,24 +903,25 @@ namespace ts.formatting {
|
||||
let trimTrailingWhitespaces: boolean;
|
||||
let lineAction = LineAction.None;
|
||||
if (rule) {
|
||||
applyRuleEdits(rule, previousItem, previousStartLine, currentItem, currentStartLine);
|
||||
|
||||
if (rule.action & (RuleAction.Space | RuleAction.Delete) && currentStartLine !== previousStartLine) {
|
||||
lineAction = LineAction.LineRemoved;
|
||||
// Handle the case where the next line is moved to be the end of this line.
|
||||
// In this case we don't indent the next line in the next pass.
|
||||
if (currentParent.getStart(sourceFile) === currentItem.pos) {
|
||||
dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ false);
|
||||
}
|
||||
}
|
||||
else if (rule.action & RuleAction.NewLine && currentStartLine === previousStartLine) {
|
||||
lineAction = LineAction.LineAdded;
|
||||
// Handle the case where token2 is moved to the new line.
|
||||
// In this case we indent token2 in the next pass but we set
|
||||
// sameLineIndent flag to notify the indenter that the indentation is within the line.
|
||||
if (currentParent.getStart(sourceFile) === currentItem.pos) {
|
||||
dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ true);
|
||||
}
|
||||
lineAction = applyRuleEdits(rule, previousItem, previousStartLine, currentItem, currentStartLine);
|
||||
switch (lineAction) {
|
||||
case LineAction.LineRemoved:
|
||||
// Handle the case where the next line is moved to be the end of this line.
|
||||
// In this case we don't indent the next line in the next pass.
|
||||
if (currentParent.getStart(sourceFile) === currentItem.pos) {
|
||||
dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ false);
|
||||
}
|
||||
break;
|
||||
case LineAction.LineAdded:
|
||||
// Handle the case where token2 is moved to the new line.
|
||||
// In this case we indent token2 in the next pass but we set
|
||||
// sameLineIndent flag to notify the indenter that the indentation is within the line.
|
||||
if (currentParent.getStart(sourceFile) === currentItem.pos) {
|
||||
dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Debug.assert(lineAction === LineAction.None);
|
||||
}
|
||||
|
||||
// We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line
|
||||
@@ -1096,19 +1078,15 @@ namespace ts.formatting {
|
||||
trimTrailingWhitespacesForLines(startLine, endLine + 1, previousRange);
|
||||
}
|
||||
|
||||
function newTextChange(start: number, len: number, newText: string): TextChange {
|
||||
return { span: createTextSpan(start, len), newText };
|
||||
}
|
||||
|
||||
function recordDelete(start: number, len: number) {
|
||||
if (len) {
|
||||
edits.push(newTextChange(start, len, ""));
|
||||
edits.push(createTextChangeFromStartLength(start, len, ""));
|
||||
}
|
||||
}
|
||||
|
||||
function recordReplace(start: number, len: number, newText: string) {
|
||||
if (len || newText) {
|
||||
edits.push(newTextChange(start, len, newText));
|
||||
edits.push(createTextChangeFromStartLength(start, len, newText));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1116,16 +1094,18 @@ namespace ts.formatting {
|
||||
previousRange: TextRangeWithKind,
|
||||
previousStartLine: number,
|
||||
currentRange: TextRangeWithKind,
|
||||
currentStartLine: number): void {
|
||||
|
||||
currentStartLine: number,
|
||||
): LineAction {
|
||||
const onLaterLine = currentStartLine !== previousStartLine;
|
||||
switch (rule.action) {
|
||||
case RuleAction.Ignore:
|
||||
// no action required
|
||||
return;
|
||||
return LineAction.None;
|
||||
case RuleAction.Delete:
|
||||
if (previousRange.end !== currentRange.pos) {
|
||||
// delete characters starting from t1.end up to t2.pos exclusive
|
||||
recordDelete(previousRange.end, currentRange.pos - previousRange.end);
|
||||
return onLaterLine ? LineAction.LineRemoved : LineAction.None;
|
||||
}
|
||||
break;
|
||||
case RuleAction.NewLine:
|
||||
@@ -1133,27 +1113,29 @@ namespace ts.formatting {
|
||||
// if line1 and line2 are on subsequent lines then no edits are required - ok to exit
|
||||
// if line1 and line2 are separated with more than one newline - ok to exit since we cannot delete extra new lines
|
||||
if (rule.flags !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) {
|
||||
return;
|
||||
return LineAction.None;
|
||||
}
|
||||
|
||||
// edit should not be applied if we have one line feed between elements
|
||||
const lineDelta = currentStartLine - previousStartLine;
|
||||
if (lineDelta !== 1) {
|
||||
recordReplace(previousRange.end, currentRange.pos - previousRange.end, options.newLineCharacter);
|
||||
return onLaterLine ? LineAction.None : LineAction.LineAdded;
|
||||
}
|
||||
break;
|
||||
case RuleAction.Space:
|
||||
// exit early if we on different lines and rule cannot change number of newlines
|
||||
if (rule.flags !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) {
|
||||
return;
|
||||
return LineAction.None;
|
||||
}
|
||||
|
||||
const posDelta = currentRange.pos - previousRange.end;
|
||||
if (posDelta !== 1 || sourceFile.text.charCodeAt(previousRange.end) !== CharacterCodes.space) {
|
||||
recordReplace(previousRange.end, currentRange.pos - previousRange.end, " ");
|
||||
return onLaterLine ? LineAction.LineRemoved : LineAction.None;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return LineAction.None;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1277,13 +1259,13 @@ namespace ts.formatting {
|
||||
}
|
||||
|
||||
if (internedTabsIndentation[tabs] === undefined) {
|
||||
internedTabsIndentation[tabs] = tabString = repeat("\t", tabs);
|
||||
internedTabsIndentation[tabs] = tabString = repeatString("\t", tabs);
|
||||
}
|
||||
else {
|
||||
tabString = internedTabsIndentation[tabs];
|
||||
}
|
||||
|
||||
return spaces ? tabString + repeat(" ", spaces) : tabString;
|
||||
return spaces ? tabString + repeatString(" ", spaces) : tabString;
|
||||
}
|
||||
else {
|
||||
let spacesString: string;
|
||||
@@ -1294,23 +1276,14 @@ namespace ts.formatting {
|
||||
}
|
||||
|
||||
if (internedSpacesIndentation[quotient] === undefined) {
|
||||
spacesString = repeat(" ", options.indentSize * quotient);
|
||||
spacesString = repeatString(" ", options.indentSize * quotient);
|
||||
internedSpacesIndentation[quotient] = spacesString;
|
||||
}
|
||||
else {
|
||||
spacesString = internedSpacesIndentation[quotient];
|
||||
}
|
||||
|
||||
return remainder ? spacesString + repeat(" ", remainder) : spacesString;
|
||||
}
|
||||
|
||||
function repeat(value: string, count: number): string {
|
||||
let s = "";
|
||||
for (let i = 0; i < count; i++) {
|
||||
s += value;
|
||||
}
|
||||
|
||||
return s;
|
||||
return remainder ? spacesString + repeatString(" ", remainder) : spacesString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ namespace ts.formatting {
|
||||
scanner.setTextPos(startPos);
|
||||
|
||||
let wasNewLine = true;
|
||||
let leadingTrivia: TextRangeWithKind[] | undefined;
|
||||
let trailingTrivia: TextRangeWithKind[] | undefined;
|
||||
let leadingTrivia: TextRangeWithTriviaKind[] | undefined;
|
||||
let trailingTrivia: TextRangeWithTriviaKind[] | undefined;
|
||||
|
||||
let savedPos: number;
|
||||
let lastScanAction: ScanAction | undefined;
|
||||
@@ -77,7 +77,7 @@ namespace ts.formatting {
|
||||
|
||||
// consume leading trivia
|
||||
scanner.scan();
|
||||
const item = {
|
||||
const item: TextRangeWithTriviaKind = {
|
||||
pos,
|
||||
end: scanner.getStartPos(),
|
||||
kind: t
|
||||
@@ -188,7 +188,7 @@ namespace ts.formatting {
|
||||
if (!isTrivia(currentToken)) {
|
||||
break;
|
||||
}
|
||||
const trivia = {
|
||||
const trivia: TextRangeWithTriviaKind = {
|
||||
pos: scanner.getStartPos(),
|
||||
end: scanner.getTextPos(),
|
||||
kind: currentToken
|
||||
|
||||
@@ -321,6 +321,9 @@ namespace ts.formatting {
|
||||
rule("NoSpaceAfterCloseBracket", SyntaxKind.CloseBracketToken, anyToken, [isNonJsxSameLineTokenContext, isNotBeforeBlockInFunctionDeclarationContext], RuleAction.Delete),
|
||||
rule("SpaceAfterSemicolon", SyntaxKind.SemicolonToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.Space),
|
||||
|
||||
// Remove extra space between for and await
|
||||
rule("SpaceBetweenForAndAwaitKeyword", SyntaxKind.ForKeyword, SyntaxKind.AwaitKeyword, [isNonJsxSameLineTokenContext], RuleAction.Space),
|
||||
|
||||
// Add a space between statements. All keywords except (do,else,case) has open/close parens after them.
|
||||
// So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any]
|
||||
rule(
|
||||
|
||||
@@ -127,30 +127,16 @@ namespace ts.GoToDefinition {
|
||||
}
|
||||
|
||||
const symbol = typeChecker.getSymbolAtLocation(node);
|
||||
if (!symbol) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const type = typeChecker.getTypeOfSymbolAtLocation(symbol, node);
|
||||
const type = symbol && typeChecker.getTypeOfSymbolAtLocation(symbol, node);
|
||||
if (!type) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum)) {
|
||||
const result: DefinitionInfo[] = [];
|
||||
forEach((<UnionType>type).types, t => {
|
||||
if (t.symbol) {
|
||||
addRange(/*to*/ result, /*from*/ getDefinitionFromSymbol(typeChecker, t.symbol, node));
|
||||
}
|
||||
});
|
||||
return result;
|
||||
return flatMap((<UnionType>type).types, t => t.symbol && getDefinitionFromSymbol(typeChecker, t.symbol, node));
|
||||
}
|
||||
|
||||
if (!type.symbol) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return getDefinitionFromSymbol(typeChecker, type.symbol, node);
|
||||
return type.symbol && getDefinitionFromSymbol(typeChecker, type.symbol, node);
|
||||
}
|
||||
|
||||
export function getDefinitionAndBoundSpan(program: Program, sourceFile: SourceFile, position: number): DefinitionInfoAndBoundSpan {
|
||||
@@ -199,66 +185,32 @@ namespace ts.GoToDefinition {
|
||||
}
|
||||
|
||||
function getDefinitionFromSymbol(typeChecker: TypeChecker, symbol: Symbol, node: Node): DefinitionInfo[] {
|
||||
const result: DefinitionInfo[] = [];
|
||||
const declarations = symbol.getDeclarations();
|
||||
const { symbolName, symbolKind, containerName } = getSymbolInfo(typeChecker, symbol, node);
|
||||
return getConstructSignatureDefinition() || getCallSignatureDefinition() || map(symbol.declarations, declaration => createDefinitionInfo(declaration, symbolKind, symbolName, containerName));
|
||||
|
||||
if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) &&
|
||||
!tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) {
|
||||
// Just add all the declarations.
|
||||
forEach(declarations, declaration => {
|
||||
result.push(createDefinitionInfo(declaration, symbolKind, symbolName, containerName));
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
function tryAddConstructSignature(symbol: Symbol, location: Node, symbolKind: ScriptElementKind, symbolName: string, containerName: string, result: DefinitionInfo[]) {
|
||||
function getConstructSignatureDefinition(): DefinitionInfo[] | undefined {
|
||||
// Applicable only if we are in a new expression, or we are on a constructor declaration
|
||||
// and in either case the symbol has a construct signature definition, i.e. class
|
||||
if (isNewExpressionTarget(location) || location.kind === SyntaxKind.ConstructorKeyword) {
|
||||
if (symbol.flags & SymbolFlags.Class) {
|
||||
// Find the first class-like declaration and try to get the construct signature.
|
||||
for (const declaration of symbol.getDeclarations()) {
|
||||
if (isClassLike(declaration)) {
|
||||
return tryAddSignature(
|
||||
declaration.members, /*selectConstructors*/ true, symbolKind, symbolName, containerName, result);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.fail("Expected declaration to have at least one class-like declaration");
|
||||
}
|
||||
if (isNewExpressionTarget(node) || node.kind === SyntaxKind.ConstructorKeyword && symbol.flags & SymbolFlags.Class) {
|
||||
const cls = find(symbol.declarations, isClassLike) || Debug.fail("Expected declaration to have at least one class-like declaration");
|
||||
return getSignatureDefinition(cls.members, /*selectConstructors*/ true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function tryAddCallSignature(symbol: Symbol, location: Node, symbolKind: ScriptElementKind, symbolName: string, containerName: string, result: DefinitionInfo[]) {
|
||||
if (isCallExpressionTarget(location) || isNewExpressionTarget(location) || isNameOfFunctionDeclaration(location)) {
|
||||
return tryAddSignature(symbol.declarations, /*selectConstructors*/ false, symbolKind, symbolName, containerName, result);
|
||||
}
|
||||
return false;
|
||||
function getCallSignatureDefinition(): DefinitionInfo[] | undefined {
|
||||
return isCallExpressionTarget(node) || isNewExpressionTarget(node) || isNameOfFunctionDeclaration(node)
|
||||
? getSignatureDefinition(symbol.declarations, /*selectConstructors*/ false)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function tryAddSignature(signatureDeclarations: ReadonlyArray<Declaration> | undefined, selectConstructors: boolean, symbolKind: ScriptElementKind, symbolName: string, containerName: string, result: DefinitionInfo[]) {
|
||||
function getSignatureDefinition(signatureDeclarations: ReadonlyArray<Declaration> | undefined, selectConstructors: boolean): DefinitionInfo[] | undefined {
|
||||
if (!signatureDeclarations) {
|
||||
return false;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const declarations: Declaration[] = [];
|
||||
let definition: Declaration | undefined;
|
||||
|
||||
for (const d of signatureDeclarations) {
|
||||
if (selectConstructors ? d.kind === SyntaxKind.Constructor : isSignatureDeclaration(d)) {
|
||||
declarations.push(d);
|
||||
if ((<FunctionLikeDeclaration>d).body) definition = d;
|
||||
}
|
||||
}
|
||||
|
||||
if (declarations.length) {
|
||||
result.push(createDefinitionInfo(definition || lastOrUndefined(declarations), symbolKind, symbolName, containerName));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
const declarations = signatureDeclarations.filter(selectConstructors ? isConstructorDeclaration : isSignatureDeclaration);
|
||||
return declarations.length
|
||||
? [createDefinitionInfo(find(declarations, d => !!(<FunctionLikeDeclaration>d).body) || last(declarations), symbolKind, symbolName, containerName)]
|
||||
: undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -510,11 +510,32 @@ namespace ts.FindAllReferences {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const sym = useLhsSymbol ? checker.getSymbolAtLocation((node.left as ts.PropertyAccessExpression).name) : symbol;
|
||||
const sym = useLhsSymbol ? checker.getSymbolAtLocation(cast(node.left, isPropertyAccessExpression).name) : symbol;
|
||||
// Better detection for GH#20803
|
||||
if (sym && !(checker.getMergedSymbol(sym.parent).flags & SymbolFlags.Module)) {
|
||||
Debug.fail(`Special property assignment kind does not have a module as its parent. Assignment is ${showSymbol(sym)}, parent is ${showSymbol(sym.parent)}`);
|
||||
}
|
||||
return sym && exportInfo(sym, kind);
|
||||
}
|
||||
}
|
||||
|
||||
function showSymbol(s: Symbol): string {
|
||||
const decls = s.declarations.map(d => (ts as any).SyntaxKind[d.kind]).join(",");
|
||||
const flags = showFlags(s.flags, (ts as any).SymbolFlags);
|
||||
return `{ declarations: ${decls}, flags: ${flags} }`;
|
||||
}
|
||||
|
||||
function showFlags(f: number, flags: any) {
|
||||
const out = [];
|
||||
for (let pow = 0; pow <= 30; pow++) {
|
||||
const n = 1 << pow;
|
||||
if (f & n) {
|
||||
out.push(flags[n]);
|
||||
}
|
||||
}
|
||||
return out.join("|");
|
||||
}
|
||||
|
||||
function getImport(): ImportedSymbol | undefined {
|
||||
const isImport = isNodeImport(node);
|
||||
if (!isImport) return undefined;
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export interface Refactor {
|
||||
/** An unique code associated with each refactor */
|
||||
name: string;
|
||||
|
||||
/** Description of the refactor to display in the UI of the editor */
|
||||
description: string;
|
||||
|
||||
/** Compute the associated code actions */
|
||||
getEditsForAction(context: RefactorContext, actionName: string): RefactorEditInfo | undefined;
|
||||
|
||||
@@ -19,7 +13,6 @@ namespace ts {
|
||||
startPosition: number;
|
||||
endPosition?: number;
|
||||
program: Program;
|
||||
host: LanguageServiceHost;
|
||||
cancellationToken?: CancellationToken;
|
||||
}
|
||||
|
||||
@@ -28,8 +21,9 @@ namespace ts {
|
||||
// e.g. nonSuggestableRefactors[refactorCode] -> the refactor you want
|
||||
const refactors: Map<Refactor> = createMap<Refactor>();
|
||||
|
||||
export function registerRefactor(refactor: Refactor) {
|
||||
refactors.set(refactor.name, refactor);
|
||||
/** @param name An unique code associated with each refactor. Does not have to be human-readable. */
|
||||
export function registerRefactor(name: string, refactor: Refactor) {
|
||||
refactors.set(name, refactor);
|
||||
}
|
||||
|
||||
export function getApplicableRefactors(context: RefactorContext): ApplicableRefactorInfo[] {
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
/* @internal */
|
||||
namespace ts.refactor.annotateWithTypeFromJSDoc {
|
||||
const refactorName = "Annotate with type from JSDoc";
|
||||
const actionName = "annotate";
|
||||
const description = Diagnostics.Annotate_with_type_from_JSDoc.message;
|
||||
registerRefactor(refactorName, { getEditsForAction, getAvailableActions });
|
||||
|
||||
const annotateTypeFromJSDoc: Refactor = {
|
||||
name: "Annotate with type from JSDoc",
|
||||
description: Diagnostics.Annotate_with_type_from_JSDoc.message,
|
||||
getEditsForAction,
|
||||
getAvailableActions
|
||||
};
|
||||
type DeclarationWithType =
|
||||
| FunctionLikeDeclaration
|
||||
| VariableDeclaration
|
||||
@@ -15,8 +12,6 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
|
||||
| PropertySignature
|
||||
| PropertyDeclaration;
|
||||
|
||||
registerRefactor(annotateTypeFromJSDoc);
|
||||
|
||||
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
|
||||
if (isInJavaScriptFile(context.file)) {
|
||||
return undefined;
|
||||
@@ -25,11 +20,11 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
|
||||
const node = getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false);
|
||||
if (hasUsableJSDoc(findAncestor(node, isDeclarationWithType))) {
|
||||
return [{
|
||||
name: annotateTypeFromJSDoc.name,
|
||||
description: annotateTypeFromJSDoc.description,
|
||||
name: refactorName,
|
||||
description,
|
||||
actions: [
|
||||
{
|
||||
description: annotateTypeFromJSDoc.description,
|
||||
description,
|
||||
name: actionName
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
/* @internal */
|
||||
|
||||
namespace ts.refactor.convertFunctionToES6Class {
|
||||
const refactorName = "Convert to ES2015 class";
|
||||
const actionName = "convert";
|
||||
|
||||
const convertFunctionToES6Class: Refactor = {
|
||||
name: "Convert to ES2015 class",
|
||||
description: Diagnostics.Convert_function_to_an_ES2015_class.message,
|
||||
getEditsForAction,
|
||||
getAvailableActions
|
||||
};
|
||||
|
||||
registerRefactor(convertFunctionToES6Class);
|
||||
const description = Diagnostics.Convert_function_to_an_ES2015_class.message;
|
||||
registerRefactor(refactorName, { getEditsForAction, getAvailableActions });
|
||||
|
||||
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
|
||||
if (!isInJavaScriptFile(context.file)) {
|
||||
@@ -29,11 +23,11 @@ namespace ts.refactor.convertFunctionToES6Class {
|
||||
if ((symbol.flags & SymbolFlags.Function) && symbol.members && (symbol.members.size > 0)) {
|
||||
return [
|
||||
{
|
||||
name: convertFunctionToES6Class.name,
|
||||
description: convertFunctionToES6Class.description,
|
||||
name: refactorName,
|
||||
description,
|
||||
actions: [
|
||||
{
|
||||
description: convertFunctionToES6Class.description,
|
||||
description,
|
||||
name: actionName
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
/* @internal */
|
||||
namespace ts.refactor {
|
||||
const actionName = "Convert to ES6 module";
|
||||
|
||||
const convertToEs6Module: Refactor = {
|
||||
name: actionName,
|
||||
description: getLocaleSpecificMessage(Diagnostics.Convert_to_ES6_module),
|
||||
getEditsForAction,
|
||||
getAvailableActions,
|
||||
};
|
||||
|
||||
registerRefactor(convertToEs6Module);
|
||||
const description = getLocaleSpecificMessage(Diagnostics.Convert_to_ES6_module);
|
||||
registerRefactor(actionName, { getEditsForAction, getAvailableActions });
|
||||
|
||||
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
|
||||
const { file, startPosition } = context;
|
||||
@@ -20,11 +13,11 @@ namespace ts.refactor {
|
||||
const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
|
||||
return !isAtTriggerLocation(file, node) ? undefined : [
|
||||
{
|
||||
name: convertToEs6Module.name,
|
||||
description: convertToEs6Module.description,
|
||||
name: actionName,
|
||||
description,
|
||||
actions: [
|
||||
{
|
||||
description: convertToEs6Module.description,
|
||||
description,
|
||||
name: actionName,
|
||||
},
|
||||
],
|
||||
|
||||
@@ -3,14 +3,8 @@
|
||||
|
||||
/* @internal */
|
||||
namespace ts.refactor.extractSymbol {
|
||||
const extractSymbol: Refactor = {
|
||||
name: "Extract Symbol",
|
||||
description: getLocaleSpecificMessage(Diagnostics.Extract_symbol),
|
||||
getAvailableActions,
|
||||
getEditsForAction,
|
||||
};
|
||||
|
||||
registerRefactor(extractSymbol);
|
||||
const refactorName = "Extract Symbol";
|
||||
registerRefactor(refactorName, { getAvailableActions, getEditsForAction });
|
||||
|
||||
/**
|
||||
* Compute the associated code actions
|
||||
@@ -77,7 +71,7 @@ namespace ts.refactor.extractSymbol {
|
||||
|
||||
if (functionActions.length) {
|
||||
infos.push({
|
||||
name: extractSymbol.name,
|
||||
name: refactorName,
|
||||
description: getLocaleSpecificMessage(Diagnostics.Extract_function),
|
||||
actions: functionActions
|
||||
});
|
||||
@@ -85,7 +79,7 @@ namespace ts.refactor.extractSymbol {
|
||||
|
||||
if (constantActions.length) {
|
||||
infos.push({
|
||||
name: extractSymbol.name,
|
||||
name: refactorName,
|
||||
description: getLocaleSpecificMessage(Diagnostics.Extract_constant),
|
||||
actions: constantActions
|
||||
});
|
||||
@@ -241,6 +235,16 @@ namespace ts.refactor.extractSymbol {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!statements.length) {
|
||||
// https://github.com/Microsoft/TypeScript/issues/20559
|
||||
// Ranges like [|case 1: break;|] will fail to populate `statements` because
|
||||
// they will never find `start` in `start.parent.statements`.
|
||||
// Consider: We could support ranges like [|case 1:|] by refining them to just
|
||||
// the expression.
|
||||
return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] };
|
||||
}
|
||||
|
||||
return { targetRange: { range: statements, facts: rangeFacts, declarations } };
|
||||
}
|
||||
|
||||
@@ -1327,6 +1331,13 @@ namespace ts.refactor.extractSymbol {
|
||||
}
|
||||
prevStatement = statement;
|
||||
}
|
||||
|
||||
if (!prevStatement && isCaseClause(curr)) {
|
||||
// We must have been in the expression of the case clause.
|
||||
Debug.assert(isSwitchStatement(curr.parent.parent));
|
||||
return curr.parent.parent;
|
||||
}
|
||||
|
||||
// There must be at least one statement since we started in one.
|
||||
Debug.assert(prevStatement !== undefined);
|
||||
return prevStatement;
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
/* @internal */
|
||||
namespace ts.refactor.installTypesForPackage {
|
||||
const refactorName = "Install missing types package";
|
||||
const actionName = "install";
|
||||
|
||||
const installTypesForPackage: Refactor = {
|
||||
name: "Install missing types package",
|
||||
description: "Install missing types package",
|
||||
getEditsForAction,
|
||||
getAvailableActions,
|
||||
};
|
||||
|
||||
registerRefactor(installTypesForPackage);
|
||||
const description = "Install missing types package";
|
||||
registerRefactor(refactorName, { getEditsForAction, getAvailableActions });
|
||||
|
||||
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
|
||||
if (getStrictOptionValue(context.program.getCompilerOptions(), "noImplicitAny")) {
|
||||
@@ -20,8 +14,8 @@ namespace ts.refactor.installTypesForPackage {
|
||||
const action = getAction(context);
|
||||
return action && [
|
||||
{
|
||||
name: installTypesForPackage.name,
|
||||
description: installTypesForPackage.description,
|
||||
name: refactorName,
|
||||
description,
|
||||
actions: [
|
||||
{
|
||||
description: action.description,
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
/* @internal */
|
||||
namespace ts.refactor.installTypesForPackage {
|
||||
const actionName = "Convert to default import";
|
||||
|
||||
const useDefaultImport: Refactor = {
|
||||
name: actionName,
|
||||
description: getLocaleSpecificMessage(Diagnostics.Convert_to_default_import),
|
||||
getEditsForAction,
|
||||
getAvailableActions,
|
||||
};
|
||||
|
||||
registerRefactor(useDefaultImport);
|
||||
const description = getLocaleSpecificMessage(Diagnostics.Convert_to_default_import);
|
||||
registerRefactor(actionName, { getEditsForAction, getAvailableActions });
|
||||
|
||||
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
|
||||
const { file, startPosition, program } = context;
|
||||
@@ -31,11 +24,11 @@ namespace ts.refactor.installTypesForPackage {
|
||||
|
||||
return [
|
||||
{
|
||||
name: useDefaultImport.name,
|
||||
description: useDefaultImport.description,
|
||||
name: actionName,
|
||||
description,
|
||||
actions: [
|
||||
{
|
||||
description: useDefaultImport.description,
|
||||
description,
|
||||
name: actionName,
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1255,7 +1255,7 @@ namespace ts {
|
||||
getCancellationToken: () => cancellationToken,
|
||||
getCanonicalFileName,
|
||||
useCaseSensitiveFileNames: () => useCaseSensitivefileNames,
|
||||
getNewLine: () => getNewLineCharacter(newSettings, { newLine: getNewLineOrDefaultFromHost(host) }),
|
||||
getNewLine: () => getNewLineCharacter(newSettings, () => getNewLineOrDefaultFromHost(host)),
|
||||
getDefaultLibFileName: (options) => host.getDefaultLibFileName(options),
|
||||
writeFile: noop,
|
||||
getCurrentDirectory: () => currentDirectory,
|
||||
@@ -1887,12 +1887,11 @@ namespace ts {
|
||||
synchronizeHostData();
|
||||
const sourceFile = getValidSourceFile(fileName);
|
||||
const span = createTextSpanFromBounds(start, end);
|
||||
const newLineCharacter = getNewLineOrDefaultFromHost(host);
|
||||
const formatContext = formatting.getFormatContext(formatOptions);
|
||||
|
||||
return flatMap(deduplicate(errorCodes, equateValues, compareValues), errorCode => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
return codefix.getFixes({ errorCode, sourceFile, span, program, newLineCharacter, host, cancellationToken, formatContext });
|
||||
return codefix.getFixes({ errorCode, sourceFile, span, program, host, cancellationToken, formatContext });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1900,10 +1899,9 @@ namespace ts {
|
||||
synchronizeHostData();
|
||||
Debug.assert(scope.type === "file");
|
||||
const sourceFile = getValidSourceFile(scope.fileName);
|
||||
const newLineCharacter = getNewLineOrDefaultFromHost(host);
|
||||
const formatContext = formatting.getFormatContext(formatOptions);
|
||||
|
||||
return codefix.getAllFixes({ fixId, sourceFile, program, newLineCharacter, host, cancellationToken, formatContext });
|
||||
return codefix.getAllFixes({ fixId, sourceFile, program, host, cancellationToken, formatContext });
|
||||
}
|
||||
|
||||
function applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
@@ -2134,7 +2132,6 @@ namespace ts {
|
||||
startPosition,
|
||||
endPosition,
|
||||
program: getProgram(),
|
||||
newLineCharacter: formatOptions ? formatOptions.newLineCharacter : host.getNewLine(),
|
||||
host,
|
||||
formatContext: formatting.getFormatContext(formatOptions),
|
||||
cancellationToken,
|
||||
|
||||
@@ -187,7 +187,7 @@ namespace ts.textChanges {
|
||||
}
|
||||
|
||||
export interface TextChangesContext {
|
||||
newLineCharacter: string;
|
||||
host: LanguageServiceHost;
|
||||
formatContext: ts.formatting.FormatContext;
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ namespace ts.textChanges {
|
||||
private readonly nodesInsertedAtClassStarts = createMap<{ sourceFile: SourceFile, cls: ClassLikeDeclaration, members: ClassElement[] }>();
|
||||
|
||||
public static fromContext(context: TextChangesContext): ChangeTracker {
|
||||
return new ChangeTracker(context.newLineCharacter === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed, context.formatContext);
|
||||
return new ChangeTracker(getNewLineOrDefaultFromHost(context.host, context.formatContext.options) === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed, context.formatContext);
|
||||
}
|
||||
|
||||
public static with(context: TextChangesContext, cb: (tracker: ChangeTracker) => void): FileTextChanges[] {
|
||||
@@ -620,10 +620,7 @@ namespace ts.textChanges {
|
||||
const sourceFile = changesInFile[0].sourceFile;
|
||||
const fileTextChanges: FileTextChanges = { fileName: sourceFile.fileName, textChanges: [] };
|
||||
for (const c of ChangeTracker.normalize(changesInFile)) {
|
||||
fileTextChanges.textChanges.push({
|
||||
span: this.computeSpan(c, sourceFile),
|
||||
newText: this.computeNewText(c, sourceFile)
|
||||
});
|
||||
fileTextChanges.textChanges.push(createTextChange(this.computeSpan(c, sourceFile), this.computeNewText(c, sourceFile)));
|
||||
}
|
||||
fileChangesList.push(fileTextChanges);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
{
|
||||
"extends": "../tsconfig-base",
|
||||
"compilerOptions": {
|
||||
"removeComments": false,
|
||||
@@ -37,6 +37,11 @@
|
||||
"../compiler/declarationEmitter.ts",
|
||||
"../compiler/emitter.ts",
|
||||
"../compiler/program.ts",
|
||||
"../compiler/builderState.ts",
|
||||
"../compiler/builder.ts",
|
||||
"../compiler/resolutionCache.ts",
|
||||
"../compiler/watch.ts",
|
||||
"../compiler/watchUtilities.ts",
|
||||
"../compiler/commandLineParser.ts",
|
||||
"../compiler/diagnosticInformationMap.generated.ts",
|
||||
"types.ts",
|
||||
|
||||
+1
-10
@@ -295,10 +295,7 @@ namespace ts {
|
||||
|
||||
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
|
||||
|
||||
// TODO: GH#20538 return `ReadonlyArray<CodeFixAction>`
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray<number>, formatOptions: FormatCodeSettings): ReadonlyArray<CodeAction>;
|
||||
// TODO: GH#20538
|
||||
/* @internal */
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray<number>, formatOptions: FormatCodeSettings): ReadonlyArray<CodeFixAction>;
|
||||
getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings): CombinedCodeActions;
|
||||
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
@@ -327,8 +324,6 @@ namespace ts {
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
// TODO: GH#20538
|
||||
/* @internal */
|
||||
export interface CombinedCodeFixScope { type: "file"; fileName: string; }
|
||||
|
||||
export interface GetCompletionsAtPositionOptions {
|
||||
@@ -419,8 +414,6 @@ namespace ts {
|
||||
commands?: CodeActionCommand[];
|
||||
}
|
||||
|
||||
// TODO: GH#20538
|
||||
/* @internal */
|
||||
export interface CodeFixAction extends CodeAction {
|
||||
/**
|
||||
* If present, one may call 'getCombinedCodeFix' with this fixId.
|
||||
@@ -429,8 +422,6 @@ namespace ts {
|
||||
fixId?: {};
|
||||
}
|
||||
|
||||
// TODO: GH#20538
|
||||
/* @internal */
|
||||
export interface CombinedCodeActions {
|
||||
changes: ReadonlyArray<FileTextChanges>;
|
||||
commands: ReadonlyArray<CodeActionCommand> | undefined;
|
||||
|
||||
@@ -1067,15 +1067,27 @@ namespace ts {
|
||||
return createTextSpanFromBounds(range.pos, range.end);
|
||||
}
|
||||
|
||||
export function createTextChangeFromStartLength(start: number, length: number, newText: string): TextChange {
|
||||
return createTextChange(createTextSpan(start, length), newText);
|
||||
}
|
||||
|
||||
export function createTextChange(span: TextSpan, newText: string): TextChange {
|
||||
return { span, newText };
|
||||
}
|
||||
|
||||
export const typeKeywords: ReadonlyArray<SyntaxKind> = [
|
||||
SyntaxKind.AnyKeyword,
|
||||
SyntaxKind.BooleanKeyword,
|
||||
SyntaxKind.KeyOfKeyword,
|
||||
SyntaxKind.NeverKeyword,
|
||||
SyntaxKind.NullKeyword,
|
||||
SyntaxKind.NumberKeyword,
|
||||
SyntaxKind.ObjectKeyword,
|
||||
SyntaxKind.StringKeyword,
|
||||
SyntaxKind.SymbolKeyword,
|
||||
SyntaxKind.VoidKeyword,
|
||||
SyntaxKind.UndefinedKeyword,
|
||||
SyntaxKind.UniqueKeyword,
|
||||
];
|
||||
|
||||
export function isTypeKeyword(kind: SyntaxKind): boolean {
|
||||
@@ -1110,6 +1122,14 @@ namespace ts {
|
||||
export function getSnapshotText(snap: IScriptSnapshot): string {
|
||||
return snap.getText(0, snap.getLength());
|
||||
}
|
||||
|
||||
export function repeatString(str: string, count: number): string {
|
||||
let result = "";
|
||||
for (let i = 0; i < count; i++) {
|
||||
result += str;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Display-part writer helpers
|
||||
@@ -1251,8 +1271,10 @@ namespace ts {
|
||||
/**
|
||||
* The default is CRLF.
|
||||
*/
|
||||
export function getNewLineOrDefaultFromHost(host: LanguageServiceHost | LanguageServiceShimHost) {
|
||||
return host.getNewLine ? host.getNewLine() : carriageReturnLineFeed;
|
||||
export function getNewLineOrDefaultFromHost(host: LanguageServiceHost | LanguageServiceShimHost, formatSettings?: FormatCodeSettings) {
|
||||
return (formatSettings && formatSettings.newLineCharacter) ||
|
||||
(host.getNewLine && host.getNewLine()) ||
|
||||
carriageReturnLineFeed;
|
||||
}
|
||||
|
||||
export function lineBreakPart() {
|
||||
|
||||
+80
-39
@@ -2297,6 +2297,7 @@ declare namespace ts {
|
||||
charset?: string;
|
||||
checkJs?: boolean;
|
||||
declaration?: boolean;
|
||||
emitDeclarationsOnly?: boolean;
|
||||
declarationDir?: string;
|
||||
disableSizeLimit?: boolean;
|
||||
downlevelIteration?: boolean;
|
||||
@@ -2537,6 +2538,7 @@ declare namespace ts {
|
||||
*/
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): (ResolvedTypeReferenceDirective | undefined)[];
|
||||
getEnvironmentVariable?(name: string): string;
|
||||
createHash?(data: string): string;
|
||||
}
|
||||
interface SourceMapRange extends TextRange {
|
||||
source?: SourceMapSource;
|
||||
@@ -2838,12 +2840,13 @@ declare namespace ts {
|
||||
}
|
||||
}
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "2.7";
|
||||
const versionMajorMinor = "2.8";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
declare namespace ts {
|
||||
function isExternalModuleNameRelative(moduleName: string): boolean;
|
||||
function sortAndDeduplicateDiagnostics(diagnostics: ReadonlyArray<Diagnostic>): Diagnostic[];
|
||||
}
|
||||
declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any;
|
||||
declare function clearTimeout(handle: any): void;
|
||||
@@ -2860,26 +2863,14 @@ declare namespace ts {
|
||||
callback: FileWatcherCallback;
|
||||
mtime?: Date;
|
||||
}
|
||||
/**
|
||||
* Partial interface of the System thats needed to support the caching of directory structure
|
||||
*/
|
||||
interface DirectoryStructureHost {
|
||||
interface System {
|
||||
args: string[];
|
||||
newLine: string;
|
||||
useCaseSensitiveFileNames: boolean;
|
||||
write(s: string): void;
|
||||
readFile(path: string, encoding?: string): string | undefined;
|
||||
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
|
||||
fileExists(path: string): boolean;
|
||||
directoryExists(path: string): boolean;
|
||||
createDirectory(path: string): void;
|
||||
getCurrentDirectory(): string;
|
||||
getDirectories(path: string): string[];
|
||||
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
exit(exitCode?: number): void;
|
||||
}
|
||||
interface System extends DirectoryStructureHost {
|
||||
args: string[];
|
||||
getFileSize?(path: string): number;
|
||||
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
|
||||
/**
|
||||
* @pollingInterval - this parameter is used in polling-based watchers and ignored in watchers that
|
||||
* use native OS file watching
|
||||
@@ -2887,7 +2878,13 @@ declare namespace ts {
|
||||
watchFile?(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
watchDirectory?(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
resolvePath(path: string): string;
|
||||
fileExists(path: string): boolean;
|
||||
directoryExists(path: string): boolean;
|
||||
createDirectory(path: string): void;
|
||||
getExecutingFilePath(): string;
|
||||
getCurrentDirectory(): string;
|
||||
getDirectories(path: string): string[];
|
||||
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
getModifiedTime?(path: string): Date;
|
||||
/**
|
||||
* This should be cryptographically secure.
|
||||
@@ -2895,6 +2892,7 @@ declare namespace ts {
|
||||
*/
|
||||
createHash?(data: string): string;
|
||||
getMemoryUsage?(): number;
|
||||
exit(exitCode?: number): void;
|
||||
realpath?(path: string): string;
|
||||
setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
clearTimeout?(timeoutId: any): void;
|
||||
@@ -3907,17 +3905,6 @@ declare namespace ts {
|
||||
declare namespace ts {
|
||||
function createPrinter(printerOptions?: PrinterOptions, handlers?: PrintHandlers): Printer;
|
||||
}
|
||||
declare namespace ts {
|
||||
interface EmitOutput {
|
||||
outputFiles: OutputFile[];
|
||||
emitSkipped: boolean;
|
||||
}
|
||||
interface OutputFile {
|
||||
name: string;
|
||||
writeByteOrderMark: boolean;
|
||||
text: string;
|
||||
}
|
||||
}
|
||||
declare namespace ts {
|
||||
function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName?: string): string | undefined;
|
||||
function resolveTripleslashReference(moduleName: string, containingFile: string): string;
|
||||
@@ -4128,7 +4115,8 @@ declare namespace ts {
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion;
|
||||
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean;
|
||||
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray<number>, formatOptions: FormatCodeSettings): ReadonlyArray<CodeAction>;
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray<number>, formatOptions: FormatCodeSettings): ReadonlyArray<CodeFixAction>;
|
||||
getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings): CombinedCodeActions;
|
||||
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
@@ -4144,6 +4132,10 @@ declare namespace ts {
|
||||
getProgram(): Program;
|
||||
dispose(): void;
|
||||
}
|
||||
interface CombinedCodeFixScope {
|
||||
type: "file";
|
||||
fileName: string;
|
||||
}
|
||||
interface GetCompletionsAtPositionOptions {
|
||||
includeExternalModuleExports: boolean;
|
||||
includeInsertTextCompletions: boolean;
|
||||
@@ -4221,6 +4213,17 @@ declare namespace ts {
|
||||
*/
|
||||
commands?: CodeActionCommand[];
|
||||
}
|
||||
interface CodeFixAction extends CodeAction {
|
||||
/**
|
||||
* If present, one may call 'getCombinedCodeFix' with this fixId.
|
||||
* This may be omitted to indicate that the code fix can't be applied in a group.
|
||||
*/
|
||||
fixId?: {};
|
||||
}
|
||||
interface CombinedCodeActions {
|
||||
changes: ReadonlyArray<FileTextChanges>;
|
||||
commands: ReadonlyArray<CodeActionCommand> | undefined;
|
||||
}
|
||||
type CodeActionCommand = InstallPackageAction;
|
||||
interface InstallPackageAction {
|
||||
}
|
||||
@@ -4836,6 +4839,8 @@ declare namespace ts.server {
|
||||
};
|
||||
};
|
||||
interface ServerHost extends System {
|
||||
watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
clearTimeout(timeoutId: any): void;
|
||||
setImmediate(callback: (...args: any[]) => void, ...args: any[]): any;
|
||||
@@ -5064,6 +5069,7 @@ declare namespace ts.server.protocol {
|
||||
DocCommentTemplate = "docCommentTemplate",
|
||||
CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects",
|
||||
GetCodeFixes = "getCodeFixes",
|
||||
GetCombinedCodeFix = "getCombinedCodeFix",
|
||||
ApplyCodeActionCommand = "applyCodeActionCommand",
|
||||
GetSupportedCodeFixes = "getSupportedCodeFixes",
|
||||
GetApplicableRefactors = "getApplicableRefactors",
|
||||
@@ -5426,6 +5432,13 @@ declare namespace ts.server.protocol {
|
||||
command: CommandTypes.GetCodeFixes;
|
||||
arguments: CodeFixRequestArgs;
|
||||
}
|
||||
interface GetCombinedCodeFixRequest extends Request {
|
||||
command: CommandTypes.GetCombinedCodeFix;
|
||||
arguments: GetCombinedCodeFixRequestArgs;
|
||||
}
|
||||
interface GetCombinedCodeFixResponse extends Response {
|
||||
body: CombinedCodeActions;
|
||||
}
|
||||
interface ApplyCodeActionCommandRequest extends Request {
|
||||
command: CommandTypes.ApplyCodeActionCommand;
|
||||
arguments: ApplyCodeActionCommandRequestArgs;
|
||||
@@ -5459,6 +5472,14 @@ declare namespace ts.server.protocol {
|
||||
*/
|
||||
errorCodes?: ReadonlyArray<number>;
|
||||
}
|
||||
interface GetCombinedCodeFixRequestArgs {
|
||||
scope: GetCombinedCodeFixScope;
|
||||
fixId: {};
|
||||
}
|
||||
interface GetCombinedCodeFixScope {
|
||||
type: "file";
|
||||
args: FileRequestArgs;
|
||||
}
|
||||
interface ApplyCodeActionCommandRequestArgs {
|
||||
/** May also be an array of commands. */
|
||||
command: {};
|
||||
@@ -6201,7 +6222,7 @@ declare namespace ts.server.protocol {
|
||||
}
|
||||
interface CodeFixResponse extends Response {
|
||||
/** The code actions that are available */
|
||||
body?: CodeAction[];
|
||||
body?: CodeFixAction[];
|
||||
}
|
||||
interface CodeAction {
|
||||
/** Description of the code action to display in the UI of the editor */
|
||||
@@ -6211,6 +6232,17 @@ declare namespace ts.server.protocol {
|
||||
/** A command is an opaque object that should be passed to `ApplyCodeActionCommandRequestArgs` without modification. */
|
||||
commands?: {}[];
|
||||
}
|
||||
interface CombinedCodeActions {
|
||||
changes: ReadonlyArray<FileCodeEdits>;
|
||||
commands?: ReadonlyArray<{}>;
|
||||
}
|
||||
interface CodeFixAction extends CodeAction {
|
||||
/**
|
||||
* If present, one may call 'getCombinedCodeFix' with this fixId.
|
||||
* This may be omitted to indicate that the code fix can't be applied in a group.
|
||||
*/
|
||||
fixId?: {};
|
||||
}
|
||||
/**
|
||||
* Format and format on key response message.
|
||||
*/
|
||||
@@ -7250,7 +7282,7 @@ declare namespace ts.server {
|
||||
private getCombinedCodeFix({scope, fixId}, simplifiedResult);
|
||||
private applyCodeActionCommand(args);
|
||||
private getStartAndEndPosition(args, scriptInfo);
|
||||
private mapCodeAction(project, {description, changes: unmappedChanges, commands});
|
||||
private mapCodeAction(project, {description, changes: unmappedChanges, commands, fixId});
|
||||
private mapTextChangesToCodeEdits(project, textChanges);
|
||||
private mapTextChangesToCodeEditsUsingScriptinfo(textChanges, scriptInfo);
|
||||
private convertTextChangeToCodeEdit(change, scriptInfo);
|
||||
@@ -7291,6 +7323,7 @@ declare namespace ts.server {
|
||||
open(newText: string): void;
|
||||
close(fileExists?: boolean): void;
|
||||
getSnapshot(): IScriptSnapshot;
|
||||
private ensureRealPath();
|
||||
getFormatCodeSettings(): FormatCodeSettings;
|
||||
attachToProject(project: Project): boolean;
|
||||
isAttached(project: Project): boolean;
|
||||
@@ -7344,6 +7377,17 @@ declare namespace ts.server {
|
||||
onProjectClosed(project: Project): void;
|
||||
}
|
||||
}
|
||||
declare namespace ts {
|
||||
interface EmitOutput {
|
||||
outputFiles: OutputFile[];
|
||||
emitSkipped: boolean;
|
||||
}
|
||||
interface OutputFile {
|
||||
name: string;
|
||||
writeByteOrderMark: boolean;
|
||||
text: string;
|
||||
}
|
||||
}
|
||||
declare namespace ts.server {
|
||||
enum ProjectKind {
|
||||
Inferred = 0,
|
||||
@@ -7387,7 +7431,6 @@ declare namespace ts.server {
|
||||
private documentRegistry;
|
||||
private compilerOptions;
|
||||
compileOnSaveEnabled: boolean;
|
||||
directoryStructureHost: DirectoryStructureHost;
|
||||
private rootFiles;
|
||||
private rootFilesMap;
|
||||
private program;
|
||||
@@ -7400,7 +7443,7 @@ declare namespace ts.server {
|
||||
languageServiceEnabled: boolean;
|
||||
readonly trace?: (s: string) => void;
|
||||
readonly realpath?: (path: string) => string;
|
||||
private builder;
|
||||
private builderState;
|
||||
/**
|
||||
* Set of files names that were updated since the last call to getChangesSinceVersion.
|
||||
*/
|
||||
@@ -7461,7 +7504,6 @@ declare namespace ts.server {
|
||||
getGlobalProjectErrors(): ReadonlyArray<Diagnostic>;
|
||||
getAllProjectErrors(): ReadonlyArray<Diagnostic>;
|
||||
getLanguageService(ensureSynchronized?: boolean): LanguageService;
|
||||
private ensureBuilder();
|
||||
private shouldEmitFile(scriptInfo);
|
||||
getCompileOnSaveAffectedFileList(scriptInfo: ScriptInfo): string[];
|
||||
/**
|
||||
@@ -7663,10 +7705,6 @@ declare namespace ts.server {
|
||||
function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin;
|
||||
function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind;
|
||||
function convertScriptKindName(scriptKindName: protocol.ScriptKindName): ScriptKind.Unknown | ScriptKind.JS | ScriptKind.JSX | ScriptKind.TS | ScriptKind.TSX;
|
||||
/**
|
||||
* This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project.
|
||||
*/
|
||||
function combineProjectOutput<T>(projects: ReadonlyArray<Project>, action: (project: Project) => ReadonlyArray<T>, comparer?: (a: T, b: T) => number, areEqual?: (a: T, b: T) => boolean): T[];
|
||||
interface HostConfiguration {
|
||||
formatCodeOptions: FormatCodeSettings;
|
||||
hostInfo: string;
|
||||
@@ -7783,7 +7821,6 @@ declare namespace ts.server {
|
||||
* @param forceInferredProjectsRefresh when true updates the inferred projects even if there is no pending work to update the files/project structures
|
||||
*/
|
||||
private ensureProjectStructuresUptoDate(forceInferredProjectsRefresh?);
|
||||
private findContainingExternalProject(fileName);
|
||||
getFormatCodeOptions(file?: NormalizedPath): FormatCodeSettings;
|
||||
private updateProjectGraphs(projects);
|
||||
private onSourceFileChanged(fileName, eventKind);
|
||||
@@ -7802,6 +7839,7 @@ declare namespace ts.server {
|
||||
*/
|
||||
private closeOpenFile(info);
|
||||
private deleteOrphanScriptInfoNotInAnyProject();
|
||||
private deleteScriptInfo(info);
|
||||
private configFileExists(configFileName, canonicalConfigFilePath, info);
|
||||
private setConfigFileExistenceByNewConfiguredProject(project);
|
||||
/**
|
||||
@@ -7860,7 +7898,9 @@ declare namespace ts.server {
|
||||
getScriptInfo(uncheckedFileName: string): ScriptInfo;
|
||||
private watchClosedScriptInfo(info);
|
||||
private stopWatchingScriptInfo(info);
|
||||
getOrCreateScriptInfoForNormalizedPath(fileName: NormalizedPath, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, hostToQueryFileExistsOn?: DirectoryStructureHost): ScriptInfo;
|
||||
getOrCreateScriptInfoForNormalizedPath(fileName: NormalizedPath, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, hostToQueryFileExistsOn?: {
|
||||
fileExists(path: string): boolean;
|
||||
}): ScriptInfo;
|
||||
private getOrCreateScriptInfoWorker(fileName, currentDirectory, openedByClient, fileContent?, scriptKind?, hasMixedContent?, hostToQueryFileExistsOn?);
|
||||
/**
|
||||
* This gets the script info for the normalized path. If the path is not rooted disk path then the open script info with project root context is preferred
|
||||
@@ -7901,6 +7941,7 @@ declare namespace ts.server {
|
||||
* @param fileContent is a known version of the file content that is more up to date than the one on disk
|
||||
*/
|
||||
openClientFile(fileName: string, fileContent?: string, scriptKind?: ScriptKind, projectRootPath?: string): OpenConfiguredProjectResult;
|
||||
private findExternalProjetContainingOpenScriptInfo(info);
|
||||
openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult;
|
||||
/**
|
||||
* Close file whose contents is managed by the client
|
||||
|
||||
+283
-28
@@ -2297,6 +2297,7 @@ declare namespace ts {
|
||||
charset?: string;
|
||||
checkJs?: boolean;
|
||||
declaration?: boolean;
|
||||
emitDeclarationsOnly?: boolean;
|
||||
declarationDir?: string;
|
||||
disableSizeLimit?: boolean;
|
||||
downlevelIteration?: boolean;
|
||||
@@ -2537,6 +2538,7 @@ declare namespace ts {
|
||||
*/
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): (ResolvedTypeReferenceDirective | undefined)[];
|
||||
getEnvironmentVariable?(name: string): string;
|
||||
createHash?(data: string): string;
|
||||
}
|
||||
interface SourceMapRange extends TextRange {
|
||||
source?: SourceMapSource;
|
||||
@@ -2838,12 +2840,13 @@ declare namespace ts {
|
||||
}
|
||||
}
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "2.7";
|
||||
const versionMajorMinor = "2.8";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
declare namespace ts {
|
||||
function isExternalModuleNameRelative(moduleName: string): boolean;
|
||||
function sortAndDeduplicateDiagnostics(diagnostics: ReadonlyArray<Diagnostic>): Diagnostic[];
|
||||
}
|
||||
declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any;
|
||||
declare function clearTimeout(handle: any): void;
|
||||
@@ -2860,26 +2863,14 @@ declare namespace ts {
|
||||
callback: FileWatcherCallback;
|
||||
mtime?: Date;
|
||||
}
|
||||
/**
|
||||
* Partial interface of the System thats needed to support the caching of directory structure
|
||||
*/
|
||||
interface DirectoryStructureHost {
|
||||
interface System {
|
||||
args: string[];
|
||||
newLine: string;
|
||||
useCaseSensitiveFileNames: boolean;
|
||||
write(s: string): void;
|
||||
readFile(path: string, encoding?: string): string | undefined;
|
||||
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
|
||||
fileExists(path: string): boolean;
|
||||
directoryExists(path: string): boolean;
|
||||
createDirectory(path: string): void;
|
||||
getCurrentDirectory(): string;
|
||||
getDirectories(path: string): string[];
|
||||
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
exit(exitCode?: number): void;
|
||||
}
|
||||
interface System extends DirectoryStructureHost {
|
||||
args: string[];
|
||||
getFileSize?(path: string): number;
|
||||
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
|
||||
/**
|
||||
* @pollingInterval - this parameter is used in polling-based watchers and ignored in watchers that
|
||||
* use native OS file watching
|
||||
@@ -2887,7 +2878,13 @@ declare namespace ts {
|
||||
watchFile?(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
watchDirectory?(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
resolvePath(path: string): string;
|
||||
fileExists(path: string): boolean;
|
||||
directoryExists(path: string): boolean;
|
||||
createDirectory(path: string): void;
|
||||
getExecutingFilePath(): string;
|
||||
getCurrentDirectory(): string;
|
||||
getDirectories(path: string): string[];
|
||||
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
getModifiedTime?(path: string): Date;
|
||||
/**
|
||||
* This should be cryptographically secure.
|
||||
@@ -2895,6 +2892,7 @@ declare namespace ts {
|
||||
*/
|
||||
createHash?(data: string): string;
|
||||
getMemoryUsage?(): number;
|
||||
exit(exitCode?: number): void;
|
||||
realpath?(path: string): string;
|
||||
setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
clearTimeout?(timeoutId: any): void;
|
||||
@@ -3854,17 +3852,6 @@ declare namespace ts {
|
||||
declare namespace ts {
|
||||
function createPrinter(printerOptions?: PrinterOptions, handlers?: PrintHandlers): Printer;
|
||||
}
|
||||
declare namespace ts {
|
||||
interface EmitOutput {
|
||||
outputFiles: OutputFile[];
|
||||
emitSkipped: boolean;
|
||||
}
|
||||
interface OutputFile {
|
||||
name: string;
|
||||
writeByteOrderMark: boolean;
|
||||
text: string;
|
||||
}
|
||||
}
|
||||
declare namespace ts {
|
||||
function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName?: string): string | undefined;
|
||||
function resolveTripleslashReference(moduleName: string, containingFile: string): string;
|
||||
@@ -3894,6 +3881,258 @@ declare namespace ts {
|
||||
*/
|
||||
function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program;
|
||||
}
|
||||
declare namespace ts {
|
||||
interface EmitOutput {
|
||||
outputFiles: OutputFile[];
|
||||
emitSkipped: boolean;
|
||||
}
|
||||
interface OutputFile {
|
||||
name: string;
|
||||
writeByteOrderMark: boolean;
|
||||
text: string;
|
||||
}
|
||||
}
|
||||
declare namespace ts {
|
||||
type AffectedFileResult<T> = {
|
||||
result: T;
|
||||
affected: SourceFile | Program;
|
||||
} | undefined;
|
||||
interface BuilderProgramHost {
|
||||
/**
|
||||
* return true if file names are treated with case sensitivity
|
||||
*/
|
||||
useCaseSensitiveFileNames(): boolean;
|
||||
/**
|
||||
* If provided this would be used this hash instead of actual file shape text for detecting changes
|
||||
*/
|
||||
createHash?: (data: string) => string;
|
||||
/**
|
||||
* When emit or emitNextAffectedFile are called without writeFile,
|
||||
* this callback if present would be used to write files
|
||||
*/
|
||||
writeFile?: WriteFileCallback;
|
||||
}
|
||||
/**
|
||||
* Builder to manage the program state changes
|
||||
*/
|
||||
interface BuilderProgram {
|
||||
/**
|
||||
* Returns current program
|
||||
*/
|
||||
getProgram(): Program;
|
||||
/**
|
||||
* Get compiler options of the program
|
||||
*/
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
/**
|
||||
* Get the source file in the program with file name
|
||||
*/
|
||||
getSourceFile(fileName: string): SourceFile | undefined;
|
||||
/**
|
||||
* Get a list of files in the program
|
||||
*/
|
||||
getSourceFiles(): ReadonlyArray<SourceFile>;
|
||||
/**
|
||||
* Get the diagnostics for compiler options
|
||||
*/
|
||||
getOptionsDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
/**
|
||||
* Get the diagnostics that dont belong to any file
|
||||
*/
|
||||
getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
/**
|
||||
* Get the syntax diagnostics, for all source files if source file is not supplied
|
||||
*/
|
||||
getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
/**
|
||||
* Get all the dependencies of the file
|
||||
*/
|
||||
getAllDependencies(sourceFile: SourceFile): ReadonlyArray<string>;
|
||||
/**
|
||||
* Gets the semantic diagnostics from the program corresponding to this state of file (if provided) or whole program
|
||||
* The semantic diagnostics are cached and managed here
|
||||
* Note that it is assumed that when asked about semantic diagnostics through this API,
|
||||
* the file has been taken out of affected files so it is safe to use cache or get from program and cache the diagnostics
|
||||
* In case of SemanticDiagnosticsBuilderProgram if the source file is not provided,
|
||||
* it will iterate through all the affected files, to ensure that cache stays valid and yet provide a way to get all semantic diagnostics
|
||||
*/
|
||||
getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
/**
|
||||
* Emits the JavaScript and declaration files.
|
||||
* When targetSource file is specified, emits the files corresponding to that source file,
|
||||
* otherwise for the whole program.
|
||||
* In case of EmitAndSemanticDiagnosticsBuilderProgram, when targetSourceFile is specified,
|
||||
* it is assumed that that file is handled from affected file list. If targetSourceFile is not specified,
|
||||
* it will only emit all the affected files instead of whole program
|
||||
*
|
||||
* The first of writeFile if provided, writeFile of BuilderProgramHost if provided, writeFile of compiler host
|
||||
* in that order would be used to write the files
|
||||
*/
|
||||
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult;
|
||||
/**
|
||||
* Get the current directory of the program
|
||||
*/
|
||||
getCurrentDirectory(): string;
|
||||
}
|
||||
/**
|
||||
* The builder that caches the semantic diagnostics for the program and handles the changed files and affected files
|
||||
*/
|
||||
interface SemanticDiagnosticsBuilderProgram extends BuilderProgram {
|
||||
/**
|
||||
* Gets the semantic diagnostics from the program for the next affected file and caches it
|
||||
* Returns undefined if the iteration is complete
|
||||
*/
|
||||
getSemanticDiagnosticsOfNextAffectedFile(cancellationToken?: CancellationToken, ignoreSourceFile?: (sourceFile: SourceFile) => boolean): AffectedFileResult<ReadonlyArray<Diagnostic>>;
|
||||
}
|
||||
/**
|
||||
* 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 {
|
||||
/**
|
||||
* 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
|
||||
* in that order would be used to write the files
|
||||
*/
|
||||
emitNextAffectedFile(writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): AffectedFileResult<EmitResult>;
|
||||
}
|
||||
/**
|
||||
* Create the builder to manage semantic diagnostics and cache them
|
||||
*/
|
||||
function createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: SemanticDiagnosticsBuilderProgram): SemanticDiagnosticsBuilderProgram;
|
||||
function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram): SemanticDiagnosticsBuilderProgram;
|
||||
/**
|
||||
* Create the builder that can handle the changes in program and iterate through changed files
|
||||
* to emit the those files and manage semantic diagnostics cache as well
|
||||
*/
|
||||
function createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram): EmitAndSemanticDiagnosticsBuilderProgram;
|
||||
function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram): EmitAndSemanticDiagnosticsBuilderProgram;
|
||||
/**
|
||||
* Creates a builder thats just abstraction over program and can be used with watch
|
||||
*/
|
||||
function createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram?: BuilderProgram): BuilderProgram;
|
||||
function createAbstractBuilder(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: BuilderProgram): BuilderProgram;
|
||||
}
|
||||
declare namespace ts {
|
||||
type DiagnosticReporter = (diagnostic: Diagnostic) => void;
|
||||
type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string) => void;
|
||||
type CreateProgram<T extends BuilderProgram> = (rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: T) => T;
|
||||
interface WatchCompilerHost<T extends BuilderProgram> {
|
||||
/**
|
||||
* Used to create the program when need for program creation or recreation detected
|
||||
*/
|
||||
createProgram: CreateProgram<T>;
|
||||
/** If provided, callback to invoke after every new program creation */
|
||||
afterProgramCreate?(program: T): void;
|
||||
/** If provided, called with Diagnostic message that informs about change in watch status */
|
||||
onWatchStatusChange?(diagnostic: Diagnostic, newLine: string): void;
|
||||
useCaseSensitiveFileNames(): boolean;
|
||||
getNewLine(): string;
|
||||
getCurrentDirectory(): string;
|
||||
getDefaultLibFileName(options: CompilerOptions): string;
|
||||
getDefaultLibLocation?(): string;
|
||||
createHash?(data: string): string;
|
||||
/**
|
||||
* Use to check file presence for source files and
|
||||
* if resolveModuleNames is not provided (complier is in charge of module resolution) then module files as well
|
||||
*/
|
||||
fileExists(path: string): boolean;
|
||||
/**
|
||||
* Use to read file text for source files and
|
||||
* if resolveModuleNames is not provided (complier is in charge of module resolution) then module files as well
|
||||
*/
|
||||
readFile(path: string, encoding?: string): string | undefined;
|
||||
/** If provided, used for module resolution as well as to handle directory structure */
|
||||
directoryExists?(path: string): boolean;
|
||||
/** If provided, used in resolutions as well as handling directory structure */
|
||||
getDirectories?(path: string): string[];
|
||||
/** If provided, used to cache and handle directory structure modifications */
|
||||
readDirectory?(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
/** Symbol links resolution */
|
||||
realpath?(path: string): string;
|
||||
/** If provided would be used to write log about compilation */
|
||||
trace?(s: string): void;
|
||||
/** If provided is used to get the environment variable */
|
||||
getEnvironmentVariable?(name: string): string;
|
||||
/** If provided, used to resolve the module names, otherwise typescript's default module resolution */
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];
|
||||
/** If provided, used to resolve type reference directives, otherwise typescript's default resolution */
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): (ResolvedTypeReferenceDirective | undefined)[];
|
||||
/** Used to watch changes in source files, missing files needed to update the program or config file */
|
||||
watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
/** Used to watch resolved module's failed lookup locations, config file specs, type roots where auto type reference directives are added */
|
||||
watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
/** If provided, will be used to set delayed compilation, so that multiple changes in short span are compiled together */
|
||||
setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
/** If provided, will be used to reset existing delayed compilation */
|
||||
clearTimeout?(timeoutId: any): void;
|
||||
}
|
||||
/**
|
||||
* Host to create watch with root files and options
|
||||
*/
|
||||
interface WatchCompilerHostOfFilesAndCompilerOptions<T extends BuilderProgram> extends WatchCompilerHost<T> {
|
||||
/** root files to use to generate program */
|
||||
rootFiles: string[];
|
||||
/** Compiler options */
|
||||
options: CompilerOptions;
|
||||
}
|
||||
/**
|
||||
* Reports config file diagnostics
|
||||
*/
|
||||
interface ConfigFileDiagnosticsReporter {
|
||||
/**
|
||||
* Reports the diagnostics in reading/writing or parsing of the config file
|
||||
*/
|
||||
onConfigFileDiagnostic: DiagnosticReporter;
|
||||
/**
|
||||
* Reports unrecoverable error when parsing config file
|
||||
*/
|
||||
onUnRecoverableConfigFileDiagnostic: DiagnosticReporter;
|
||||
}
|
||||
/**
|
||||
* Host to create watch with config file
|
||||
*/
|
||||
interface WatchCompilerHostOfConfigFile<T extends BuilderProgram> extends WatchCompilerHost<T>, ConfigFileDiagnosticsReporter {
|
||||
/** Name of the config file to compile */
|
||||
configFileName: string;
|
||||
/** Options to extend */
|
||||
optionsToExtend?: CompilerOptions;
|
||||
/**
|
||||
* Used to generate source file names from the config file and its include, exclude, files rules
|
||||
* and also to cache the directory stucture
|
||||
*/
|
||||
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
}
|
||||
interface Watch<T> {
|
||||
/** Synchronize with host and get updated program */
|
||||
getProgram(): T;
|
||||
}
|
||||
/**
|
||||
* Creates the watch what generates program using the config file
|
||||
*/
|
||||
interface WatchOfConfigFile<T> extends Watch<T> {
|
||||
}
|
||||
/**
|
||||
* Creates the watch that generates program using the root files and compiler options
|
||||
*/
|
||||
interface WatchOfFilesAndCompilerOptions<T> extends Watch<T> {
|
||||
/** Updates the root files in the program, only if this is not config file compilation */
|
||||
updateRootFileNames(fileNames: string[]): void;
|
||||
}
|
||||
/**
|
||||
* Create the watch compiler host for either configFile or fileNames and its options
|
||||
*/
|
||||
function createWatchCompilerHost<T extends BuilderProgram>(rootFiles: string[], options: CompilerOptions, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfFilesAndCompilerOptions<T>;
|
||||
function createWatchCompilerHost<T extends BuilderProgram>(configFileName: string, optionsToExtend: CompilerOptions | undefined, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfConfigFile<T>;
|
||||
/**
|
||||
* Creates the watch from the host for root files and compiler options
|
||||
*/
|
||||
function createWatchProgram<T extends BuilderProgram>(host: WatchCompilerHostOfFilesAndCompilerOptions<T>): WatchOfFilesAndCompilerOptions<T>;
|
||||
/**
|
||||
* Creates the watch from the host for config file
|
||||
*/
|
||||
function createWatchProgram<T extends BuilderProgram>(host: WatchCompilerHostOfConfigFile<T>): WatchOfConfigFile<T>;
|
||||
}
|
||||
declare namespace ts {
|
||||
function parseCommandLine(commandLine: ReadonlyArray<string>, readFile?: (path: string) => string | undefined): ParsedCommandLine;
|
||||
/**
|
||||
@@ -4128,7 +4367,8 @@ declare namespace ts {
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion;
|
||||
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean;
|
||||
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray<number>, formatOptions: FormatCodeSettings): ReadonlyArray<CodeAction>;
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray<number>, formatOptions: FormatCodeSettings): ReadonlyArray<CodeFixAction>;
|
||||
getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings): CombinedCodeActions;
|
||||
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
|
||||
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
|
||||
@@ -4144,6 +4384,10 @@ declare namespace ts {
|
||||
getProgram(): Program;
|
||||
dispose(): void;
|
||||
}
|
||||
interface CombinedCodeFixScope {
|
||||
type: "file";
|
||||
fileName: string;
|
||||
}
|
||||
interface GetCompletionsAtPositionOptions {
|
||||
includeExternalModuleExports: boolean;
|
||||
includeInsertTextCompletions: boolean;
|
||||
@@ -4221,6 +4465,17 @@ declare namespace ts {
|
||||
*/
|
||||
commands?: CodeActionCommand[];
|
||||
}
|
||||
interface CodeFixAction extends CodeAction {
|
||||
/**
|
||||
* If present, one may call 'getCombinedCodeFix' with this fixId.
|
||||
* This may be omitted to indicate that the code fix can't be applied in a group.
|
||||
*/
|
||||
fixId?: {};
|
||||
}
|
||||
interface CombinedCodeActions {
|
||||
changes: ReadonlyArray<FileTextChanges>;
|
||||
commands: ReadonlyArray<CodeActionCommand> | undefined;
|
||||
}
|
||||
type CodeActionCommand = InstallPackageAction;
|
||||
interface InstallPackageAction {
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
tests/cases/compiler/assigningFromObjectToAnythingElse.ts(3,1): error TS2322: Type 'Object' is not assignable to type 'RegExp'.
|
||||
The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?
|
||||
Property 'exec' is missing in type 'Object'.
|
||||
tests/cases/compiler/assigningFromObjectToAnythingElse.ts(5,17): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/compiler/assigningFromObjectToAnythingElse.ts(6,17): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/compiler/assigningFromObjectToAnythingElse.ts(5,31): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/compiler/assigningFromObjectToAnythingElse.ts(6,31): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/compiler/assigningFromObjectToAnythingElse.ts(8,5): error TS2322: Type 'Object' is not assignable to type 'Error'.
|
||||
The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?
|
||||
Property 'name' is missing in type 'Object'.
|
||||
@@ -18,10 +18,10 @@ tests/cases/compiler/assigningFromObjectToAnythingElse.ts(8,5): error TS2322: Ty
|
||||
!!! error TS2322: Property 'exec' is missing in type 'Object'.
|
||||
|
||||
var a: String = Object.create<Object>("");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~
|
||||
!!! error TS2558: Expected 0 type arguments, but got 1.
|
||||
var c: String = Object.create<Number>(1);
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~
|
||||
!!! error TS2558: Expected 0 type arguments, but got 1.
|
||||
|
||||
var w: Error = new Object();
|
||||
|
||||
@@ -0,0 +1,497 @@
|
||||
//// [asyncWithVarShadowing_es6.ts]
|
||||
// https://github.com/Microsoft/TypeScript/issues/20461
|
||||
declare const y: any;
|
||||
|
||||
async function fn1(x) {
|
||||
var x;
|
||||
}
|
||||
|
||||
async function fn2(x) {
|
||||
var x, z;
|
||||
}
|
||||
|
||||
async function fn3(x) {
|
||||
var z;
|
||||
}
|
||||
|
||||
async function fn4(x) {
|
||||
var x = y;
|
||||
}
|
||||
|
||||
async function fn5(x) {
|
||||
var { x } = y;
|
||||
}
|
||||
|
||||
async function fn6(x) {
|
||||
var { x, z } = y;
|
||||
}
|
||||
|
||||
async function fn7(x) {
|
||||
var { x = y } = y;
|
||||
}
|
||||
|
||||
async function fn8(x) {
|
||||
var { z: x } = y;
|
||||
}
|
||||
|
||||
async function fn9(x) {
|
||||
var { z: { x } } = y;
|
||||
}
|
||||
|
||||
async function fn10(x) {
|
||||
var { z: { x } = y } = y;
|
||||
}
|
||||
|
||||
async function fn11(x) {
|
||||
var { ...x } = y;
|
||||
}
|
||||
|
||||
async function fn12(x) {
|
||||
var [x] = y;
|
||||
}
|
||||
|
||||
async function fn13(x) {
|
||||
var [x = y] = y;
|
||||
}
|
||||
|
||||
async function fn14(x) {
|
||||
var [, x] = y;
|
||||
}
|
||||
|
||||
async function fn15(x) {
|
||||
var [...x] = y;
|
||||
}
|
||||
|
||||
async function fn16(x) {
|
||||
var [[x]] = y;
|
||||
}
|
||||
|
||||
async function fn17(x) {
|
||||
var [[x] = y] = y;
|
||||
}
|
||||
|
||||
async function fn18({ x }) {
|
||||
var x;
|
||||
}
|
||||
|
||||
async function fn19([x]) {
|
||||
var x;
|
||||
}
|
||||
|
||||
async function fn20(x) {
|
||||
{
|
||||
var x;
|
||||
}
|
||||
}
|
||||
|
||||
async function fn21(x) {
|
||||
if (y) {
|
||||
var x;
|
||||
}
|
||||
}
|
||||
|
||||
async function fn22(x) {
|
||||
if (y) {
|
||||
}
|
||||
else {
|
||||
var x;
|
||||
}
|
||||
}
|
||||
|
||||
async function fn23(x) {
|
||||
try {
|
||||
var x;
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
async function fn24(x) {
|
||||
try {
|
||||
|
||||
}
|
||||
catch (e) {
|
||||
var x;
|
||||
}
|
||||
}
|
||||
|
||||
async function fn25(x) {
|
||||
try {
|
||||
|
||||
}
|
||||
catch (x) {
|
||||
var x;
|
||||
}
|
||||
}
|
||||
|
||||
async function fn26(x) {
|
||||
try {
|
||||
|
||||
}
|
||||
catch ({ x }) {
|
||||
var x;
|
||||
}
|
||||
}
|
||||
|
||||
async function fn27(x) {
|
||||
try {
|
||||
}
|
||||
finally {
|
||||
var x;
|
||||
}
|
||||
}
|
||||
|
||||
async function fn28(x) {
|
||||
while (y) {
|
||||
var x;
|
||||
}
|
||||
}
|
||||
|
||||
async function fn29(x) {
|
||||
do {
|
||||
var x;
|
||||
}
|
||||
while (y);
|
||||
}
|
||||
|
||||
async function fn30(x) {
|
||||
for (var x = y;;) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
async function fn31(x) {
|
||||
for (var { x } = y;;) {
|
||||
}
|
||||
}
|
||||
|
||||
async function fn32(x) {
|
||||
for (;;) {
|
||||
var x;
|
||||
}
|
||||
}
|
||||
|
||||
async function fn33(x: string) {
|
||||
for (var x in y) {
|
||||
}
|
||||
}
|
||||
|
||||
async function fn34(x) {
|
||||
for (var z in y) {
|
||||
var x;
|
||||
}
|
||||
}
|
||||
|
||||
async function fn35(x) {
|
||||
for (var x of y) {
|
||||
}
|
||||
}
|
||||
|
||||
async function fn36(x) {
|
||||
for (var { x } of y) {
|
||||
}
|
||||
}
|
||||
|
||||
async function fn37(x) {
|
||||
for (var z of y) {
|
||||
var x;
|
||||
}
|
||||
}
|
||||
|
||||
async function fn38(x) {
|
||||
switch (y) {
|
||||
case y:
|
||||
var x;
|
||||
}
|
||||
}
|
||||
|
||||
async function fn39(x) {
|
||||
foo: {
|
||||
var x;
|
||||
break foo;
|
||||
}
|
||||
}
|
||||
|
||||
async function fn40(x) {
|
||||
try {
|
||||
|
||||
}
|
||||
catch {
|
||||
var x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [asyncWithVarShadowing_es6.js]
|
||||
function fn1(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn2(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
});
|
||||
var x, z;
|
||||
}
|
||||
function fn3(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
var z;
|
||||
});
|
||||
}
|
||||
function fn4(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
x = y;
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn5(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
({ x } = y);
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn6(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
({ x, z } = y);
|
||||
});
|
||||
var x, z;
|
||||
}
|
||||
function fn7(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
({ x = y } = y);
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn8(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
({ z: x } = y);
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn9(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
({ z: { x } } = y);
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn10(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
({ z: { x } = y } = y);
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn11(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
x = __rest(y, []);
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn12(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
[x] = y;
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn13(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
[x = y] = y;
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn14(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
[, x] = y;
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn15(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
[...x] = y;
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn16(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
[[x]] = y;
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn17(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
[[x] = y] = y;
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn18({ x }) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn19([x]) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn20(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
{
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn21(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (y) {
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn22(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (y) {
|
||||
}
|
||||
else {
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn23(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn24(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn25(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
}
|
||||
catch (x) {
|
||||
var x;
|
||||
}
|
||||
});
|
||||
}
|
||||
function fn26(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
}
|
||||
catch ({ x }) {
|
||||
var x;
|
||||
}
|
||||
});
|
||||
}
|
||||
function fn27(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
}
|
||||
finally {
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn28(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
while (y) {
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn29(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
do {
|
||||
} while (y);
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn30(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
for (x = y;;) {
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn31(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
for ({ x } = y;;) {
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn32(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
for (;;) {
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn33(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
for (x in y) {
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn34(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
for (var z in y) {
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn35(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
for (x of y) {
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn36(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
for ({ x } of y) {
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn37(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
for (var z of y) {
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn38(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
switch (y) {
|
||||
case y:
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn39(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
foo: {
|
||||
break foo;
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
function fn40(x) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
}
|
||||
catch (_a) {
|
||||
}
|
||||
});
|
||||
var x;
|
||||
}
|
||||
@@ -0,0 +1,432 @@
|
||||
=== tests/cases/conformance/async/es6/asyncWithVarShadowing_es6.ts ===
|
||||
// https://github.com/Microsoft/TypeScript/issues/20461
|
||||
declare const y: any;
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
|
||||
async function fn1(x) {
|
||||
>fn1 : Symbol(fn1, Decl(asyncWithVarShadowing_es6.ts, 1, 21))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 3, 19), Decl(asyncWithVarShadowing_es6.ts, 4, 7))
|
||||
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 3, 19), Decl(asyncWithVarShadowing_es6.ts, 4, 7))
|
||||
}
|
||||
|
||||
async function fn2(x) {
|
||||
>fn2 : Symbol(fn2, Decl(asyncWithVarShadowing_es6.ts, 5, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 7, 19), Decl(asyncWithVarShadowing_es6.ts, 8, 7))
|
||||
|
||||
var x, z;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 7, 19), Decl(asyncWithVarShadowing_es6.ts, 8, 7))
|
||||
>z : Symbol(z, Decl(asyncWithVarShadowing_es6.ts, 8, 10))
|
||||
}
|
||||
|
||||
async function fn3(x) {
|
||||
>fn3 : Symbol(fn3, Decl(asyncWithVarShadowing_es6.ts, 9, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 11, 19))
|
||||
|
||||
var z;
|
||||
>z : Symbol(z, Decl(asyncWithVarShadowing_es6.ts, 12, 7))
|
||||
}
|
||||
|
||||
async function fn4(x) {
|
||||
>fn4 : Symbol(fn4, Decl(asyncWithVarShadowing_es6.ts, 13, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 15, 19), Decl(asyncWithVarShadowing_es6.ts, 16, 7))
|
||||
|
||||
var x = y;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 15, 19), Decl(asyncWithVarShadowing_es6.ts, 16, 7))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
|
||||
async function fn5(x) {
|
||||
>fn5 : Symbol(fn5, Decl(asyncWithVarShadowing_es6.ts, 17, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 19, 19), Decl(asyncWithVarShadowing_es6.ts, 20, 9))
|
||||
|
||||
var { x } = y;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 19, 19), Decl(asyncWithVarShadowing_es6.ts, 20, 9))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
|
||||
async function fn6(x) {
|
||||
>fn6 : Symbol(fn6, Decl(asyncWithVarShadowing_es6.ts, 21, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 23, 19), Decl(asyncWithVarShadowing_es6.ts, 24, 9))
|
||||
|
||||
var { x, z } = y;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 23, 19), Decl(asyncWithVarShadowing_es6.ts, 24, 9))
|
||||
>z : Symbol(z, Decl(asyncWithVarShadowing_es6.ts, 24, 12))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
|
||||
async function fn7(x) {
|
||||
>fn7 : Symbol(fn7, Decl(asyncWithVarShadowing_es6.ts, 25, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 27, 19), Decl(asyncWithVarShadowing_es6.ts, 28, 9))
|
||||
|
||||
var { x = y } = y;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 27, 19), Decl(asyncWithVarShadowing_es6.ts, 28, 9))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
|
||||
async function fn8(x) {
|
||||
>fn8 : Symbol(fn8, Decl(asyncWithVarShadowing_es6.ts, 29, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 31, 19), Decl(asyncWithVarShadowing_es6.ts, 32, 9))
|
||||
|
||||
var { z: x } = y;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 31, 19), Decl(asyncWithVarShadowing_es6.ts, 32, 9))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
|
||||
async function fn9(x) {
|
||||
>fn9 : Symbol(fn9, Decl(asyncWithVarShadowing_es6.ts, 33, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 35, 19), Decl(asyncWithVarShadowing_es6.ts, 36, 14))
|
||||
|
||||
var { z: { x } } = y;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 35, 19), Decl(asyncWithVarShadowing_es6.ts, 36, 14))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
|
||||
async function fn10(x) {
|
||||
>fn10 : Symbol(fn10, Decl(asyncWithVarShadowing_es6.ts, 37, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 39, 20), Decl(asyncWithVarShadowing_es6.ts, 40, 14))
|
||||
|
||||
var { z: { x } = y } = y;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 39, 20), Decl(asyncWithVarShadowing_es6.ts, 40, 14))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
|
||||
async function fn11(x) {
|
||||
>fn11 : Symbol(fn11, Decl(asyncWithVarShadowing_es6.ts, 41, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 43, 20), Decl(asyncWithVarShadowing_es6.ts, 44, 9))
|
||||
|
||||
var { ...x } = y;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 43, 20), Decl(asyncWithVarShadowing_es6.ts, 44, 9))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
|
||||
async function fn12(x) {
|
||||
>fn12 : Symbol(fn12, Decl(asyncWithVarShadowing_es6.ts, 45, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 47, 20), Decl(asyncWithVarShadowing_es6.ts, 48, 9))
|
||||
|
||||
var [x] = y;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 47, 20), Decl(asyncWithVarShadowing_es6.ts, 48, 9))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
|
||||
async function fn13(x) {
|
||||
>fn13 : Symbol(fn13, Decl(asyncWithVarShadowing_es6.ts, 49, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 51, 20), Decl(asyncWithVarShadowing_es6.ts, 52, 9))
|
||||
|
||||
var [x = y] = y;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 51, 20), Decl(asyncWithVarShadowing_es6.ts, 52, 9))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
|
||||
async function fn14(x) {
|
||||
>fn14 : Symbol(fn14, Decl(asyncWithVarShadowing_es6.ts, 53, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 55, 20), Decl(asyncWithVarShadowing_es6.ts, 56, 10))
|
||||
|
||||
var [, x] = y;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 55, 20), Decl(asyncWithVarShadowing_es6.ts, 56, 10))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
|
||||
async function fn15(x) {
|
||||
>fn15 : Symbol(fn15, Decl(asyncWithVarShadowing_es6.ts, 57, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 59, 20), Decl(asyncWithVarShadowing_es6.ts, 60, 9))
|
||||
|
||||
var [...x] = y;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 59, 20), Decl(asyncWithVarShadowing_es6.ts, 60, 9))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
|
||||
async function fn16(x) {
|
||||
>fn16 : Symbol(fn16, Decl(asyncWithVarShadowing_es6.ts, 61, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 63, 20), Decl(asyncWithVarShadowing_es6.ts, 64, 10))
|
||||
|
||||
var [[x]] = y;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 63, 20), Decl(asyncWithVarShadowing_es6.ts, 64, 10))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
|
||||
async function fn17(x) {
|
||||
>fn17 : Symbol(fn17, Decl(asyncWithVarShadowing_es6.ts, 65, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 67, 20), Decl(asyncWithVarShadowing_es6.ts, 68, 10))
|
||||
|
||||
var [[x] = y] = y;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 67, 20), Decl(asyncWithVarShadowing_es6.ts, 68, 10))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
|
||||
async function fn18({ x }) {
|
||||
>fn18 : Symbol(fn18, Decl(asyncWithVarShadowing_es6.ts, 69, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 71, 21), Decl(asyncWithVarShadowing_es6.ts, 72, 7))
|
||||
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 71, 21), Decl(asyncWithVarShadowing_es6.ts, 72, 7))
|
||||
}
|
||||
|
||||
async function fn19([x]) {
|
||||
>fn19 : Symbol(fn19, Decl(asyncWithVarShadowing_es6.ts, 73, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 75, 21), Decl(asyncWithVarShadowing_es6.ts, 76, 7))
|
||||
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 75, 21), Decl(asyncWithVarShadowing_es6.ts, 76, 7))
|
||||
}
|
||||
|
||||
async function fn20(x) {
|
||||
>fn20 : Symbol(fn20, Decl(asyncWithVarShadowing_es6.ts, 77, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 79, 20), Decl(asyncWithVarShadowing_es6.ts, 81, 11))
|
||||
{
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 79, 20), Decl(asyncWithVarShadowing_es6.ts, 81, 11))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn21(x) {
|
||||
>fn21 : Symbol(fn21, Decl(asyncWithVarShadowing_es6.ts, 83, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 85, 20), Decl(asyncWithVarShadowing_es6.ts, 87, 11))
|
||||
|
||||
if (y) {
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 85, 20), Decl(asyncWithVarShadowing_es6.ts, 87, 11))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn22(x) {
|
||||
>fn22 : Symbol(fn22, Decl(asyncWithVarShadowing_es6.ts, 89, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 91, 20), Decl(asyncWithVarShadowing_es6.ts, 95, 11))
|
||||
|
||||
if (y) {
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
else {
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 91, 20), Decl(asyncWithVarShadowing_es6.ts, 95, 11))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn23(x) {
|
||||
>fn23 : Symbol(fn23, Decl(asyncWithVarShadowing_es6.ts, 97, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 99, 20), Decl(asyncWithVarShadowing_es6.ts, 101, 11))
|
||||
|
||||
try {
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 99, 20), Decl(asyncWithVarShadowing_es6.ts, 101, 11))
|
||||
}
|
||||
catch (e) {
|
||||
>e : Symbol(e, Decl(asyncWithVarShadowing_es6.ts, 103, 11))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn24(x) {
|
||||
>fn24 : Symbol(fn24, Decl(asyncWithVarShadowing_es6.ts, 105, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 107, 20), Decl(asyncWithVarShadowing_es6.ts, 112, 11))
|
||||
|
||||
try {
|
||||
|
||||
}
|
||||
catch (e) {
|
||||
>e : Symbol(e, Decl(asyncWithVarShadowing_es6.ts, 111, 11))
|
||||
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 107, 20), Decl(asyncWithVarShadowing_es6.ts, 112, 11))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn25(x) {
|
||||
>fn25 : Symbol(fn25, Decl(asyncWithVarShadowing_es6.ts, 114, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 116, 20), Decl(asyncWithVarShadowing_es6.ts, 121, 11))
|
||||
|
||||
try {
|
||||
|
||||
}
|
||||
catch (x) {
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 120, 11))
|
||||
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 116, 20), Decl(asyncWithVarShadowing_es6.ts, 121, 11))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn26(x) {
|
||||
>fn26 : Symbol(fn26, Decl(asyncWithVarShadowing_es6.ts, 123, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 125, 20), Decl(asyncWithVarShadowing_es6.ts, 130, 11))
|
||||
|
||||
try {
|
||||
|
||||
}
|
||||
catch ({ x }) {
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 129, 12))
|
||||
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 125, 20), Decl(asyncWithVarShadowing_es6.ts, 130, 11))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn27(x) {
|
||||
>fn27 : Symbol(fn27, Decl(asyncWithVarShadowing_es6.ts, 132, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 134, 20), Decl(asyncWithVarShadowing_es6.ts, 138, 11))
|
||||
|
||||
try {
|
||||
}
|
||||
finally {
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 134, 20), Decl(asyncWithVarShadowing_es6.ts, 138, 11))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn28(x) {
|
||||
>fn28 : Symbol(fn28, Decl(asyncWithVarShadowing_es6.ts, 140, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 142, 20), Decl(asyncWithVarShadowing_es6.ts, 144, 11))
|
||||
|
||||
while (y) {
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 142, 20), Decl(asyncWithVarShadowing_es6.ts, 144, 11))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn29(x) {
|
||||
>fn29 : Symbol(fn29, Decl(asyncWithVarShadowing_es6.ts, 146, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 148, 20), Decl(asyncWithVarShadowing_es6.ts, 150, 11))
|
||||
|
||||
do {
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 148, 20), Decl(asyncWithVarShadowing_es6.ts, 150, 11))
|
||||
}
|
||||
while (y);
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
|
||||
async function fn30(x) {
|
||||
>fn30 : Symbol(fn30, Decl(asyncWithVarShadowing_es6.ts, 153, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 155, 20), Decl(asyncWithVarShadowing_es6.ts, 156, 12))
|
||||
|
||||
for (var x = y;;) {
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 155, 20), Decl(asyncWithVarShadowing_es6.ts, 156, 12))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
async function fn31(x) {
|
||||
>fn31 : Symbol(fn31, Decl(asyncWithVarShadowing_es6.ts, 159, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 161, 20), Decl(asyncWithVarShadowing_es6.ts, 162, 14))
|
||||
|
||||
for (var { x } = y;;) {
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 161, 20), Decl(asyncWithVarShadowing_es6.ts, 162, 14))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn32(x) {
|
||||
>fn32 : Symbol(fn32, Decl(asyncWithVarShadowing_es6.ts, 164, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 166, 20), Decl(asyncWithVarShadowing_es6.ts, 168, 11))
|
||||
|
||||
for (;;) {
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 166, 20), Decl(asyncWithVarShadowing_es6.ts, 168, 11))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn33(x: string) {
|
||||
>fn33 : Symbol(fn33, Decl(asyncWithVarShadowing_es6.ts, 170, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 172, 20), Decl(asyncWithVarShadowing_es6.ts, 173, 12))
|
||||
|
||||
for (var x in y) {
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 172, 20), Decl(asyncWithVarShadowing_es6.ts, 173, 12))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn34(x) {
|
||||
>fn34 : Symbol(fn34, Decl(asyncWithVarShadowing_es6.ts, 175, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 177, 20), Decl(asyncWithVarShadowing_es6.ts, 179, 11))
|
||||
|
||||
for (var z in y) {
|
||||
>z : Symbol(z, Decl(asyncWithVarShadowing_es6.ts, 178, 12))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 177, 20), Decl(asyncWithVarShadowing_es6.ts, 179, 11))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn35(x) {
|
||||
>fn35 : Symbol(fn35, Decl(asyncWithVarShadowing_es6.ts, 181, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 183, 20), Decl(asyncWithVarShadowing_es6.ts, 184, 12))
|
||||
|
||||
for (var x of y) {
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 183, 20), Decl(asyncWithVarShadowing_es6.ts, 184, 12))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn36(x) {
|
||||
>fn36 : Symbol(fn36, Decl(asyncWithVarShadowing_es6.ts, 186, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 188, 20), Decl(asyncWithVarShadowing_es6.ts, 189, 14))
|
||||
|
||||
for (var { x } of y) {
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 188, 20), Decl(asyncWithVarShadowing_es6.ts, 189, 14))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn37(x) {
|
||||
>fn37 : Symbol(fn37, Decl(asyncWithVarShadowing_es6.ts, 191, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 193, 20), Decl(asyncWithVarShadowing_es6.ts, 195, 11))
|
||||
|
||||
for (var z of y) {
|
||||
>z : Symbol(z, Decl(asyncWithVarShadowing_es6.ts, 194, 12))
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 193, 20), Decl(asyncWithVarShadowing_es6.ts, 195, 11))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn38(x) {
|
||||
>fn38 : Symbol(fn38, Decl(asyncWithVarShadowing_es6.ts, 197, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 199, 20), Decl(asyncWithVarShadowing_es6.ts, 202, 15))
|
||||
|
||||
switch (y) {
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
|
||||
case y:
|
||||
>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13))
|
||||
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 199, 20), Decl(asyncWithVarShadowing_es6.ts, 202, 15))
|
||||
}
|
||||
}
|
||||
|
||||
async function fn39(x) {
|
||||
>fn39 : Symbol(fn39, Decl(asyncWithVarShadowing_es6.ts, 204, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 206, 20), Decl(asyncWithVarShadowing_es6.ts, 208, 11))
|
||||
|
||||
foo: {
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 206, 20), Decl(asyncWithVarShadowing_es6.ts, 208, 11))
|
||||
|
||||
break foo;
|
||||
}
|
||||
}
|
||||
|
||||
async function fn40(x) {
|
||||
>fn40 : Symbol(fn40, Decl(asyncWithVarShadowing_es6.ts, 211, 1))
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 213, 20), Decl(asyncWithVarShadowing_es6.ts, 218, 11))
|
||||
|
||||
try {
|
||||
|
||||
}
|
||||
catch {
|
||||
var x;
|
||||
>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 213, 20), Decl(asyncWithVarShadowing_es6.ts, 218, 11))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,439 @@
|
||||
=== tests/cases/conformance/async/es6/asyncWithVarShadowing_es6.ts ===
|
||||
// https://github.com/Microsoft/TypeScript/issues/20461
|
||||
declare const y: any;
|
||||
>y : any
|
||||
|
||||
async function fn1(x) {
|
||||
>fn1 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
|
||||
async function fn2(x) {
|
||||
>fn2 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var x, z;
|
||||
>x : any
|
||||
>z : any
|
||||
}
|
||||
|
||||
async function fn3(x) {
|
||||
>fn3 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var z;
|
||||
>z : any
|
||||
}
|
||||
|
||||
async function fn4(x) {
|
||||
>fn4 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var x = y;
|
||||
>x : any
|
||||
>y : any
|
||||
}
|
||||
|
||||
async function fn5(x) {
|
||||
>fn5 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var { x } = y;
|
||||
>x : any
|
||||
>y : any
|
||||
}
|
||||
|
||||
async function fn6(x) {
|
||||
>fn6 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var { x, z } = y;
|
||||
>x : any
|
||||
>z : any
|
||||
>y : any
|
||||
}
|
||||
|
||||
async function fn7(x) {
|
||||
>fn7 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var { x = y } = y;
|
||||
>x : any
|
||||
>y : any
|
||||
>y : any
|
||||
}
|
||||
|
||||
async function fn8(x) {
|
||||
>fn8 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var { z: x } = y;
|
||||
>z : any
|
||||
>x : any
|
||||
>y : any
|
||||
}
|
||||
|
||||
async function fn9(x) {
|
||||
>fn9 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var { z: { x } } = y;
|
||||
>z : any
|
||||
>x : any
|
||||
>y : any
|
||||
}
|
||||
|
||||
async function fn10(x) {
|
||||
>fn10 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var { z: { x } = y } = y;
|
||||
>z : any
|
||||
>x : any
|
||||
>y : any
|
||||
>y : any
|
||||
}
|
||||
|
||||
async function fn11(x) {
|
||||
>fn11 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var { ...x } = y;
|
||||
>x : any
|
||||
>y : any
|
||||
}
|
||||
|
||||
async function fn12(x) {
|
||||
>fn12 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var [x] = y;
|
||||
>x : any
|
||||
>y : any
|
||||
}
|
||||
|
||||
async function fn13(x) {
|
||||
>fn13 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var [x = y] = y;
|
||||
>x : any
|
||||
>y : any
|
||||
>y : any
|
||||
}
|
||||
|
||||
async function fn14(x) {
|
||||
>fn14 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var [, x] = y;
|
||||
> : undefined
|
||||
>x : any
|
||||
>y : any
|
||||
}
|
||||
|
||||
async function fn15(x) {
|
||||
>fn15 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var [...x] = y;
|
||||
>x : any
|
||||
>y : any
|
||||
}
|
||||
|
||||
async function fn16(x) {
|
||||
>fn16 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var [[x]] = y;
|
||||
>x : any
|
||||
>y : any
|
||||
}
|
||||
|
||||
async function fn17(x) {
|
||||
>fn17 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var [[x] = y] = y;
|
||||
>x : any
|
||||
>y : any
|
||||
>y : any
|
||||
}
|
||||
|
||||
async function fn18({ x }) {
|
||||
>fn18 : ({ x }: { x: any; }) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
|
||||
async function fn19([x]) {
|
||||
>fn19 : ([x]: [any]) => Promise<void>
|
||||
>x : any
|
||||
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
|
||||
async function fn20(x) {
|
||||
>fn20 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
{
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn21(x) {
|
||||
>fn21 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
if (y) {
|
||||
>y : any
|
||||
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn22(x) {
|
||||
>fn22 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
if (y) {
|
||||
>y : any
|
||||
}
|
||||
else {
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn23(x) {
|
||||
>fn23 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
try {
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
catch (e) {
|
||||
>e : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn24(x) {
|
||||
>fn24 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
try {
|
||||
|
||||
}
|
||||
catch (e) {
|
||||
>e : any
|
||||
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn25(x) {
|
||||
>fn25 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
try {
|
||||
|
||||
}
|
||||
catch (x) {
|
||||
>x : any
|
||||
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn26(x) {
|
||||
>fn26 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
try {
|
||||
|
||||
}
|
||||
catch ({ x }) {
|
||||
>x : any
|
||||
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn27(x) {
|
||||
>fn27 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
try {
|
||||
}
|
||||
finally {
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn28(x) {
|
||||
>fn28 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
while (y) {
|
||||
>y : any
|
||||
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn29(x) {
|
||||
>fn29 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
do {
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
while (y);
|
||||
>y : any
|
||||
}
|
||||
|
||||
async function fn30(x) {
|
||||
>fn30 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
for (var x = y;;) {
|
||||
>x : any
|
||||
>y : any
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
async function fn31(x) {
|
||||
>fn31 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
for (var { x } = y;;) {
|
||||
>x : any
|
||||
>y : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn32(x) {
|
||||
>fn32 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
for (;;) {
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn33(x: string) {
|
||||
>fn33 : (x: string) => Promise<void>
|
||||
>x : string
|
||||
|
||||
for (var x in y) {
|
||||
>x : string
|
||||
>y : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn34(x) {
|
||||
>fn34 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
for (var z in y) {
|
||||
>z : string
|
||||
>y : any
|
||||
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn35(x) {
|
||||
>fn35 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
for (var x of y) {
|
||||
>x : any
|
||||
>y : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn36(x) {
|
||||
>fn36 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
for (var { x } of y) {
|
||||
>x : any
|
||||
>y : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn37(x) {
|
||||
>fn37 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
for (var z of y) {
|
||||
>z : any
|
||||
>y : any
|
||||
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn38(x) {
|
||||
>fn38 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
switch (y) {
|
||||
>y : any
|
||||
|
||||
case y:
|
||||
>y : any
|
||||
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn39(x) {
|
||||
>fn39 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
foo: {
|
||||
>foo : any
|
||||
|
||||
var x;
|
||||
>x : any
|
||||
|
||||
break foo;
|
||||
>foo : any
|
||||
}
|
||||
}
|
||||
|
||||
async function fn40(x) {
|
||||
>fn40 : (x: any) => Promise<void>
|
||||
>x : any
|
||||
|
||||
try {
|
||||
|
||||
}
|
||||
catch {
|
||||
var x;
|
||||
>x : any
|
||||
}
|
||||
}
|
||||
|
||||
+28
-28
@@ -1,17 +1,17 @@
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(5,10): error TS2558: Expected 2 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(6,11): error TS2558: Expected 2 type arguments, but got 3.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(9,10): error TS2558: Expected 2 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(10,11): error TS2558: Expected 2 type arguments, but got 3.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(13,10): error TS2558: Expected 2 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(14,11): error TS2558: Expected 2 type arguments, but got 3.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(21,10): error TS2558: Expected 2 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(22,11): error TS2558: Expected 2 type arguments, but got 3.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(28,10): error TS2558: Expected 2 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(29,11): error TS2558: Expected 2 type arguments, but got 3.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(36,10): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(37,11): error TS2558: Expected 0 type arguments, but got 3.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(43,10): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(44,11): error TS2558: Expected 0 type arguments, but got 3.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(5,12): error TS2558: Expected 2 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(6,13): error TS2558: Expected 2 type arguments, but got 3.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(9,13): error TS2558: Expected 2 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(10,14): error TS2558: Expected 2 type arguments, but got 3.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(13,13): error TS2558: Expected 2 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(14,14): error TS2558: Expected 2 type arguments, but got 3.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(21,22): error TS2558: Expected 2 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(22,23): error TS2558: Expected 2 type arguments, but got 3.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(28,14): error TS2558: Expected 2 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(29,15): error TS2558: Expected 2 type arguments, but got 3.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(36,23): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(37,24): error TS2558: Expected 0 type arguments, but got 3.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(43,15): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts(44,16): error TS2558: Expected 0 type arguments, but got 3.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFunctionWithIncorrectNumberOfTypeArguments.ts (14 errors) ====
|
||||
@@ -20,26 +20,26 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFuncti
|
||||
|
||||
function f<T, U>(x: T, y: U): T { return null; }
|
||||
var r1 = f<number>(1, '');
|
||||
~~~~~~~~~~~~~~~~
|
||||
~~~~~~
|
||||
!!! error TS2558: Expected 2 type arguments, but got 1.
|
||||
var r1b = f<number, string, number>(1, '');
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2558: Expected 2 type arguments, but got 3.
|
||||
|
||||
var f2 = <T, U>(x: T, y: U): T => { return null; }
|
||||
var r2 = f2<number>(1, '');
|
||||
~~~~~~~~~~~~~~~~~
|
||||
~~~~~~
|
||||
!!! error TS2558: Expected 2 type arguments, but got 1.
|
||||
var r2b = f2<number, string, number>(1, '');
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2558: Expected 2 type arguments, but got 3.
|
||||
|
||||
var f3: { <T, U>(x: T, y: U): T; }
|
||||
var r3 = f3<number>(1, '');
|
||||
~~~~~~~~~~~~~~~~~
|
||||
~~~~~~
|
||||
!!! error TS2558: Expected 2 type arguments, but got 1.
|
||||
var r3b = f3<number, string, number>(1, '');
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2558: Expected 2 type arguments, but got 3.
|
||||
|
||||
class C {
|
||||
@@ -48,10 +48,10 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFuncti
|
||||
}
|
||||
}
|
||||
var r4 = (new C()).f<number>(1, '');
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~
|
||||
!!! error TS2558: Expected 2 type arguments, but got 1.
|
||||
var r4b = (new C()).f<number, string, number>(1, '');
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2558: Expected 2 type arguments, but got 3.
|
||||
|
||||
interface I {
|
||||
@@ -59,10 +59,10 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFuncti
|
||||
}
|
||||
var i: I;
|
||||
var r5 = i.f<number>(1, '');
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~
|
||||
!!! error TS2558: Expected 2 type arguments, but got 1.
|
||||
var r5b = i.f<number, string, number>(1, '');
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2558: Expected 2 type arguments, but got 3.
|
||||
|
||||
class C2<T, U> {
|
||||
@@ -71,10 +71,10 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFuncti
|
||||
}
|
||||
}
|
||||
var r6 = (new C2()).f<number>(1, '');
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~
|
||||
!!! error TS2558: Expected 0 type arguments, but got 1.
|
||||
var r6b = (new C2()).f<number, string, number>(1, '');
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2558: Expected 0 type arguments, but got 3.
|
||||
|
||||
interface I2<T, U> {
|
||||
@@ -82,8 +82,8 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/callGenericFuncti
|
||||
}
|
||||
var i2: I2<number, string>;
|
||||
var r7 = i2.f<number>(1, '');
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~
|
||||
!!! error TS2558: Expected 0 type arguments, but got 1.
|
||||
var r7b = i2.f<number, string, number>(1, '');
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2558: Expected 0 type arguments, but got 3.
|
||||
@@ -1,10 +1,10 @@
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFunctionWithTypeArguments.ts(5,9): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFunctionWithTypeArguments.ts(8,10): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFunctionWithTypeArguments.ts(11,10): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFunctionWithTypeArguments.ts(18,10): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFunctionWithTypeArguments.ts(24,10): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFunctionWithTypeArguments.ts(31,10): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFunctionWithTypeArguments.ts(37,10): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFunctionWithTypeArguments.ts(5,11): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFunctionWithTypeArguments.ts(8,13): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFunctionWithTypeArguments.ts(11,13): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFunctionWithTypeArguments.ts(18,22): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFunctionWithTypeArguments.ts(24,14): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFunctionWithTypeArguments.ts(31,23): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFunctionWithTypeArguments.ts(37,15): error TS2558: Expected 0 type arguments, but got 1.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFunctionWithTypeArguments.ts(40,10): error TS2347: Untyped function calls may not accept type arguments.
|
||||
tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFunctionWithTypeArguments.ts(43,10): error TS2347: Untyped function calls may not accept type arguments.
|
||||
|
||||
@@ -15,17 +15,17 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFun
|
||||
|
||||
function f(x: number) { return null; }
|
||||
var r = f<string>(1);
|
||||
~~~~~~~~~~~~
|
||||
~~~~~~
|
||||
!!! error TS2558: Expected 0 type arguments, but got 1.
|
||||
|
||||
var f2 = (x: number) => { return null; }
|
||||
var r2 = f2<string>(1);
|
||||
~~~~~~~~~~~~~
|
||||
~~~~~~
|
||||
!!! error TS2558: Expected 0 type arguments, but got 1.
|
||||
|
||||
var f3: { (x: number): any; }
|
||||
var r3 = f3<string>(1);
|
||||
~~~~~~~~~~~~~
|
||||
~~~~~~
|
||||
!!! error TS2558: Expected 0 type arguments, but got 1.
|
||||
|
||||
class C {
|
||||
@@ -34,7 +34,7 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFun
|
||||
}
|
||||
}
|
||||
var r4 = (new C()).f<string>(1);
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~
|
||||
!!! error TS2558: Expected 0 type arguments, but got 1.
|
||||
|
||||
interface I {
|
||||
@@ -42,7 +42,7 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFun
|
||||
}
|
||||
var i: I;
|
||||
var r5 = i.f<string>(1);
|
||||
~~~~~~~~~~~~~~
|
||||
~~~~~~
|
||||
!!! error TS2558: Expected 0 type arguments, but got 1.
|
||||
|
||||
class C2 {
|
||||
@@ -51,7 +51,7 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFun
|
||||
}
|
||||
}
|
||||
var r6 = (new C2()).f<string>(1);
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~
|
||||
!!! error TS2558: Expected 0 type arguments, but got 1.
|
||||
|
||||
interface I2 {
|
||||
@@ -59,7 +59,7 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/callNonGenericFun
|
||||
}
|
||||
var i2: I2;
|
||||
var r7 = i2.f<string>(1);
|
||||
~~~~~~~~~~~~~~~
|
||||
~~~~~~
|
||||
!!! error TS2558: Expected 0 type arguments, but got 1.
|
||||
|
||||
var a;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user