mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into compareStrings
This commit is contained in:
@@ -59,3 +59,11 @@ internal/
|
||||
.idea
|
||||
yarn.lock
|
||||
.parallelperf.*
|
||||
tests/cases/user/*/package-lock.json
|
||||
tests/cases/user/*/node_modules/
|
||||
tests/cases/user/*/**/*.js
|
||||
tests/cases/user/*/**/*.js.map
|
||||
tests/cases/user/*/**/*.d.ts
|
||||
!tests/cases/user/zone.js/
|
||||
!tests/cases/user/bignumber.js/
|
||||
!tests/cases/user/discord.js/
|
||||
|
||||
+1
-1
@@ -2,8 +2,8 @@ language: node_js
|
||||
|
||||
node_js:
|
||||
- 'stable'
|
||||
- '8'
|
||||
- '6'
|
||||
- '4'
|
||||
|
||||
sudo: false
|
||||
|
||||
|
||||
+25
-39
@@ -123,15 +123,13 @@ const es2015LibrarySources = [
|
||||
"es2015.symbol.wellknown.d.ts"
|
||||
];
|
||||
|
||||
const es2015LibrarySourceMap = es2015LibrarySources.map(function(source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
});
|
||||
const es2015LibrarySourceMap = es2015LibrarySources.map(source =>
|
||||
({ target: "lib." + source, sources: ["header.d.ts", source] }));
|
||||
|
||||
const es2016LibrarySource = ["es2016.array.include.d.ts"];
|
||||
|
||||
const es2016LibrarySourceMap = es2016LibrarySource.map(function(source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
});
|
||||
const es2016LibrarySourceMap = es2016LibrarySource.map(source =>
|
||||
({ target: "lib." + source, sources: ["header.d.ts", source] }));
|
||||
|
||||
const es2017LibrarySource = [
|
||||
"es2017.object.d.ts",
|
||||
@@ -140,17 +138,15 @@ const es2017LibrarySource = [
|
||||
"es2017.intl.d.ts",
|
||||
];
|
||||
|
||||
const es2017LibrarySourceMap = es2017LibrarySource.map(function(source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
});
|
||||
const es2017LibrarySourceMap = es2017LibrarySource.map(source =>
|
||||
({ target: "lib." + source, sources: ["header.d.ts", source] }));
|
||||
|
||||
const esnextLibrarySource = [
|
||||
"esnext.asynciterable.d.ts"
|
||||
];
|
||||
|
||||
const esnextLibrarySourceMap = esnextLibrarySource.map(function (source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
});
|
||||
const esnextLibrarySourceMap = esnextLibrarySource.map(source =>
|
||||
({ target: "lib." + source, sources: ["header.d.ts", source] }));
|
||||
|
||||
const hostsLibrarySources = ["dom.generated.d.ts", "webworker.importscripts.d.ts", "scripthost.d.ts"];
|
||||
|
||||
@@ -171,14 +167,13 @@ const librarySourceMap = [
|
||||
// JavaScript + all host library
|
||||
{ target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources) },
|
||||
{ target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") },
|
||||
{ target: "lib.es2016.full.d.ts", sources: ["header.d.ts", "es2016.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") },
|
||||
{ target: "lib.es2017.full.d.ts", sources: ["header.d.ts", "es2017.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") },
|
||||
{ target: "lib.esnext.full.d.ts", sources: ["header.d.ts", "esnext.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") },
|
||||
{ target: "lib.es2016.full.d.ts", sources: ["header.d.ts", "es2016.d.ts"].concat(hostsLibrarySources, "dom.iterable.d.ts") },
|
||||
{ target: "lib.es2017.full.d.ts", sources: ["header.d.ts", "es2017.d.ts"].concat(hostsLibrarySources, "dom.iterable.d.ts") },
|
||||
{ target: "lib.esnext.full.d.ts", sources: ["header.d.ts", "esnext.d.ts"].concat(hostsLibrarySources, "dom.iterable.d.ts") },
|
||||
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap, esnextLibrarySourceMap);
|
||||
|
||||
const libraryTargets = librarySourceMap.map(function(f) {
|
||||
return path.join(builtLocalDirectory, f.target);
|
||||
});
|
||||
const libraryTargets = librarySourceMap.map(f =>
|
||||
path.join(builtLocalDirectory, f.target));
|
||||
|
||||
/**
|
||||
* .lcg file is what localization team uses to know what messages to localize.
|
||||
@@ -193,22 +188,19 @@ const generatedLCGFile = path.join(builtLocalDirectory, "enu", "diagnosticMessag
|
||||
* 2. 'src\compiler\diagnosticMessages.generated.json' => 'built\local\ENU\diagnosticMessages.generated.json.lcg'
|
||||
* generate the lcg file (source of messages to localize) from the diagnosticMessages.generated.json
|
||||
*/
|
||||
const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"].map(function (f) {
|
||||
return path.join(builtLocalDirectory, f, "diagnosticMessages.generated.json");
|
||||
}).concat(generatedLCGFile);
|
||||
const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"]
|
||||
.map(f => path.join(builtLocalDirectory, f, "diagnosticMessages.generated.json"))
|
||||
.concat(generatedLCGFile);
|
||||
|
||||
for (const i in libraryTargets) {
|
||||
const entry = librarySourceMap[i];
|
||||
const target = libraryTargets[i];
|
||||
const sources = [copyright].concat(entry.sources.map(function(s) {
|
||||
return path.join(libraryDirectory, s);
|
||||
}));
|
||||
gulp.task(target, /*help*/ false, [], function() {
|
||||
return gulp.src(sources)
|
||||
const sources = [copyright].concat(entry.sources.map(s => path.join(libraryDirectory, s)));
|
||||
gulp.task(target, /*help*/ false, [], () =>
|
||||
gulp.src(sources)
|
||||
.pipe(newer(target))
|
||||
.pipe(concat(target, { newLine: "\n\n" }))
|
||||
.pipe(gulp.dest("."));
|
||||
});
|
||||
.pipe(gulp.dest(".")));
|
||||
}
|
||||
|
||||
const configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js");
|
||||
@@ -575,9 +567,7 @@ gulp.task(specMd, /*help*/ false, [word2mdJs], (done) => {
|
||||
const specMDFullPath = path.resolve(specMd);
|
||||
const cmd = "cscript //nologo " + word2mdJs + " \"" + specWordFullPath + "\" " + "\"" + specMDFullPath + "\"";
|
||||
console.log(cmd);
|
||||
cp.exec(cmd, function() {
|
||||
done();
|
||||
});
|
||||
cp.exec(cmd, done);
|
||||
});
|
||||
|
||||
gulp.task("generate-spec", "Generates a Markdown version of the Language Specification", [specMd]);
|
||||
@@ -714,17 +704,13 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
||||
}
|
||||
args.push(run);
|
||||
setNodeEnvToDevelopment();
|
||||
exec(mocha, args, lintThenFinish, function(e, status) {
|
||||
finish(e, status);
|
||||
});
|
||||
exec(mocha, args, lintThenFinish, finish);
|
||||
|
||||
}
|
||||
else {
|
||||
// run task to load all tests and partition them between workers
|
||||
setNodeEnvToDevelopment();
|
||||
exec(host, [run], lintThenFinish, function(e, status) {
|
||||
finish(e, status);
|
||||
});
|
||||
exec(host, [run], lintThenFinish, finish);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1082,7 +1068,7 @@ function sendNextFile(files: {path: string}[], child: cp.ChildProcess, callback:
|
||||
function spawnLintWorker(files: {path: string}[], callback: (failures: number) => void) {
|
||||
const child = cp.fork("./scripts/parallel-lint");
|
||||
let failures = 0;
|
||||
child.on("message", function(data) {
|
||||
child.on("message", data => {
|
||||
switch (data.kind) {
|
||||
case "result":
|
||||
if (data.failures > 0) {
|
||||
@@ -1106,7 +1092,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/es5.d.ts --exclude 'src/lib/*.generated.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] });
|
||||
|
||||
+2
-1
@@ -105,6 +105,7 @@ var harnessCoreSources = [
|
||||
"projectsRunner.ts",
|
||||
"loggedIO.ts",
|
||||
"rwcRunner.ts",
|
||||
"userRunner.ts",
|
||||
"test262Runner.ts",
|
||||
"./parallel/shared.ts",
|
||||
"./parallel/host.ts",
|
||||
@@ -1282,7 +1283,7 @@ task("lint", ["build-rules"], () => {
|
||||
const fileMatcher = process.env.f || process.env.file || process.env.files;
|
||||
const files = fileMatcher
|
||||
? `src/**/${fileMatcher}`
|
||||
: "Gulpfile.ts 'scripts/generateLocalizedDiagnosticMessages.ts' 'scripts/tslint/**/*.ts' 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.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);
|
||||
jake.exec([cmd], { interactive: true }, () => {
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import jobs.generation.Utilities;
|
||||
def project = GithubProject
|
||||
def branch = GithubBranchName
|
||||
|
||||
def nodeVersions = ['stable', '6', '4']
|
||||
def nodeVersions = ['stable', '8', '6']
|
||||
|
||||
nodeVersions.each { nodeVer ->
|
||||
|
||||
|
||||
@@ -74,10 +74,12 @@
|
||||
"q": "latest",
|
||||
"run-sequence": "latest",
|
||||
"sorcery": "latest",
|
||||
"source-map-support": "latest",
|
||||
"through2": "latest",
|
||||
"travis-fold": "latest",
|
||||
"ts-node": "latest",
|
||||
"tslint": "latest",
|
||||
"vinyl": "latest",
|
||||
"colors": "latest",
|
||||
"typescript": "next"
|
||||
},
|
||||
|
||||
@@ -65,10 +65,11 @@ function main(): void {
|
||||
* There are three exceptions, zh-CN, zh-TW and pt-BR.
|
||||
*/
|
||||
function getPreferedLocaleName(localeName: string) {
|
||||
localeName = localeName.toLowerCase();
|
||||
switch (localeName) {
|
||||
case "zh-CN":
|
||||
case "zh-TW":
|
||||
case "pt-BR":
|
||||
case "zh-cn":
|
||||
case "zh-tw":
|
||||
case "pt-br":
|
||||
return localeName;
|
||||
default:
|
||||
return localeName.split("-")[0];
|
||||
|
||||
@@ -64,7 +64,6 @@ module Commands {
|
||||
}
|
||||
if (path.charAt(1) === ":") {
|
||||
if (path.charAt(2) === directorySeparator) return 3;
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
+11
-8
@@ -192,7 +192,7 @@ namespace ts {
|
||||
return bindSourceFile;
|
||||
|
||||
function bindInStrictMode(file: SourceFile, opts: CompilerOptions): boolean {
|
||||
if ((opts.alwaysStrict === undefined ? opts.strict : opts.alwaysStrict) && !file.isDeclarationFile) {
|
||||
if (getStrictOptionValue(opts, "alwaysStrict") && !file.isDeclarationFile) {
|
||||
// bind in strict mode source files with alwaysStrict option
|
||||
return true;
|
||||
}
|
||||
@@ -1550,7 +1550,7 @@ namespace ts {
|
||||
function setExportContextFlag(node: ModuleDeclaration | SourceFile) {
|
||||
// A declaration source file or ambient module declaration that contains no export declarations (but possibly regular
|
||||
// declarations with export modifiers) is an export context in which declarations are implicitly exported.
|
||||
if (isInAmbientContext(node) && !hasExportDeclarations(node)) {
|
||||
if (node.flags & NodeFlags.Ambient && !hasExportDeclarations(node)) {
|
||||
node.flags |= NodeFlags.ExportContext;
|
||||
}
|
||||
else {
|
||||
@@ -1726,7 +1726,7 @@ namespace ts {
|
||||
node.originalKeywordKind >= SyntaxKind.FirstFutureReservedWord &&
|
||||
node.originalKeywordKind <= SyntaxKind.LastFutureReservedWord &&
|
||||
!isIdentifierName(node) &&
|
||||
!isInAmbientContext(node)) {
|
||||
!(node.flags & NodeFlags.Ambient)) {
|
||||
|
||||
// Report error only if there are no parse errors in file
|
||||
if (!file.parseDiagnostics.length) {
|
||||
@@ -2481,7 +2481,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindParameter(node: ParameterDeclaration) {
|
||||
if (inStrictMode && !isInAmbientContext(node)) {
|
||||
if (inStrictMode && !(node.flags & NodeFlags.Ambient)) {
|
||||
// It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
|
||||
// strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
|
||||
checkStrictModeEvalOrArguments(node, node.name);
|
||||
@@ -2503,7 +2503,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindFunctionDeclaration(node: FunctionDeclaration) {
|
||||
if (!file.isDeclarationFile && !isInAmbientContext(node)) {
|
||||
if (!file.isDeclarationFile && !(node.flags & NodeFlags.Ambient)) {
|
||||
if (isAsyncFunction(node)) {
|
||||
emitFlags |= NodeFlags.HasAsyncFunctions;
|
||||
}
|
||||
@@ -2520,7 +2520,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindFunctionExpression(node: FunctionExpression) {
|
||||
if (!file.isDeclarationFile && !isInAmbientContext(node)) {
|
||||
if (!file.isDeclarationFile && !(node.flags & NodeFlags.Ambient)) {
|
||||
if (isAsyncFunction(node)) {
|
||||
emitFlags |= NodeFlags.HasAsyncFunctions;
|
||||
}
|
||||
@@ -2534,7 +2534,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
if (!file.isDeclarationFile && !isInAmbientContext(node) && isAsyncFunction(node)) {
|
||||
if (!file.isDeclarationFile && !(node.flags & NodeFlags.Ambient) && isAsyncFunction(node)) {
|
||||
emitFlags |= NodeFlags.HasAsyncFunctions;
|
||||
}
|
||||
|
||||
@@ -2583,7 +2583,7 @@ namespace ts {
|
||||
// On the other side we do want to report errors on non-initialized 'lets' because of TDZ
|
||||
const reportUnreachableCode =
|
||||
!options.allowUnreachableCode &&
|
||||
!isInAmbientContext(node) &&
|
||||
!(node.flags & NodeFlags.Ambient) &&
|
||||
(
|
||||
node.kind !== SyntaxKind.VariableStatement ||
|
||||
getCombinedNodeFlags((<VariableStatement>node).declarationList) & NodeFlags.BlockScoped ||
|
||||
@@ -3296,6 +3296,9 @@ namespace ts {
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
case SyntaxKind.JsxText:
|
||||
case SyntaxKind.JsxClosingElement:
|
||||
case SyntaxKind.JsxFragment:
|
||||
case SyntaxKind.JsxOpeningFragment:
|
||||
case SyntaxKind.JsxClosingFragment:
|
||||
case SyntaxKind.JsxAttribute:
|
||||
case SyntaxKind.JsxAttributes:
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
|
||||
+295
-170
File diff suppressed because it is too large
Load Diff
@@ -1138,6 +1138,13 @@ namespace ts {
|
||||
reportInvalidOptionValue(option && option.type !== "number");
|
||||
return Number((<NumericLiteral>valueExpression).text);
|
||||
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
if ((<PrefixUnaryExpression>valueExpression).operator !== SyntaxKind.MinusToken || (<PrefixUnaryExpression>valueExpression).operand.kind !== SyntaxKind.NumericLiteral) {
|
||||
break; // not valid JSON syntax
|
||||
}
|
||||
reportInvalidOptionValue(option && option.type !== "number");
|
||||
return -Number((<NumericLiteral>(<PrefixUnaryExpression>valueExpression).operand).text);
|
||||
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
reportInvalidOptionValue(option && option.type !== "object");
|
||||
const objectLiteralExpression = <ObjectLiteralExpression>valueExpression;
|
||||
|
||||
+6
-27
@@ -1064,32 +1064,6 @@ namespace ts {
|
||||
return initial;
|
||||
}
|
||||
|
||||
export function reduceRight<T, U>(array: ReadonlyArray<T>, f: (memo: U, value: T, i: number) => U, initial: U, start?: number, count?: number): U;
|
||||
export function reduceRight<T>(array: ReadonlyArray<T>, f: (memo: T, value: T, i: number) => T): T;
|
||||
export function reduceRight<T>(array: T[], f: (memo: T, value: T, i: number) => T, initial?: T, start?: number, count?: number): T {
|
||||
if (array) {
|
||||
const size = array.length;
|
||||
if (size > 0) {
|
||||
let pos = start === undefined || start > size - 1 ? size - 1 : start;
|
||||
const end = count === undefined || pos - count < 0 ? 0 : pos - count;
|
||||
let result: T;
|
||||
if (arguments.length <= 2) {
|
||||
result = array[pos];
|
||||
pos--;
|
||||
}
|
||||
else {
|
||||
result = initial;
|
||||
}
|
||||
while (pos >= end) {
|
||||
result = f(result, array[pos], pos);
|
||||
pos--;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return initial;
|
||||
}
|
||||
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
/**
|
||||
@@ -1833,7 +1807,6 @@ namespace ts {
|
||||
}
|
||||
if (path.charCodeAt(1) === CharacterCodes.colon) {
|
||||
if (path.charCodeAt(2) === CharacterCodes.slash) return 3;
|
||||
return 2;
|
||||
}
|
||||
// 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',
|
||||
@@ -1943,6 +1916,12 @@ namespace ts {
|
||||
return moduleResolution;
|
||||
}
|
||||
|
||||
export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "alwaysStrict";
|
||||
|
||||
export function getStrictOptionValue(compilerOptions: CompilerOptions, flag: StrictOptionName): boolean {
|
||||
return compilerOptions[flag] === undefined ? compilerOptions.strict : compilerOptions[flag];
|
||||
}
|
||||
|
||||
export function hasZeroOrOneAsteriskCharacter(str: string): boolean {
|
||||
let seenAsterisk = false;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
|
||||
@@ -3615,6 +3615,18 @@
|
||||
"category": "Error",
|
||||
"code": 17013
|
||||
},
|
||||
"JSX fragment has no corresponding closing tag.": {
|
||||
"category": "Error",
|
||||
"code": 17014
|
||||
},
|
||||
"Expected corresponding closing tag for JSX fragment.": {
|
||||
"category": "Error",
|
||||
"code": 17015
|
||||
},
|
||||
"JSX fragment is not supported when using --jsxFactory": {
|
||||
"category": "Error",
|
||||
"code":17016
|
||||
},
|
||||
|
||||
"Circularity detected while resolving configuration: {0}": {
|
||||
"category": "Error",
|
||||
@@ -3781,5 +3793,13 @@
|
||||
"Infer parameter types from usage.": {
|
||||
"category": "Message",
|
||||
"code": 95012
|
||||
},
|
||||
"Convert to default import": {
|
||||
"category": "Message",
|
||||
"code": 95013
|
||||
},
|
||||
"Install '{0}'": {
|
||||
"category": "Message",
|
||||
"code": 95014
|
||||
}
|
||||
}
|
||||
|
||||
+30
-20
@@ -699,9 +699,11 @@ namespace ts {
|
||||
case SyntaxKind.JsxText:
|
||||
return emitJsxText(<JsxText>node);
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
return emitJsxOpeningElement(<JsxOpeningElement>node);
|
||||
case SyntaxKind.JsxOpeningFragment:
|
||||
return emitJsxOpeningElementOrFragment(<JsxOpeningElement>node);
|
||||
case SyntaxKind.JsxClosingElement:
|
||||
return emitJsxClosingElement(<JsxClosingElement>node);
|
||||
case SyntaxKind.JsxClosingFragment:
|
||||
return emitJsxClosingElementOrFragment(<JsxClosingElement>node);
|
||||
case SyntaxKind.JsxAttribute:
|
||||
return emitJsxAttribute(<JsxAttribute>node);
|
||||
case SyntaxKind.JsxAttributes:
|
||||
@@ -836,6 +838,8 @@ namespace ts {
|
||||
return emitJsxElement(<JsxElement>node);
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return emitJsxSelfClosingElement(<JsxSelfClosingElement>node);
|
||||
case SyntaxKind.JsxFragment:
|
||||
return emitJsxFragment(<JsxFragment>node);
|
||||
|
||||
// Transformation nodes
|
||||
case SyntaxKind.PartiallyEmittedExpression:
|
||||
@@ -2060,7 +2064,7 @@ namespace ts {
|
||||
|
||||
function emitJsxElement(node: JsxElement) {
|
||||
emit(node.openingElement);
|
||||
emitList(node, node.children, ListFormat.JsxElementChildren);
|
||||
emitList(node, node.children, ListFormat.JsxElementOrFragmentChildren);
|
||||
emit(node.closingElement);
|
||||
}
|
||||
|
||||
@@ -2075,14 +2079,24 @@ namespace ts {
|
||||
write("/>");
|
||||
}
|
||||
|
||||
function emitJsxOpeningElement(node: JsxOpeningElement) {
|
||||
function emitJsxFragment(node: JsxFragment) {
|
||||
emit(node.openingFragment);
|
||||
emitList(node, node.children, ListFormat.JsxElementOrFragmentChildren);
|
||||
emit(node.closingFragment);
|
||||
}
|
||||
|
||||
function emitJsxOpeningElementOrFragment(node: JsxOpeningElement | JsxOpeningFragment) {
|
||||
write("<");
|
||||
emitJsxTagName(node.tagName);
|
||||
writeIfAny(node.attributes.properties, " ");
|
||||
// We are checking here so we won't re-enter the emitting pipeline and emit extra sourcemap
|
||||
if (node.attributes.properties && node.attributes.properties.length > 0) {
|
||||
emit(node.attributes);
|
||||
|
||||
if (isJsxOpeningElement(node)) {
|
||||
emitJsxTagName(node.tagName);
|
||||
// We are checking here so we won't re-enter the emitting pipeline and emit extra sourcemap
|
||||
if (node.attributes.properties && node.attributes.properties.length > 0) {
|
||||
write(" ");
|
||||
emit(node.attributes);
|
||||
}
|
||||
}
|
||||
|
||||
write(">");
|
||||
}
|
||||
|
||||
@@ -2090,9 +2104,11 @@ namespace ts {
|
||||
writer.writeLiteral(getTextOfNode(node, /*includeTrivia*/ true));
|
||||
}
|
||||
|
||||
function emitJsxClosingElement(node: JsxClosingElement) {
|
||||
function emitJsxClosingElementOrFragment(node: JsxClosingElement | JsxClosingFragment) {
|
||||
write("</");
|
||||
emitJsxTagName(node.tagName);
|
||||
if (isJsxClosingElement(node)) {
|
||||
emitJsxTagName(node.tagName);
|
||||
}
|
||||
write(">");
|
||||
}
|
||||
|
||||
@@ -2611,12 +2627,6 @@ namespace ts {
|
||||
writer.decreaseIndent();
|
||||
}
|
||||
|
||||
function writeIfAny(nodes: NodeArray<Node>, text: string) {
|
||||
if (some(nodes)) {
|
||||
write(text);
|
||||
}
|
||||
}
|
||||
|
||||
function writeToken(token: SyntaxKind, pos: number, contextNode?: Node) {
|
||||
return onEmitSourceMapOfToken
|
||||
? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText)
|
||||
@@ -2651,8 +2661,8 @@ namespace ts {
|
||||
function writeLines(text: string): void {
|
||||
const lines = text.split(/\r\n?|\n/g);
|
||||
const indentation = guessIndentation(lines);
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = indentation ? lines[i].slice(indentation) : lines[i];
|
||||
for (const lineText of lines) {
|
||||
const line = indentation ? lineText.slice(indentation) : lineText;
|
||||
if (line.length) {
|
||||
writeLine();
|
||||
write(line);
|
||||
@@ -3176,7 +3186,7 @@ namespace ts {
|
||||
EnumMembers = CommaDelimited | Indented | MultiLine,
|
||||
CaseBlockClauses = Indented | MultiLine,
|
||||
NamedImportsOrExportsElements = CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | SingleLine | SpaceBetweenBraces,
|
||||
JsxElementChildren = SingleLine | NoInterveningComments,
|
||||
JsxElementOrFragmentChildren = SingleLine | NoInterveningComments,
|
||||
JsxElementAttributes = SingleLine | SpaceBetweenSiblings | NoInterveningComments,
|
||||
CaseOrDefaultClauseStatements = Indented | MultiLine | NoTrailingNewLine | OptionalIfEmpty,
|
||||
HeritageClauseTypes = CommaDelimited | SpaceBetweenSiblings | SingleLine,
|
||||
|
||||
+73
-5
@@ -1982,7 +1982,7 @@ namespace ts {
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
node.isExportEquals = isExportEquals;
|
||||
node.expression = expression;
|
||||
node.expression = isExportEquals ? parenthesizeBinaryOperand(SyntaxKind.EqualsToken, expression, /*isLeftSideOfBinary*/ false, /*leftOperand*/ undefined) : parenthesizeDefaultExpression(expression);
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -2115,6 +2115,22 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createJsxFragment(openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment) {
|
||||
const node = <JsxFragment>createSynthesizedNode(SyntaxKind.JsxFragment);
|
||||
node.openingFragment = openingFragment;
|
||||
node.children = createNodeArray(children);
|
||||
node.closingFragment = closingFragment;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, closingFragment: JsxClosingFragment) {
|
||||
return node.openingFragment !== openingFragment
|
||||
|| node.children !== children
|
||||
|| node.closingFragment !== closingFragment
|
||||
? updateNode(createJsxFragment(openingFragment, children, closingFragment), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression) {
|
||||
const node = <JsxAttribute>createSynthesizedNode(SyntaxKind.JsxAttribute);
|
||||
node.name = name;
|
||||
@@ -2625,7 +2641,7 @@ namespace ts {
|
||||
/**
|
||||
* Gets a custom text range to use when emitting source maps.
|
||||
*/
|
||||
export function getSourceMapRange(node: Node) {
|
||||
export function getSourceMapRange(node: Node): SourceMapRange {
|
||||
const emitNode = node.emitNode;
|
||||
return (emitNode && emitNode.sourceMapRange) || node;
|
||||
}
|
||||
@@ -2951,7 +2967,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
function createReactNamespace(reactNamespace: string, parent: JsxOpeningLikeElement) {
|
||||
function createReactNamespace(reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment) {
|
||||
// To ensure the emit resolver can properly resolve the namespace, we need to
|
||||
// treat this identifier as if it were a source tree node by clearing the `Synthesized`
|
||||
// flag and setting a parent node.
|
||||
@@ -2963,7 +2979,7 @@ namespace ts {
|
||||
return react;
|
||||
}
|
||||
|
||||
function createJsxFactoryExpressionFromEntityName(jsxFactory: EntityName, parent: JsxOpeningLikeElement): Expression {
|
||||
function createJsxFactoryExpressionFromEntityName(jsxFactory: EntityName, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression {
|
||||
if (isQualifiedName(jsxFactory)) {
|
||||
const left = createJsxFactoryExpressionFromEntityName(jsxFactory.left, parent);
|
||||
const right = createIdentifier(idText(jsxFactory.right));
|
||||
@@ -2975,7 +2991,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createJsxFactoryExpression(jsxFactoryEntity: EntityName, reactNamespace: string, parent: JsxOpeningLikeElement): Expression {
|
||||
function createJsxFactoryExpression(jsxFactoryEntity: EntityName, reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression {
|
||||
return jsxFactoryEntity ?
|
||||
createJsxFactoryExpressionFromEntityName(jsxFactoryEntity, parent) :
|
||||
createPropertyAccess(
|
||||
@@ -3016,6 +3032,37 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
export function createExpressionForJsxFragment(jsxFactoryEntity: EntityName, reactNamespace: string, children: Expression[], parentElement: JsxOpeningFragment, location: TextRange): LeftHandSideExpression {
|
||||
const tagName = createPropertyAccess(
|
||||
createReactNamespace(reactNamespace, parentElement),
|
||||
"Fragment"
|
||||
);
|
||||
|
||||
const argumentsList = [<Expression>tagName];
|
||||
argumentsList.push(createNull());
|
||||
|
||||
if (children && children.length > 0) {
|
||||
if (children.length > 1) {
|
||||
for (const child of children) {
|
||||
child.startsOnNewLine = true;
|
||||
argumentsList.push(child);
|
||||
}
|
||||
}
|
||||
else {
|
||||
argumentsList.push(children[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return setTextRange(
|
||||
createCall(
|
||||
createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement),
|
||||
/*typeArguments*/ undefined,
|
||||
argumentsList
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
export function getHelperName(name: string) {
|
||||
@@ -3885,6 +3932,27 @@ namespace ts {
|
||||
: e;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Per the spec](https://tc39.github.io/ecma262/#prod-ExportDeclaration), `export default` accepts _AssigmentExpression_ but
|
||||
* has a lookahead restriction for `function`, `async function`, and `class`.
|
||||
*
|
||||
* Basically, that means we need to parenthesize in the following cases:
|
||||
*
|
||||
* - BinaryExpression of CommaToken
|
||||
* - CommaList (synthetic list of multiple comma expressions)
|
||||
* - FunctionExpression
|
||||
* - ClassExpression
|
||||
*/
|
||||
export function parenthesizeDefaultExpression(e: Expression) {
|
||||
const check = skipPartiallyEmittedExpressions(e);
|
||||
return (check.kind === SyntaxKind.ClassExpression ||
|
||||
check.kind === SyntaxKind.FunctionExpression ||
|
||||
check.kind === SyntaxKind.CommaListExpression ||
|
||||
isBinaryExpression(check) && check.operatorToken.kind === SyntaxKind.CommaToken)
|
||||
? createParen(e)
|
||||
: e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an expression in parentheses if it is needed in order to use the expression
|
||||
* as the expression of a NewExpression node.
|
||||
|
||||
+96
-19
@@ -377,6 +377,10 @@ namespace ts {
|
||||
return visitNode(cbNode, (<JsxElement>node).openingElement) ||
|
||||
visitNodes(cbNode, cbNodes, (<JsxElement>node).children) ||
|
||||
visitNode(cbNode, (<JsxElement>node).closingElement);
|
||||
case SyntaxKind.JsxFragment:
|
||||
return visitNode(cbNode, (<JsxFragment>node).openingFragment) ||
|
||||
visitNodes(cbNode, cbNodes, (<JsxFragment>node).children) ||
|
||||
visitNode(cbNode, (<JsxFragment>node).closingFragment);
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
return visitNode(cbNode, (<JsxOpeningLikeElement>node).tagName) ||
|
||||
@@ -627,6 +631,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function parseIsolatedEntityName(content: string, languageVersion: ScriptTarget): EntityName {
|
||||
// Choice of `isDeclarationFile` should be arbitrary
|
||||
initializeState(content, languageVersion, /*syntaxCursor*/ undefined, ScriptKind.JS);
|
||||
// Prime the scanner.
|
||||
nextToken();
|
||||
@@ -639,7 +644,7 @@ namespace ts {
|
||||
export function parseJsonText(fileName: string, sourceText: string): JsonSourceFile {
|
||||
initializeState(sourceText, ScriptTarget.ES2015, /*syntaxCursor*/ undefined, ScriptKind.JSON);
|
||||
// Set source file so that errors will be reported with this file name
|
||||
sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON);
|
||||
sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclaration*/ false);
|
||||
const result = <JsonSourceFile>sourceFile;
|
||||
|
||||
// Prime the scanner.
|
||||
@@ -681,7 +686,16 @@ namespace ts {
|
||||
identifierCount = 0;
|
||||
nodeCount = 0;
|
||||
|
||||
contextFlags = scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JSON ? NodeFlags.JavaScriptFile : NodeFlags.None;
|
||||
switch (scriptKind) {
|
||||
case ScriptKind.JS:
|
||||
case ScriptKind.JSX:
|
||||
case ScriptKind.JSON:
|
||||
contextFlags = NodeFlags.JavaScriptFile;
|
||||
break;
|
||||
default:
|
||||
contextFlags = NodeFlags.None;
|
||||
break;
|
||||
}
|
||||
parseErrorBeforeNextFinishedNode = false;
|
||||
|
||||
// Initialize and prime the scanner before parsing the source elements.
|
||||
@@ -705,7 +719,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean, scriptKind: ScriptKind): SourceFile {
|
||||
sourceFile = createSourceFile(fileName, languageVersion, scriptKind);
|
||||
const isDeclarationFile = isDeclarationFileName(fileName);
|
||||
if (isDeclarationFile) {
|
||||
contextFlags |= NodeFlags.Ambient;
|
||||
}
|
||||
|
||||
sourceFile = createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile);
|
||||
sourceFile.flags = contextFlags;
|
||||
|
||||
// Prime the scanner.
|
||||
@@ -782,7 +801,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createSourceFile(fileName: string, languageVersion: ScriptTarget, scriptKind: ScriptKind): SourceFile {
|
||||
function createSourceFile(fileName: string, languageVersion: ScriptTarget, scriptKind: ScriptKind, isDeclarationFile: boolean): SourceFile {
|
||||
// code from createNode is inlined here so createNode won't have to deal with special case of creating source files
|
||||
// this is quite rare comparing to other nodes and createNode should be as fast as possible
|
||||
const sourceFile = <SourceFile>new SourceFileConstructor(SyntaxKind.SourceFile, /*pos*/ 0, /* end */ sourceText.length);
|
||||
@@ -793,7 +812,7 @@ namespace ts {
|
||||
sourceFile.languageVersion = languageVersion;
|
||||
sourceFile.fileName = normalizePath(fileName);
|
||||
sourceFile.languageVariant = getLanguageVariant(scriptKind);
|
||||
sourceFile.isDeclarationFile = fileExtensionIs(sourceFile.fileName, Extension.Dts);
|
||||
sourceFile.isDeclarationFile = isDeclarationFile;
|
||||
sourceFile.scriptKind = scriptKind;
|
||||
|
||||
return sourceFile;
|
||||
@@ -1423,6 +1442,11 @@ namespace ts {
|
||||
return tokenIsIdentifierOrKeyword(token());
|
||||
}
|
||||
|
||||
function nextTokenIsIdentifierOrKeywordOrGreaterThan() {
|
||||
nextToken();
|
||||
return tokenIsIdentifierOrKeywordOrGreaterThan(token());
|
||||
}
|
||||
|
||||
function isHeritageClauseExtendsOrImplementsKeyword(): boolean {
|
||||
if (token() === SyntaxKind.ImplementsKeyword ||
|
||||
token() === SyntaxKind.ExtendsKeyword) {
|
||||
@@ -3802,9 +3826,9 @@ namespace ts {
|
||||
node.operand = parseLeftHandSideExpressionOrHigher();
|
||||
return finishNode(node);
|
||||
}
|
||||
else if (sourceFile.languageVariant === LanguageVariant.JSX && token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeyword)) {
|
||||
else if (sourceFile.languageVariant === LanguageVariant.JSX && token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) {
|
||||
// JSXElement is part of primaryExpression
|
||||
return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true);
|
||||
return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true);
|
||||
}
|
||||
|
||||
const expression = parseLeftHandSideExpressionOrHigher();
|
||||
@@ -3959,14 +3983,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
|
||||
function parseJsxElementOrSelfClosingElement(inExpressionContext: boolean): JsxElement | JsxSelfClosingElement {
|
||||
const opening = parseJsxOpeningOrSelfClosingElement(inExpressionContext);
|
||||
let result: JsxElement | JsxSelfClosingElement;
|
||||
function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext: boolean): JsxElement | JsxSelfClosingElement | JsxFragment {
|
||||
const opening = parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext);
|
||||
let result: JsxElement | JsxSelfClosingElement | JsxFragment;
|
||||
if (opening.kind === SyntaxKind.JsxOpeningElement) {
|
||||
const node = <JsxElement>createNode(SyntaxKind.JsxElement, opening.pos);
|
||||
node.openingElement = opening;
|
||||
|
||||
node.children = parseJsxChildren(node.openingElement.tagName);
|
||||
node.children = parseJsxChildren(node.openingElement);
|
||||
node.closingElement = parseJsxClosingElement(inExpressionContext);
|
||||
|
||||
if (!tagNamesAreEquivalent(node.openingElement.tagName, node.closingElement.tagName)) {
|
||||
@@ -3975,6 +3999,14 @@ namespace ts {
|
||||
|
||||
result = finishNode(node);
|
||||
}
|
||||
else if (opening.kind === SyntaxKind.JsxOpeningFragment) {
|
||||
const node = <JsxFragment>createNode(SyntaxKind.JsxFragment, opening.pos);
|
||||
node.openingFragment = opening;
|
||||
node.children = parseJsxChildren(node.openingFragment);
|
||||
node.closingFragment = parseJsxClosingFragment(inExpressionContext);
|
||||
|
||||
result = finishNode(node);
|
||||
}
|
||||
else {
|
||||
Debug.assert(opening.kind === SyntaxKind.JsxSelfClosingElement);
|
||||
// Nothing else to do for self-closing elements
|
||||
@@ -3989,7 +4021,7 @@ namespace ts {
|
||||
// Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios
|
||||
// of one sort or another.
|
||||
if (inExpressionContext && token() === SyntaxKind.LessThanToken) {
|
||||
const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true));
|
||||
const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true));
|
||||
if (invalidElement) {
|
||||
parseErrorAtCurrentToken(Diagnostics.JSX_expressions_must_have_one_parent_element);
|
||||
const badNode = <BinaryExpression>createNode(SyntaxKind.BinaryExpression, result.pos);
|
||||
@@ -4020,12 +4052,12 @@ namespace ts {
|
||||
case SyntaxKind.OpenBraceToken:
|
||||
return parseJsxExpression(/*inExpressionContext*/ false);
|
||||
case SyntaxKind.LessThanToken:
|
||||
return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ false);
|
||||
return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ false);
|
||||
}
|
||||
Debug.fail("Unknown JSX child kind " + token());
|
||||
}
|
||||
|
||||
function parseJsxChildren(openingTagName: LeftHandSideExpression): NodeArray<JsxChild> {
|
||||
function parseJsxChildren(openingTag: JsxOpeningElement | JsxOpeningFragment): NodeArray<JsxChild> {
|
||||
const list = [];
|
||||
const listPos = getNodePos();
|
||||
const saveParsingContext = parsingContext;
|
||||
@@ -4040,7 +4072,13 @@ namespace ts {
|
||||
else if (token() === SyntaxKind.EndOfFileToken) {
|
||||
// If we hit EOF, issue the error at the tag that lacks the closing element
|
||||
// rather than at the end of the file (which is useless)
|
||||
parseErrorAtPosition(openingTagName.pos, openingTagName.end - openingTagName.pos, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, openingTagName));
|
||||
if (isJsxOpeningFragment(openingTag)) {
|
||||
parseErrorAtPosition(openingTag.pos, openingTag.end - openingTag.pos, Diagnostics.JSX_fragment_has_no_corresponding_closing_tag);
|
||||
}
|
||||
else {
|
||||
const openingTagName = openingTag.tagName;
|
||||
parseErrorAtPosition(openingTagName.pos, openingTagName.end - openingTagName.pos, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, openingTagName));
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (token() === SyntaxKind.ConflictMarkerTrivia) {
|
||||
@@ -4063,11 +4101,17 @@ namespace ts {
|
||||
return finishNode(jsxAttributes);
|
||||
}
|
||||
|
||||
function parseJsxOpeningOrSelfClosingElement(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement {
|
||||
function parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement | JsxOpeningFragment {
|
||||
const fullStart = scanner.getStartPos();
|
||||
|
||||
parseExpected(SyntaxKind.LessThanToken);
|
||||
|
||||
if (token() === SyntaxKind.GreaterThanToken) {
|
||||
parseExpected(SyntaxKind.GreaterThanToken);
|
||||
const node: JsxOpeningFragment = <JsxOpeningFragment>createNode(SyntaxKind.JsxOpeningFragment, fullStart);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
const tagName = parseJsxElementName();
|
||||
const attributes = parseJsxAttributes();
|
||||
|
||||
@@ -4179,6 +4223,23 @@ namespace ts {
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseJsxClosingFragment(inExpressionContext: boolean): JsxClosingFragment {
|
||||
const node = <JsxClosingFragment>createNode(SyntaxKind.JsxClosingFragment);
|
||||
parseExpected(SyntaxKind.LessThanSlashToken);
|
||||
if (tokenIsIdentifierOrKeyword(token())) {
|
||||
const unexpectedTagName = parseJsxElementName();
|
||||
parseErrorAtPosition(unexpectedTagName.pos, unexpectedTagName.end - unexpectedTagName.pos, Diagnostics.Expected_corresponding_closing_tag_for_JSX_fragment);
|
||||
}
|
||||
if (inExpressionContext) {
|
||||
parseExpected(SyntaxKind.GreaterThanToken);
|
||||
}
|
||||
else {
|
||||
parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
|
||||
scanJsxText();
|
||||
}
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseTypeAssertion(): TypeAssertion {
|
||||
const node = <TypeAssertion>createNode(SyntaxKind.TypeAssertionExpression);
|
||||
parseExpected(SyntaxKind.LessThanToken);
|
||||
@@ -5089,6 +5150,18 @@ namespace ts {
|
||||
const fullStart = getNodePos();
|
||||
const decorators = parseDecorators();
|
||||
const modifiers = parseModifiers();
|
||||
if (some(modifiers, m => m.kind === SyntaxKind.DeclareKeyword)) {
|
||||
for (const m of modifiers) {
|
||||
m.flags |= NodeFlags.Ambient;
|
||||
}
|
||||
return doInsideOfContext(NodeFlags.Ambient, () => parseDeclarationWorker(fullStart, decorators, modifiers));
|
||||
}
|
||||
else {
|
||||
return parseDeclarationWorker(fullStart, decorators, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
function parseDeclarationWorker(fullStart: number, decorators: NodeArray<Decorator> | undefined, modifiers: NodeArray<Modifier> | undefined): Statement {
|
||||
switch (token()) {
|
||||
case SyntaxKind.VarKeyword:
|
||||
case SyntaxKind.LetKeyword:
|
||||
@@ -5446,8 +5519,8 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function parseDecorators(): NodeArray<Decorator> {
|
||||
let list: Decorator[];
|
||||
function parseDecorators(): NodeArray<Decorator> | undefined {
|
||||
let list: Decorator[] | undefined;
|
||||
const listPos = getNodePos();
|
||||
while (true) {
|
||||
const decoratorStart = getNodePos();
|
||||
@@ -6131,7 +6204,7 @@ namespace ts {
|
||||
export namespace JSDocParser {
|
||||
export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number): { jsDocTypeExpression: JSDocTypeExpression, diagnostics: Diagnostic[] } | undefined {
|
||||
initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
|
||||
sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS);
|
||||
sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS, /*isDeclarationFile*/ false);
|
||||
scanner.setText(content, start, length);
|
||||
currentToken = scanner.scan();
|
||||
const jsDocTypeExpression = parseJSDocTypeExpression();
|
||||
@@ -7461,4 +7534,8 @@ namespace ts {
|
||||
Value = -1
|
||||
}
|
||||
}
|
||||
|
||||
function isDeclarationFileName(fileName: string): boolean {
|
||||
return fileExtensionIs(fileName, Extension.Dts);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-14
@@ -7,18 +7,10 @@ namespace ts {
|
||||
const ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/;
|
||||
|
||||
export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string {
|
||||
while (true) {
|
||||
const fileName = combinePaths(searchPath, configName);
|
||||
if (fileExists(fileName)) {
|
||||
return fileName;
|
||||
}
|
||||
const parentPath = getDirectoryPath(searchPath);
|
||||
if (parentPath === searchPath) {
|
||||
break;
|
||||
}
|
||||
searchPath = parentPath;
|
||||
}
|
||||
return undefined;
|
||||
return forEachAncestorDirectory(searchPath, ancestor => {
|
||||
const fileName = combinePaths(ancestor, configName);
|
||||
return fileExists(fileName) ? fileName : undefined;
|
||||
});
|
||||
}
|
||||
|
||||
export function resolveTripleslashReference(moduleName: string, containingFile: string): string {
|
||||
@@ -2132,7 +2124,7 @@ namespace ts {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib");
|
||||
}
|
||||
|
||||
if (options.noImplicitUseStrict && (options.alwaysStrict === undefined ? options.strict : options.alwaysStrict)) {
|
||||
if (options.noImplicitUseStrict && getStrictOptionValue(options, "alwaysStrict")) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict");
|
||||
}
|
||||
|
||||
@@ -2361,7 +2353,7 @@ namespace ts {
|
||||
return options.jsx ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set;
|
||||
}
|
||||
function needAllowJs() {
|
||||
return options.allowJs || !options.noImplicitAny ? undefined : Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type;
|
||||
return options.allowJs || !getStrictOptionValue(options, "noImplicitAny") ? undefined : Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,9 +69,8 @@ namespace ts {
|
||||
|
||||
export const maxNumberOfFilesToIterateForInvalidation = 256;
|
||||
|
||||
interface GetResolutionWithResolvedFileName<T extends ResolutionWithFailedLookupLocations = ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName = ResolutionWithResolvedFileName> {
|
||||
(resolution: T): R;
|
||||
}
|
||||
type GetResolutionWithResolvedFileName<T extends ResolutionWithFailedLookupLocations = ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName = ResolutionWithResolvedFileName> =
|
||||
(resolution: T) => R;
|
||||
|
||||
export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string): ResolutionCache {
|
||||
let filesWithChangedSetOfUnresolvedImports: Path[] | undefined;
|
||||
@@ -320,6 +319,10 @@ namespace ts {
|
||||
return endsWith(dirPath, "/node_modules");
|
||||
}
|
||||
|
||||
function isNodeModulesAtTypesDirectory(dirPath: Path) {
|
||||
return endsWith(dirPath, "/node_modules/@types");
|
||||
}
|
||||
|
||||
function isDirectoryAtleastAtLevelFromFSRoot(dirPath: Path, minLevels: number) {
|
||||
for (let searchIndex = getRootLength(dirPath); minLevels > 0; minLevels--) {
|
||||
searchIndex = dirPath.indexOf(directorySeparator, searchIndex) + 1;
|
||||
@@ -560,11 +563,21 @@ namespace ts {
|
||||
else {
|
||||
// Some file or directory in the watching directory is created
|
||||
// Return early if it does not have any of the watching extension or not the custom failed lookup path
|
||||
if (!isPathWithDefaultFailedLookupExtension(fileOrDirectoryPath) && !customFailedLookupPaths.has(fileOrDirectoryPath)) {
|
||||
return false;
|
||||
const dirOfFileOrDirectory = getDirectoryPath(fileOrDirectoryPath);
|
||||
if (isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) {
|
||||
// Invalidate any resolution from this directory
|
||||
isChangedFailedLookupLocation = location => {
|
||||
const locationPath = resolutionHost.toPath(location);
|
||||
return locationPath === fileOrDirectoryPath || startsWith(resolutionHost.toPath(location), fileOrDirectoryPath);
|
||||
};
|
||||
}
|
||||
else {
|
||||
if (!isPathWithDefaultFailedLookupExtension(fileOrDirectoryPath) && !customFailedLookupPaths.has(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;
|
||||
}
|
||||
// Resolution need to be invalidated if failed lookup location is same as the file or directory getting created
|
||||
isChangedFailedLookupLocation = location => resolutionHost.toPath(location) === fileOrDirectoryPath;
|
||||
}
|
||||
const hasChangedFailedLookupLocation = (resolution: ResolutionWithFailedLookupLocations) => some(resolution.failedLookupLocations, isChangedFailedLookupLocation);
|
||||
const invalidatedFilesCount = filesWithInvalidatedResolutions && filesWithInvalidatedResolutions.size;
|
||||
|
||||
@@ -2,15 +2,18 @@
|
||||
/// <reference path="diagnosticInformationMap.generated.ts"/>
|
||||
|
||||
namespace ts {
|
||||
export interface ErrorCallback {
|
||||
(message: DiagnosticMessage, length: number): void;
|
||||
}
|
||||
export type ErrorCallback = (message: DiagnosticMessage, length: number) => void;
|
||||
|
||||
/* @internal */
|
||||
export function tokenIsIdentifierOrKeyword(token: SyntaxKind): boolean {
|
||||
return token >= SyntaxKind.Identifier;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function tokenIsIdentifierOrKeywordOrGreaterThan(token: SyntaxKind): boolean {
|
||||
return token === SyntaxKind.GreaterThanToken || tokenIsIdentifierOrKeyword(token);
|
||||
}
|
||||
|
||||
export interface Scanner {
|
||||
getStartPos(): number;
|
||||
getToken(): SyntaxKind;
|
||||
|
||||
+2
-2
@@ -124,7 +124,7 @@ namespace ts {
|
||||
getEnvironmentVariable?(name: string): string;
|
||||
};
|
||||
|
||||
export let sys: System = (function() {
|
||||
export let sys: System = (() => {
|
||||
function getNodeSystem(): System {
|
||||
const _fs = require("fs");
|
||||
const _path = require("path");
|
||||
@@ -594,7 +594,7 @@ namespace ts {
|
||||
if (sys) {
|
||||
// patch writefile to create folder before writing the file
|
||||
const originalWriteFile = sys.writeFile;
|
||||
sys.writeFile = function(path, data, writeBom) {
|
||||
sys.writeFile = (path, data, writeBom) => {
|
||||
const directoryPath = getDirectoryPath(normalizeSlashes(path));
|
||||
if (directoryPath && !sys.directoryExists(directoryPath)) {
|
||||
recursiveCreateDirectory(directoryPath, sys);
|
||||
|
||||
@@ -41,6 +41,9 @@ namespace ts {
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return visitJsxSelfClosingElement(<JsxSelfClosingElement>node, /*isChild*/ false);
|
||||
|
||||
case SyntaxKind.JsxFragment:
|
||||
return visitJsxFragment(<JsxFragment>node, /*isChild*/ false);
|
||||
|
||||
case SyntaxKind.JsxExpression:
|
||||
return visitJsxExpression(<JsxExpression>node);
|
||||
|
||||
@@ -63,6 +66,9 @@ namespace ts {
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return visitJsxSelfClosingElement(<JsxSelfClosingElement>node, /*isChild*/ true);
|
||||
|
||||
case SyntaxKind.JsxFragment:
|
||||
return visitJsxFragment(<JsxFragment>node, /*isChild*/ true);
|
||||
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return undefined;
|
||||
@@ -77,6 +83,10 @@ namespace ts {
|
||||
return visitJsxOpeningLikeElement(node, /*children*/ undefined, isChild, /*location*/ node);
|
||||
}
|
||||
|
||||
function visitJsxFragment(node: JsxFragment, isChild: boolean) {
|
||||
return visitJsxOpeningFragment(node.openingFragment, node.children, isChild, /*location*/ node);
|
||||
}
|
||||
|
||||
function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: ReadonlyArray<JsxChild>, isChild: boolean, location: TextRange) {
|
||||
const tagName = getTagName(node);
|
||||
let objectProperties: Expression;
|
||||
@@ -126,6 +136,22 @@ namespace ts {
|
||||
return element;
|
||||
}
|
||||
|
||||
function visitJsxOpeningFragment(node: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, isChild: boolean, location: TextRange) {
|
||||
const element = createExpressionForJsxFragment(
|
||||
context.getEmitResolver().getJsxFactoryEntity(),
|
||||
compilerOptions.reactNamespace,
|
||||
mapDefined(children, transformJsxChildToExpression),
|
||||
node,
|
||||
location
|
||||
);
|
||||
|
||||
if (isChild) {
|
||||
startOnNewLine(element);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
function transformJsxSpreadAttributeToExpression(node: JsxSpreadAttribute) {
|
||||
return visitNode(node.expression, visitor, isExpression);
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace ts {
|
||||
startLexicalEnvironment();
|
||||
|
||||
const statements: Statement[] = [];
|
||||
const ensureUseStrict = compilerOptions.alwaysStrict || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile));
|
||||
const ensureUseStrict = getStrictOptionValue(compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile));
|
||||
const statementOffset = addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor);
|
||||
|
||||
if (shouldEmitUnderscoreUnderscoreESModule()) {
|
||||
|
||||
@@ -146,8 +146,7 @@ namespace ts {
|
||||
function collectDependencyGroups(externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]) {
|
||||
const groupIndices = createMap<number>();
|
||||
const dependencyGroups: DependencyGroup[] = [];
|
||||
for (let i = 0; i < externalImports.length; i++) {
|
||||
const externalImport = externalImports[i];
|
||||
for (const externalImport of externalImports) {
|
||||
const externalModuleName = getExternalModuleNameLiteral(externalImport, currentSourceFile, host, resolver, compilerOptions);
|
||||
if (externalModuleName) {
|
||||
const text = externalModuleName.text;
|
||||
@@ -225,7 +224,7 @@ namespace ts {
|
||||
startLexicalEnvironment();
|
||||
|
||||
// Add any prologue directives.
|
||||
const ensureUseStrict = compilerOptions.alwaysStrict || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile));
|
||||
const ensureUseStrict = getStrictOptionValue(compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile));
|
||||
const statementOffset = addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor);
|
||||
|
||||
// var __moduleName = context_1 && context_1.id;
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace ts {
|
||||
|
||||
const resolver = context.getEmitResolver();
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
const strictNullChecks = typeof compilerOptions.strictNullChecks === "undefined" ? compilerOptions.strict : compilerOptions.strictNullChecks;
|
||||
const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks");
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
|
||||
@@ -225,6 +225,13 @@ namespace ts {
|
||||
if (parsed !== node) {
|
||||
// If the node has been transformed by a `before` transformer, perform no ellision on it
|
||||
// As the type information we would attempt to lookup to perform ellision is potentially unavailable for the synthesized nodes
|
||||
// We do not reuse `visitorWorker`, as the ellidable statement syntax kinds are technically unrecognized by the switch-case in `visitTypeScript`,
|
||||
// and will trigger debug failures when debug verbosity is turned up
|
||||
if (node.transformFlags & TransformFlags.ContainsTypeScript) {
|
||||
// This node contains TypeScript, so we should visit its children.
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
// Otherwise, we can just return the node
|
||||
return node;
|
||||
}
|
||||
switch (node.kind) {
|
||||
@@ -521,7 +528,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitSourceFile(node: SourceFile) {
|
||||
const alwaysStrict = (compilerOptions.alwaysStrict === undefined ? compilerOptions.strict : compilerOptions.alwaysStrict) &&
|
||||
const alwaysStrict = getStrictOptionValue(compilerOptions, "alwaysStrict") &&
|
||||
!(isExternalModule(node) && moduleKind >= ModuleKind.ES2015);
|
||||
return updateSourceFileNode(
|
||||
node,
|
||||
|
||||
+2
-16
@@ -43,20 +43,12 @@ namespace ts {
|
||||
return s;
|
||||
}
|
||||
|
||||
function isJSONSupported() {
|
||||
return typeof JSON === "object" && typeof JSON.parse === "function";
|
||||
}
|
||||
|
||||
export function executeCommandLine(args: string[]): void {
|
||||
const commandLine = parseCommandLine(args);
|
||||
|
||||
// Configuration file name (if any)
|
||||
let configFileName: string;
|
||||
if (commandLine.options.locale) {
|
||||
if (!isJSONSupported()) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--locale"));
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
validateLocaleAndSetLanguage(commandLine.options.locale, sys, commandLine.errors);
|
||||
}
|
||||
|
||||
@@ -84,10 +76,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (commandLine.options.project) {
|
||||
if (!isJSONSupported()) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--project"));
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
if (commandLine.fileNames.length !== 0) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Option_project_cannot_be_mixed_with_source_files_on_a_command_line));
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
@@ -109,7 +97,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (commandLine.fileNames.length === 0 && isJSONSupported()) {
|
||||
else if (commandLine.fileNames.length === 0) {
|
||||
const searchPath = normalizePath(sys.getCurrentDirectory());
|
||||
configFileName = findConfigFile(searchPath, sys.fileExists);
|
||||
}
|
||||
@@ -317,9 +305,7 @@ namespace ts {
|
||||
|
||||
const optionsDescriptionMap = createMap<string[]>(); // Map between option.description and list of option.type if it is a kind
|
||||
|
||||
for (let i = 0; i < optsList.length; i++) {
|
||||
const option = optsList[i];
|
||||
|
||||
for (const option of optsList) {
|
||||
// If an option lacks a description,
|
||||
// it is not officially supported.
|
||||
if (!option.description) {
|
||||
|
||||
+49
-16
@@ -341,6 +341,9 @@ namespace ts {
|
||||
JsxSelfClosingElement,
|
||||
JsxOpeningElement,
|
||||
JsxClosingElement,
|
||||
JsxFragment,
|
||||
JsxOpeningFragment,
|
||||
JsxClosingFragment,
|
||||
JsxAttribute,
|
||||
JsxAttributes,
|
||||
JsxSpreadAttribute,
|
||||
@@ -375,6 +378,7 @@ namespace ts {
|
||||
JSDocFunctionType,
|
||||
JSDocVariadicType,
|
||||
JSDocComment,
|
||||
JSDocTypeLiteral,
|
||||
JSDocTag,
|
||||
JSDocAugmentsTag,
|
||||
JSDocClassTag,
|
||||
@@ -384,7 +388,6 @@ namespace ts {
|
||||
JSDocTemplateTag,
|
||||
JSDocTypedefTag,
|
||||
JSDocPropertyTag,
|
||||
JSDocTypeLiteral,
|
||||
|
||||
// Synthesized list
|
||||
SyntaxList,
|
||||
@@ -426,9 +429,9 @@ namespace ts {
|
||||
LastBinaryOperator = CaretEqualsToken,
|
||||
FirstNode = QualifiedName,
|
||||
FirstJSDocNode = JSDocTypeExpression,
|
||||
LastJSDocNode = JSDocTypeLiteral,
|
||||
LastJSDocNode = JSDocPropertyTag,
|
||||
FirstJSDocTagNode = JSDocTag,
|
||||
LastJSDocTagNode = JSDocTypeLiteral
|
||||
LastJSDocTagNode = JSDocPropertyTag
|
||||
}
|
||||
|
||||
export const enum NodeFlags {
|
||||
@@ -464,7 +467,8 @@ namespace ts {
|
||||
/* @internal */
|
||||
PossiblyContainsDynamicImport = 1 << 19,
|
||||
JSDoc = 1 << 20, // If node was parsed inside jsdoc
|
||||
/* @internal */ InWithStatement = 1 << 21, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`)
|
||||
/* @internal */ Ambient = 1 << 21, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier.
|
||||
/* @internal */ InWithStatement = 1 << 22, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`)
|
||||
|
||||
BlockScoped = Let | Const,
|
||||
|
||||
@@ -472,7 +476,7 @@ namespace ts {
|
||||
ReachabilityAndEmitFlags = ReachabilityCheckFlags | HasAsyncFunctions,
|
||||
|
||||
// Parsing context flags
|
||||
ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile | InWithStatement,
|
||||
ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile | InWithStatement | Ambient,
|
||||
|
||||
// Exclude these flags when parsing a Type
|
||||
TypeExcludesFlags = YieldContext | AwaitContext,
|
||||
@@ -1633,7 +1637,7 @@ namespace ts {
|
||||
closingElement: JsxClosingElement;
|
||||
}
|
||||
|
||||
/// Either the opening tag in a <Tag>...</Tag> pair, or the lone <Tag /> in a self-closing form
|
||||
/// Either the opening tag in a <Tag>...</Tag> pair or the lone <Tag /> in a self-closing form
|
||||
export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement;
|
||||
|
||||
export type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute;
|
||||
@@ -1659,6 +1663,26 @@ namespace ts {
|
||||
attributes: JsxAttributes;
|
||||
}
|
||||
|
||||
/// A JSX expression of the form <>...</>
|
||||
export interface JsxFragment extends PrimaryExpression {
|
||||
kind: SyntaxKind.JsxFragment;
|
||||
openingFragment: JsxOpeningFragment;
|
||||
children: NodeArray<JsxChild>;
|
||||
closingFragment: JsxClosingFragment;
|
||||
}
|
||||
|
||||
/// The opening element of a <>...</> JsxFragment
|
||||
export interface JsxOpeningFragment extends Expression {
|
||||
kind: SyntaxKind.JsxOpeningFragment;
|
||||
parent?: JsxFragment;
|
||||
}
|
||||
|
||||
/// The closing element of a <>...</> JsxFragment
|
||||
export interface JsxClosingFragment extends Expression {
|
||||
kind: SyntaxKind.JsxClosingFragment;
|
||||
parent?: JsxFragment;
|
||||
}
|
||||
|
||||
export interface JsxAttribute extends ObjectLiteralElement {
|
||||
kind: SyntaxKind.JsxAttribute;
|
||||
parent?: JsxAttributes;
|
||||
@@ -1692,7 +1716,7 @@ namespace ts {
|
||||
parent?: JsxElement;
|
||||
}
|
||||
|
||||
export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement;
|
||||
export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment;
|
||||
|
||||
export interface Statement extends Node {
|
||||
_statementBrand: any;
|
||||
@@ -2461,9 +2485,13 @@ namespace ts {
|
||||
readFile(path: string): string | undefined;
|
||||
}
|
||||
|
||||
export interface WriteFileCallback {
|
||||
(fileName: string, data: string, writeByteOrderMark: boolean, onError: ((message: string) => void) | undefined, sourceFiles: ReadonlyArray<SourceFile>): void;
|
||||
}
|
||||
export type WriteFileCallback = (
|
||||
fileName: string,
|
||||
data: string,
|
||||
writeByteOrderMark: boolean,
|
||||
onError: ((message: string) => void) | undefined,
|
||||
sourceFiles: ReadonlyArray<SourceFile>,
|
||||
) => void;
|
||||
|
||||
export class OperationCanceledException { }
|
||||
|
||||
@@ -3340,6 +3368,7 @@ namespace ts {
|
||||
ObjectLiteral = 1 << 7, // Originates in an object literal
|
||||
EvolvingArray = 1 << 8, // Evolving array type
|
||||
ObjectLiteralPatternWithComputedProperties = 1 << 9, // Object literal pattern with computed properties
|
||||
ContainsSpread = 1 << 10, // Object literal contains spread operation
|
||||
ClassOrInterface = Class | Interface
|
||||
}
|
||||
|
||||
@@ -3571,9 +3600,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface TypeMapper {
|
||||
(t: TypeParameter): Type;
|
||||
}
|
||||
export type TypeMapper = (t: TypeParameter) => Type;
|
||||
|
||||
export const enum InferencePriority {
|
||||
Contravariant = 1 << 0, // Inference from contravariant position
|
||||
@@ -3622,6 +3649,14 @@ namespace ts {
|
||||
compareTypes: TypeComparer; // Type comparer function
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface WideningContext {
|
||||
parent?: WideningContext; // Parent context
|
||||
propertyName?: __String; // Name of property in parent
|
||||
siblings?: Type[]; // Types of siblings
|
||||
resolvedPropertyNames?: __String[]; // Property names occurring in sibling object literals
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const enum SpecialPropertyAssignmentKind {
|
||||
None,
|
||||
@@ -4173,9 +4208,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface HasInvalidatedResolution {
|
||||
(sourceFile: Path): boolean;
|
||||
}
|
||||
export type HasInvalidatedResolution = (sourceFile: Path) => boolean;
|
||||
|
||||
export interface CompilerHost extends ModuleResolutionHost {
|
||||
getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile | undefined;
|
||||
|
||||
+32
-17
@@ -1132,7 +1132,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a node is a property or element access expression for super.
|
||||
* Determines whether a node is a property or element access expression for `super`.
|
||||
*/
|
||||
export function isSuperProperty(node: Node): node is SuperProperty {
|
||||
const kind = node.kind;
|
||||
@@ -1140,7 +1140,16 @@ namespace ts {
|
||||
&& (<PropertyAccessExpression | ElementAccessExpression>node).expression.kind === SyntaxKind.SuperKeyword;
|
||||
}
|
||||
|
||||
export function getEntityNameFromTypeNode(node: TypeNode): EntityNameOrEntityNameExpression {
|
||||
/**
|
||||
* Determines whether a node is a property or element access expression for `this`.
|
||||
*/
|
||||
export function isThisProperty(node: Node): boolean {
|
||||
const kind = node.kind;
|
||||
return (kind === SyntaxKind.PropertyAccessExpression || kind === SyntaxKind.ElementAccessExpression)
|
||||
&& (<PropertyAccessExpression | ElementAccessExpression>node).expression.kind === SyntaxKind.ThisKeyword;
|
||||
}
|
||||
|
||||
export function getEntityNameFromTypeNode(node: TypeNode): EntityNameOrEntityNameExpression {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.TypeReference:
|
||||
return (<TypeReferenceNode>node).typeName;
|
||||
@@ -1228,7 +1237,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isPartOfExpression(node: Node): boolean {
|
||||
export function isExpressionNode(node: Node): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.SuperKeyword:
|
||||
case SyntaxKind.NullKeyword:
|
||||
@@ -1262,6 +1271,7 @@ namespace ts {
|
||||
case SyntaxKind.OmittedExpression:
|
||||
case SyntaxKind.JsxElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxFragment:
|
||||
case SyntaxKind.YieldExpression:
|
||||
case SyntaxKind.AwaitExpression:
|
||||
case SyntaxKind.MetaProperty:
|
||||
@@ -1331,7 +1341,7 @@ namespace ts {
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return (<ExpressionWithTypeArguments>parent).expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent);
|
||||
default:
|
||||
return isPartOfExpression(parent);
|
||||
return isExpressionNode(parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1718,16 +1728,6 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isInAmbientContext(node: Node): boolean {
|
||||
while (node) {
|
||||
if (hasModifier(node, ModifierFlags.Ambient) || (node.kind === SyntaxKind.SourceFile && (node as SourceFile).isDeclarationFile)) {
|
||||
return true;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// True if the given identifier, string literal, or number literal is the name of a declaration node
|
||||
export function isDeclarationName(name: Node): boolean {
|
||||
switch (name.kind) {
|
||||
@@ -2170,6 +2170,7 @@ namespace ts {
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.JsxElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxFragment:
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.TemplateExpression:
|
||||
@@ -3599,7 +3600,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Calls `callback` on `directory` and every ancestor directory it has, returning the first defined result. */
|
||||
export function forEachAncestorDirectory<T>(directory: string, callback: (directory: string) => T): T {
|
||||
export function forEachAncestorDirectory<T>(directory: string, callback: (directory: string) => T | undefined): T | undefined {
|
||||
while (true) {
|
||||
const result = callback(directory);
|
||||
if (result !== undefined) {
|
||||
@@ -4805,6 +4806,18 @@ namespace ts {
|
||||
return node.kind === SyntaxKind.JsxClosingElement;
|
||||
}
|
||||
|
||||
export function isJsxFragment(node: Node): node is JsxFragment {
|
||||
return node.kind === SyntaxKind.JsxFragment;
|
||||
}
|
||||
|
||||
export function isJsxOpeningFragment(node: Node): node is JsxOpeningFragment {
|
||||
return node.kind === SyntaxKind.JsxOpeningFragment;
|
||||
}
|
||||
|
||||
export function isJsxClosingFragment(node: Node): node is JsxClosingFragment {
|
||||
return node.kind === SyntaxKind.JsxClosingFragment;
|
||||
}
|
||||
|
||||
export function isJsxAttribute(node: Node): node is JsxAttribute {
|
||||
return node.kind === SyntaxKind.JsxAttribute;
|
||||
}
|
||||
@@ -5330,6 +5343,7 @@ namespace ts {
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.JsxElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxFragment:
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
@@ -5392,7 +5406,7 @@ namespace ts {
|
||||
/* @internal */
|
||||
/**
|
||||
* Determines whether a node is an expression based only on its kind.
|
||||
* Use `isPartOfExpression` if not in transforms.
|
||||
* Use `isExpressionNode` if not in transforms.
|
||||
*/
|
||||
export function isExpression(node: Node): node is Expression {
|
||||
return isExpressionKind(skipPartiallyEmittedExpressions(node).kind);
|
||||
@@ -5651,7 +5665,8 @@ namespace ts {
|
||||
return kind === SyntaxKind.JsxElement
|
||||
|| kind === SyntaxKind.JsxExpression
|
||||
|| kind === SyntaxKind.JsxSelfClosingElement
|
||||
|| kind === SyntaxKind.JsxText;
|
||||
|| kind === SyntaxKind.JsxText
|
||||
|| kind === SyntaxKind.JsxFragment;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
||||
@@ -819,6 +819,12 @@ namespace ts {
|
||||
return updateJsxClosingElement(<JsxClosingElement>node,
|
||||
visitNode((<JsxClosingElement>node).tagName, visitor, isJsxTagNameExpression));
|
||||
|
||||
case SyntaxKind.JsxFragment:
|
||||
return updateJsxFragment(<JsxFragment>node,
|
||||
visitNode((<JsxFragment>node).openingFragment, visitor, isJsxOpeningFragment),
|
||||
nodesVisitor((<JsxFragment>node).children, visitor, isJsxChild),
|
||||
visitNode((<JsxFragment>node).closingFragment, visitor, isJsxClosingFragment));
|
||||
|
||||
case SyntaxKind.JsxAttribute:
|
||||
return updateJsxAttribute(<JsxAttribute>node,
|
||||
visitNode((<JsxAttribute>node).name, visitor, isIdentifier),
|
||||
@@ -1334,6 +1340,12 @@ namespace ts {
|
||||
result = reduceNode((<JsxElement>node).closingElement, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.JsxFragment:
|
||||
result = reduceNode((<JsxFragment>node).openingFragment, cbNode, result);
|
||||
result = reduceLeft((<JsxFragment>node).children, cbNode, result);
|
||||
result = reduceNode((<JsxFragment>node).closingFragment, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
result = reduceNode((<JsxSelfClosingElement | JsxOpeningElement>node).tagName, cbNode, result);
|
||||
|
||||
@@ -211,8 +211,8 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
this.emit = false;
|
||||
|
||||
const opts = this.options.split(",");
|
||||
for (let i = 0; i < opts.length; i++) {
|
||||
switch (opts[i]) {
|
||||
for (const opt of opts) {
|
||||
switch (opt) {
|
||||
case "emit":
|
||||
this.emit = true;
|
||||
break;
|
||||
|
||||
+136
-60
@@ -314,7 +314,7 @@ namespace FourSlash {
|
||||
|
||||
const languageServiceAdapter = this.getLanguageServiceAdapter(testType, this.cancellationToken, compilationOptions);
|
||||
this.languageServiceAdapterHost = languageServiceAdapter.getHost();
|
||||
this.languageService = languageServiceAdapter.getLanguageService();
|
||||
this.languageService = memoWrap(languageServiceAdapter.getLanguageService(), this); // Wrap the LS to cache some expensive operations certain tests call repeatedly
|
||||
|
||||
if (startResolveFileRef) {
|
||||
// Add the entry-point file itself into the languageServiceShimHost
|
||||
@@ -381,6 +381,39 @@ namespace FourSlash {
|
||||
|
||||
// Open the first file by default
|
||||
this.openFile(0);
|
||||
|
||||
function memoWrap(ls: ts.LanguageService, target: TestState): ts.LanguageService {
|
||||
const cacheableMembers: (keyof typeof ls)[] = [
|
||||
"getCompletionsAtPosition",
|
||||
"getCompletionEntryDetails",
|
||||
"getCompletionEntrySymbol",
|
||||
"getQuickInfoAtPosition",
|
||||
"getSignatureHelpItems",
|
||||
"getReferencesAtPosition",
|
||||
"getDocumentHighlights",
|
||||
];
|
||||
const proxy = {} as ts.LanguageService;
|
||||
for (const k in ls) {
|
||||
const key = k as keyof typeof ls;
|
||||
if (cacheableMembers.indexOf(key) === -1) {
|
||||
proxy[key] = (...args: any[]) => (ls[key] as Function)(...args);
|
||||
continue;
|
||||
}
|
||||
const memo = Utils.memoize(
|
||||
(_version: number, _active: string, _caret: number, _selectEnd: number, _marker: string, ...args: any[]) => (ls[key] as Function)(...args),
|
||||
(...args) => args.join("|,|")
|
||||
);
|
||||
proxy[key] = (...args: any[]) => memo(
|
||||
target.languageServiceAdapterHost.getScriptInfo(target.activeFile.fileName).version,
|
||||
target.activeFile.fileName,
|
||||
target.currentCaretPosition,
|
||||
target.selectionEnd,
|
||||
target.lastKnownMarker,
|
||||
...args
|
||||
);
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
}
|
||||
|
||||
private getFileContent(fileName: string): string {
|
||||
@@ -437,6 +470,10 @@ namespace FourSlash {
|
||||
|
||||
public select(startMarker: string, endMarker: string) {
|
||||
const start = this.getMarkerByName(startMarker), end = this.getMarkerByName(endMarker);
|
||||
ts.Debug.assert(start.fileName === end.fileName);
|
||||
if (this.activeFile.fileName !== start.fileName) {
|
||||
this.openFile(start.fileName);
|
||||
}
|
||||
this.goToPosition(start.position);
|
||||
this.selectionEnd = end.position;
|
||||
}
|
||||
@@ -599,19 +636,23 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
public verifyGoToDefinition(arg0: any, endMarkerNames?: string | string[]) {
|
||||
this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinition());
|
||||
this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinitionAndBoundSpan());
|
||||
}
|
||||
|
||||
private getGoToDefinition(): ts.DefinitionInfo[] {
|
||||
return this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
}
|
||||
|
||||
private getGoToDefinitionAndBoundSpan(): ts.DefinitionInfoAndBoundSpan {
|
||||
return this.languageService.getDefinitionAndBoundSpan(this.activeFile.fileName, this.currentCaretPosition);
|
||||
}
|
||||
|
||||
public verifyGoToType(arg0: any, endMarkerNames?: string | string[]) {
|
||||
this.verifyGoToX(arg0, endMarkerNames, () =>
|
||||
this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition));
|
||||
}
|
||||
|
||||
private verifyGoToX(arg0: any, endMarkerNames: string | string[] | undefined, getDefs: () => ts.DefinitionInfo[] | undefined) {
|
||||
private verifyGoToX(arg0: any, endMarkerNames: string | string[] | undefined, getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
|
||||
if (endMarkerNames) {
|
||||
this.verifyGoToXPlain(arg0, endMarkerNames, getDefs);
|
||||
}
|
||||
@@ -631,7 +672,7 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
private verifyGoToXPlain(startMarkerNames: string | string[], endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | undefined) {
|
||||
private verifyGoToXPlain(startMarkerNames: string | string[], endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
|
||||
for (const start of toArray(startMarkerNames)) {
|
||||
this.verifyGoToXSingle(start, endMarkerNames, getDefs);
|
||||
}
|
||||
@@ -643,26 +684,57 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
private verifyGoToXSingle(startMarkerName: string, endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | undefined) {
|
||||
private verifyGoToXSingle(startMarkerName: string, endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
|
||||
this.goToMarker(startMarkerName);
|
||||
this.verifyGoToXWorker(toArray(endMarkerNames), getDefs);
|
||||
this.verifyGoToXWorker(toArray(endMarkerNames), getDefs, startMarkerName);
|
||||
}
|
||||
|
||||
private verifyGoToXWorker(endMarkers: string[], getDefs: () => ts.DefinitionInfo[] | undefined) {
|
||||
const definitions = getDefs() || [];
|
||||
private verifyGoToXWorker(endMarkers: string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined, startMarkerName?: string) {
|
||||
const defs = getDefs();
|
||||
let definitions: ts.DefinitionInfo[] | ReadonlyArray<ts.DefinitionInfo>;
|
||||
let testName: string;
|
||||
|
||||
if (!defs || Array.isArray(defs)) {
|
||||
definitions = defs as ts.DefinitionInfo[] || [];
|
||||
testName = "goToDefinitions";
|
||||
}
|
||||
else {
|
||||
this.verifyDefinitionTextSpan(defs, startMarkerName);
|
||||
|
||||
definitions = defs.definitions;
|
||||
testName = "goToDefinitionsAndBoundSpan";
|
||||
}
|
||||
|
||||
if (endMarkers.length !== definitions.length) {
|
||||
this.raiseError(`goToDefinitions failed - expected to find ${endMarkers.length} definitions but got ${definitions.length}`);
|
||||
this.raiseError(`${testName} failed - expected to find ${endMarkers.length} definitions but got ${definitions.length}`);
|
||||
}
|
||||
|
||||
ts.zipWith(endMarkers, definitions, (endMarker, definition, i) => {
|
||||
const marker = this.getMarkerByName(endMarker);
|
||||
if (marker.fileName !== definition.fileName || marker.position !== definition.textSpan.start) {
|
||||
this.raiseError(`goToDefinition failed for definition ${endMarker} (${i}): expected ${marker.fileName} at ${marker.position}, got ${definition.fileName} at ${definition.textSpan.start}`);
|
||||
this.raiseError(`${testName} failed for definition ${endMarker} (${i}): expected ${marker.fileName} at ${marker.position}, got ${definition.fileName} at ${definition.textSpan.start}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private verifyDefinitionTextSpan(defs: ts.DefinitionInfoAndBoundSpan, startMarkerName: string) {
|
||||
const range = this.testData.ranges.find(range => this.markerName(range.marker) === startMarkerName);
|
||||
|
||||
if (!range && !defs.textSpan) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!range) {
|
||||
this.raiseError(`goToDefinitionsAndBoundSpan failed - found a TextSpan ${JSON.stringify(defs.textSpan)} when it wasn't expected.`);
|
||||
}
|
||||
else if (defs.textSpan.start !== range.start || defs.textSpan.length !== range.end - range.start) {
|
||||
const expected: ts.TextSpan = {
|
||||
start: range.start, length: range.end - range.start
|
||||
};
|
||||
this.raiseError(`goToDefinitionsAndBoundSpan failed - expected to find TextSpan ${JSON.stringify(expected)} but got ${JSON.stringify(defs.textSpan)}`);
|
||||
}
|
||||
}
|
||||
|
||||
public verifyGetEmitOutputForCurrentFile(expected: string): void {
|
||||
const emit = this.languageService.getEmitOutput(this.activeFile.fileName);
|
||||
if (emit.outputFiles.length !== 1) {
|
||||
@@ -799,13 +871,13 @@ namespace FourSlash {
|
||||
});
|
||||
}
|
||||
|
||||
public verifyCompletionListContains(symbol: string, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean) {
|
||||
const completions = this.getCompletionListAtCaret();
|
||||
public verifyCompletionListContains(entryId: ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean, options?: ts.GetCompletionsAtPositionOptions) {
|
||||
const completions = this.getCompletionListAtCaret(options);
|
||||
if (completions) {
|
||||
this.assertItemInCompletionList(completions.entries, symbol, text, documentation, kind, spanIndex, hasAction);
|
||||
this.assertItemInCompletionList(completions.entries, entryId, text, documentation, kind, spanIndex, hasAction);
|
||||
}
|
||||
else {
|
||||
this.raiseError(`No completions at position '${this.currentCaretPosition}' when looking for '${symbol}'.`);
|
||||
this.raiseError(`No completions at position '${this.currentCaretPosition}' when looking for '${JSON.stringify(entryId)}'.`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -820,43 +892,40 @@ namespace FourSlash {
|
||||
* @param expectedKind the kind of symbol (see ScriptElementKind)
|
||||
* @param spanIndex the index of the range that the completion item's replacement text span should match
|
||||
*/
|
||||
public verifyCompletionListDoesNotContain(symbol: string, expectedText?: string, expectedDocumentation?: string, expectedKind?: string, spanIndex?: number) {
|
||||
const that = this;
|
||||
public verifyCompletionListDoesNotContain(entryId: ts.Completions.CompletionEntryIdentifier, expectedText?: string, expectedDocumentation?: string, expectedKind?: string, spanIndex?: number, options?: ts.GetCompletionsAtPositionOptions) {
|
||||
let replacementSpan: ts.TextSpan;
|
||||
if (spanIndex !== undefined) {
|
||||
replacementSpan = this.getTextSpanForRangeAtIndex(spanIndex);
|
||||
}
|
||||
|
||||
function filterByTextOrDocumentation(entry: ts.CompletionEntry) {
|
||||
const details = that.getCompletionEntryDetails(entry.name);
|
||||
const documentation = details && ts.displayPartsToString(details.documentation);
|
||||
const text = details && ts.displayPartsToString(details.displayParts);
|
||||
|
||||
// If any of the expected values are undefined, assume that users don't
|
||||
// care about them.
|
||||
if (replacementSpan && !TestState.textSpansEqual(replacementSpan, entry.replacementSpan)) {
|
||||
return false;
|
||||
}
|
||||
else if (expectedText && text !== expectedText) {
|
||||
return false;
|
||||
}
|
||||
else if (expectedDocumentation && documentation !== expectedDocumentation) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const completions = this.getCompletionListAtCaret();
|
||||
const completions = this.getCompletionListAtCaret(options);
|
||||
if (completions) {
|
||||
let filterCompletions = completions.entries.filter(e => e.name === symbol);
|
||||
let filterCompletions = completions.entries.filter(e => e.name === entryId.name && e.source === entryId.source);
|
||||
filterCompletions = expectedKind ? filterCompletions.filter(e => e.kind === expectedKind) : filterCompletions;
|
||||
filterCompletions = filterCompletions.filter(filterByTextOrDocumentation);
|
||||
filterCompletions = filterCompletions.filter(entry => {
|
||||
const details = this.getCompletionEntryDetails(entry.name);
|
||||
const documentation = details && ts.displayPartsToString(details.documentation);
|
||||
const text = details && ts.displayPartsToString(details.displayParts);
|
||||
|
||||
// If any of the expected values are undefined, assume that users don't
|
||||
// care about them.
|
||||
if (replacementSpan && !TestState.textSpansEqual(replacementSpan, entry.replacementSpan)) {
|
||||
return false;
|
||||
}
|
||||
else if (expectedText && text !== expectedText) {
|
||||
return false;
|
||||
}
|
||||
else if (expectedDocumentation && documentation !== expectedDocumentation) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
if (filterCompletions.length !== 0) {
|
||||
// After filtered using all present criterion, if there are still symbol left in the list
|
||||
// then these symbols must meet the criterion for Not supposed to be in the list. So we
|
||||
// raise an error
|
||||
let error = "Completion list did contain \'" + symbol + "\'.";
|
||||
let error = `Completion list did contain '${JSON.stringify(entryId)}\'.`;
|
||||
const details = this.getCompletionEntryDetails(filterCompletions[0].name);
|
||||
if (expectedText) {
|
||||
error += "Expected text: " + expectedText + " to equal: " + ts.displayPartsToString(details.displayParts) + ".";
|
||||
@@ -1142,12 +1211,12 @@ Actual: ${stringify(fullActual)}`);
|
||||
this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(references)})`);
|
||||
}
|
||||
|
||||
private getCompletionListAtCaret() {
|
||||
return this.languageService.getCompletionsAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
private getCompletionListAtCaret(options?: ts.GetCompletionsAtPositionOptions): ts.CompletionInfo {
|
||||
return this.languageService.getCompletionsAtPosition(this.activeFile.fileName, this.currentCaretPosition, options);
|
||||
}
|
||||
|
||||
private getCompletionEntryDetails(entryName: string) {
|
||||
return this.languageService.getCompletionEntryDetails(this.activeFile.fileName, this.currentCaretPosition, entryName, this.formatCodeSettings);
|
||||
private getCompletionEntryDetails(entryName: string, source?: string): ts.CompletionEntryDetails {
|
||||
return this.languageService.getCompletionEntryDetails(this.activeFile.fileName, this.currentCaretPosition, entryName, this.formatCodeSettings, source);
|
||||
}
|
||||
|
||||
private getReferencesAtCaret() {
|
||||
@@ -1656,7 +1725,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
const longestNameLength = max(entries, m => m.name.length);
|
||||
const longestKindLength = max(entries, m => m.kind.length);
|
||||
entries.sort((m, n) => m.sortText > n.sortText ? 1 : m.sortText < n.sortText ? -1 : m.name > n.name ? 1 : m.name < n.name ? -1 : 0);
|
||||
const membersString = entries.map(m => `${pad(m.name, longestNameLength)} ${pad(m.kind, longestKindLength)} ${m.kindModifiers}`).join("\n");
|
||||
const membersString = entries.map(m => `${pad(m.name, longestNameLength)} ${pad(m.kind, longestKindLength)} ${m.kindModifiers} ${m.source === undefined ? "" : m.source}`).join("\n");
|
||||
Harness.IO.log(membersString);
|
||||
}
|
||||
|
||||
@@ -1737,7 +1806,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
else if (prevChar === " " && /A-Za-z_/.test(ch)) {
|
||||
/* Completions */
|
||||
this.languageService.getCompletionsAtPosition(this.activeFile.fileName, offset);
|
||||
this.languageService.getCompletionsAtPosition(this.activeFile.fileName, offset, { includeExternalModuleExports: false });
|
||||
}
|
||||
|
||||
if (i % checkCadence === 0) {
|
||||
@@ -2312,13 +2381,13 @@ Actual: ${stringify(fullActual)}`);
|
||||
public applyCodeActionFromCompletion(markerName: string, options: FourSlashInterface.VerifyCompletionActionOptions) {
|
||||
this.goToMarker(markerName);
|
||||
|
||||
const actualCompletion = this.getCompletionListAtCaret().entries.find(e => e.name === options.name);
|
||||
const actualCompletion = this.getCompletionListAtCaret({ includeExternalModuleExports: true }).entries.find(e => e.name === options.name && e.source === options.source);
|
||||
|
||||
if (!actualCompletion.hasAction) {
|
||||
this.raiseError(`Completion for ${options.name} does not have an associated action.`);
|
||||
}
|
||||
|
||||
const details = this.getCompletionEntryDetails(options.name);
|
||||
const details = this.getCompletionEntryDetails(options.name, actualCompletion.source);
|
||||
if (details.codeActions.length !== 1) {
|
||||
this.raiseError(`Expected one code action, got ${details.codeActions.length}`);
|
||||
}
|
||||
@@ -3000,7 +3069,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
|
||||
private assertItemInCompletionList(
|
||||
items: ts.CompletionEntry[],
|
||||
name: string,
|
||||
entryId: ts.Completions.CompletionEntryIdentifier,
|
||||
text: string | undefined,
|
||||
documentation: string | undefined,
|
||||
kind: string | undefined,
|
||||
@@ -3008,25 +3077,27 @@ Actual: ${stringify(fullActual)}`);
|
||||
hasAction: boolean | undefined,
|
||||
) {
|
||||
for (const item of items) {
|
||||
if (item.name === name) {
|
||||
if (documentation !== undefined || text !== undefined) {
|
||||
const details = this.getCompletionEntryDetails(item.name);
|
||||
if (item.name === entryId.name && item.source === entryId.source) {
|
||||
if (documentation !== undefined || text !== undefined || entryId.source !== undefined) {
|
||||
const details = this.getCompletionEntryDetails(item.name, item.source);
|
||||
|
||||
if (documentation !== undefined) {
|
||||
assert.equal(ts.displayPartsToString(details.documentation), documentation, this.assertionMessageAtLastKnownMarker("completion item documentation for " + name));
|
||||
assert.equal(ts.displayPartsToString(details.documentation), documentation, this.assertionMessageAtLastKnownMarker("completion item documentation for " + entryId));
|
||||
}
|
||||
if (text !== undefined) {
|
||||
assert.equal(ts.displayPartsToString(details.displayParts), text, this.assertionMessageAtLastKnownMarker("completion item detail text for " + name));
|
||||
assert.equal(ts.displayPartsToString(details.displayParts), text, this.assertionMessageAtLastKnownMarker("completion item detail text for " + entryId));
|
||||
}
|
||||
|
||||
assert.deepEqual(details.source, entryId.source === undefined ? undefined : [ts.textPart(entryId.source)]);
|
||||
}
|
||||
|
||||
if (kind !== undefined) {
|
||||
assert.equal(item.kind, kind, this.assertionMessageAtLastKnownMarker("completion item kind for " + name));
|
||||
assert.equal(item.kind, kind, this.assertionMessageAtLastKnownMarker("completion item kind for " + entryId));
|
||||
}
|
||||
|
||||
if (spanIndex !== undefined) {
|
||||
const span = this.getTextSpanForRangeAtIndex(spanIndex);
|
||||
assert.isTrue(TestState.textSpansEqual(span, item.replacementSpan), this.assertionMessageAtLastKnownMarker(stringify(span) + " does not equal " + stringify(item.replacementSpan) + " replacement span for " + name));
|
||||
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);
|
||||
@@ -3037,7 +3108,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
|
||||
const itemsString = items.map(item => stringify({ name: item.name, kind: item.kind })).join(",\n");
|
||||
|
||||
this.raiseError(`Expected "${stringify({ name, text, documentation, kind })}" to be in list [${itemsString}]`);
|
||||
this.raiseError(`Expected "${stringify({ entryId, text, documentation, kind })}" to be in list [${itemsString}]`);
|
||||
}
|
||||
|
||||
private findFile(indexOrName: any) {
|
||||
@@ -3748,12 +3819,15 @@ namespace FourSlashInterface {
|
||||
|
||||
// Verifies the completion list contains the specified symbol. The
|
||||
// completion list is brought up if necessary
|
||||
public completionListContains(symbol: string, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean) {
|
||||
public completionListContains(entryId: string | ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean, options?: ts.GetCompletionsAtPositionOptions) {
|
||||
if (typeof entryId === "string") {
|
||||
entryId = { name: entryId, source: undefined };
|
||||
}
|
||||
if (this.negative) {
|
||||
this.state.verifyCompletionListDoesNotContain(symbol, text, documentation, kind, spanIndex);
|
||||
this.state.verifyCompletionListDoesNotContain(entryId, text, documentation, kind, spanIndex, options);
|
||||
}
|
||||
else {
|
||||
this.state.verifyCompletionListContains(symbol, text, documentation, kind, spanIndex, hasAction);
|
||||
this.state.verifyCompletionListContains(entryId, text, documentation, kind, spanIndex, hasAction, options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3911,6 +3985,7 @@ namespace FourSlashInterface {
|
||||
}
|
||||
|
||||
public goToDefinition(startMarkerName: string | string[], endMarkerName: string | string[]): void;
|
||||
public goToDefinition(startMarkerName: string | string[], endMarkerName: string | string[], range: FourSlash.Range): void;
|
||||
public goToDefinition(startsAndEnds: [string | string[], string | string[]][]): void;
|
||||
public goToDefinition(startsAndEnds: { [startMarkerName: string]: string | string[] }): void;
|
||||
public goToDefinition(arg0: any, endMarkerName?: string | string[]) {
|
||||
@@ -4508,6 +4583,7 @@ namespace FourSlashInterface {
|
||||
|
||||
export interface VerifyCompletionActionOptions extends NewContentOptions {
|
||||
name: string;
|
||||
source?: string;
|
||||
description: string;
|
||||
}
|
||||
}
|
||||
|
||||
+24
-16
@@ -32,6 +32,9 @@
|
||||
// this will work in the browser via browserify
|
||||
var _chai: typeof chai = require("chai");
|
||||
var assert: typeof _chai.assert = _chai.assert;
|
||||
// chai's builtin `assert.isFalse` is featureful but slow - we don't use those features,
|
||||
// so we'll just overwrite it as an alterative to migrating a bunch of code off of chai
|
||||
assert.isFalse = (expr, msg) => { if (expr as any as boolean !== false) throw new Error(msg); };
|
||||
declare var __dirname: string; // Node-specific
|
||||
var global: NodeJS.Global = <any>Function("return this").call(undefined);
|
||||
|
||||
@@ -476,7 +479,7 @@ namespace Utils {
|
||||
}
|
||||
|
||||
namespace Harness {
|
||||
export interface IO {
|
||||
export interface Io {
|
||||
newLine(): string;
|
||||
getCurrentDirectory(): string;
|
||||
useCaseSensitiveFileNames(): boolean;
|
||||
@@ -499,7 +502,7 @@ namespace Harness {
|
||||
tryEnableSourceMapsForHost?(): void;
|
||||
getEnvironmentVariable?(name: string): string;
|
||||
}
|
||||
export let IO: IO;
|
||||
export let IO: Io;
|
||||
|
||||
// harness always uses one kind of new line
|
||||
// But note that `parseTestData` in `fourslash.ts` uses "\n"
|
||||
@@ -572,14 +575,13 @@ namespace Harness {
|
||||
function filesInFolder(folder: string): string[] {
|
||||
let paths: string[] = [];
|
||||
|
||||
const files = fs.readdirSync(folder);
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const pathToFile = pathModule.join(folder, files[i]);
|
||||
for (const file of fs.readdirSync(folder)) {
|
||||
const pathToFile = pathModule.join(folder, file);
|
||||
const stat = fs.statSync(pathToFile);
|
||||
if (options.recursive && stat.isDirectory()) {
|
||||
paths = paths.concat(filesInFolder(pathToFile));
|
||||
}
|
||||
else if (stat.isFile() && (!spec || files[i].match(spec))) {
|
||||
else if (stat.isFile() && (!spec || file.match(spec))) {
|
||||
paths.push(pathToFile);
|
||||
}
|
||||
}
|
||||
@@ -781,9 +783,15 @@ namespace Harness {
|
||||
? IO.newLine() + `//# sourceURL=${IO.resolvePath(tcServicesFileName)}`
|
||||
: "");
|
||||
|
||||
export interface SourceMapEmitterCallback {
|
||||
(emittedFile: string, emittedLine: number, emittedColumn: number, sourceFile: string, sourceLine: number, sourceColumn: number, sourceName: string): void;
|
||||
}
|
||||
export type SourceMapEmitterCallback = (
|
||||
emittedFile: string,
|
||||
emittedLine: number,
|
||||
emittedColumn: number,
|
||||
sourceFile: string,
|
||||
sourceLine: number,
|
||||
sourceColumn: number,
|
||||
sourceName: string,
|
||||
) => void;
|
||||
|
||||
// Settings
|
||||
export let userSpecifiedRoot = "";
|
||||
@@ -1196,6 +1204,9 @@ namespace Harness {
|
||||
traceResults = [];
|
||||
compilerHost.trace = text => traceResults.push(text);
|
||||
}
|
||||
else {
|
||||
compilerHost.directoryExists = () => true; // This only visibly affects resolution traces, so to save time we always return true where possible
|
||||
}
|
||||
const program = ts.createProgram(programFileNames, options, compilerHost);
|
||||
|
||||
const emitResult = program.emit();
|
||||
@@ -1569,10 +1580,8 @@ namespace Harness {
|
||||
|
||||
// Preserve legacy behavior
|
||||
if (lastIndexWritten === undefined) {
|
||||
for (let i = 0; i < codeLines.length; i++) {
|
||||
const currentCodeLine = codeLines[i];
|
||||
typeLines += currentCodeLine + "\r\n";
|
||||
typeLines += "No type information for this code.";
|
||||
for (const codeLine of codeLines) {
|
||||
typeLines += codeLine + "\r\nNo type information for this code.";
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1858,8 +1867,7 @@ namespace Harness {
|
||||
let currentFileName: any = undefined;
|
||||
let refs: string[] = [];
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
for (const line of lines) {
|
||||
const testMetaData = optionRegex.exec(line);
|
||||
if (testMetaData) {
|
||||
// Comment line, check for global/file @options and record them
|
||||
@@ -2139,7 +2147,7 @@ namespace Harness {
|
||||
return filePath.indexOf(Harness.libFolder) === 0;
|
||||
}
|
||||
|
||||
export function getDefaultLibraryFile(io: Harness.IO): Harness.Compiler.TestFile {
|
||||
export function getDefaultLibraryFile(io: Harness.Io): Harness.Compiler.TestFile {
|
||||
const libFile = Harness.userSpecifiedRoot + Harness.libFolder + Harness.Compiler.defaultLibFileName;
|
||||
return { unitName: libFile, content: io.readFile(libFile) };
|
||||
}
|
||||
|
||||
@@ -413,11 +413,11 @@ namespace Harness.LanguageService {
|
||||
getEncodedSemanticClassifications(fileName: string, span: ts.TextSpan): ts.Classifications {
|
||||
return unwrapJSONCallResult(this.shim.getEncodedSemanticClassifications(fileName, span.start, span.length));
|
||||
}
|
||||
getCompletionsAtPosition(fileName: string, position: number): ts.CompletionInfo {
|
||||
return unwrapJSONCallResult(this.shim.getCompletionsAtPosition(fileName, position));
|
||||
getCompletionsAtPosition(fileName: string, position: number, options: ts.GetCompletionsAtPositionOptions | undefined): ts.CompletionInfo {
|
||||
return unwrapJSONCallResult(this.shim.getCompletionsAtPosition(fileName, position, options));
|
||||
}
|
||||
getCompletionEntryDetails(fileName: string, position: number, entryName: string, options: ts.FormatCodeOptions): ts.CompletionEntryDetails {
|
||||
return unwrapJSONCallResult(this.shim.getCompletionEntryDetails(fileName, position, entryName, JSON.stringify(options)));
|
||||
getCompletionEntryDetails(fileName: string, position: number, entryName: string, options: ts.FormatCodeOptions | undefined, source: string | undefined): ts.CompletionEntryDetails {
|
||||
return unwrapJSONCallResult(this.shim.getCompletionEntryDetails(fileName, position, entryName, JSON.stringify(options), source));
|
||||
}
|
||||
getCompletionEntrySymbol(): ts.Symbol {
|
||||
throw new Error("getCompletionEntrySymbol not implemented across the shim layer.");
|
||||
@@ -443,6 +443,9 @@ namespace Harness.LanguageService {
|
||||
getDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] {
|
||||
return unwrapJSONCallResult(this.shim.getDefinitionAtPosition(fileName, position));
|
||||
}
|
||||
getDefinitionAndBoundSpan(fileName: string, position: number): ts.DefinitionInfoAndBoundSpan {
|
||||
return unwrapJSONCallResult(this.shim.getDefinitionAndBoundSpan(fileName, position));
|
||||
}
|
||||
getTypeDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] {
|
||||
return unwrapJSONCallResult(this.shim.getTypeDefinitionAtPosition(fileName, position));
|
||||
}
|
||||
@@ -541,9 +544,9 @@ namespace Harness.LanguageService {
|
||||
getClassifier(): ts.Classifier { return new ClassifierShimProxy(this.factory.createClassifierShim(this.host)); }
|
||||
getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo {
|
||||
let shimResult: {
|
||||
referencedFiles: ts.IFileReference[];
|
||||
typeReferenceDirectives: ts.IFileReference[];
|
||||
importedFiles: ts.IFileReference[];
|
||||
referencedFiles: ts.ShimsFileReference[];
|
||||
typeReferenceDirectives: ts.ShimsFileReference[];
|
||||
importedFiles: ts.ShimsFileReference[];
|
||||
isLibFile: boolean;
|
||||
};
|
||||
|
||||
@@ -754,6 +757,7 @@ namespace Harness.LanguageService {
|
||||
create(info: ts.server.PluginCreateInfo) {
|
||||
const proxy = makeDefaultProxy(info);
|
||||
const langSvc: any = info.languageService;
|
||||
// tslint:disable-next-line only-arrow-functions
|
||||
proxy.getQuickInfoAtPosition = function () {
|
||||
const parts = langSvc.getQuickInfoAtPosition.apply(langSvc, arguments);
|
||||
if (parts.displayParts.length > 0) {
|
||||
@@ -786,7 +790,7 @@ namespace Harness.LanguageService {
|
||||
module: () => ({
|
||||
create(info: ts.server.PluginCreateInfo) {
|
||||
const proxy = makeDefaultProxy(info);
|
||||
proxy.getSemanticDiagnostics = function (filename: string) {
|
||||
proxy.getSemanticDiagnostics = filename => {
|
||||
const prev = info.languageService.getSemanticDiagnostics(filename);
|
||||
const sourceFile: ts.SourceFile = info.languageService.getSourceFile(filename);
|
||||
prev.push({
|
||||
@@ -812,11 +816,12 @@ namespace Harness.LanguageService {
|
||||
};
|
||||
}
|
||||
|
||||
function makeDefaultProxy(info: ts.server.PluginCreateInfo) {
|
||||
function makeDefaultProxy(info: ts.server.PluginCreateInfo): ts.LanguageService {
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
const proxy = Object.create(/*prototype*/ null);
|
||||
const langSvc: any = info.languageService;
|
||||
for (const k of Object.keys(langSvc)) {
|
||||
// tslint:disable-next-line only-arrow-functions
|
||||
proxy[k] = function () {
|
||||
return langSvc[k].apply(langSvc, arguments);
|
||||
};
|
||||
|
||||
+49
-24
@@ -14,19 +14,19 @@ interface FileInformation {
|
||||
interface FindFileResult {
|
||||
}
|
||||
|
||||
interface IOLogFile {
|
||||
interface IoLogFile {
|
||||
path: string;
|
||||
codepage: number;
|
||||
result?: FileInformation;
|
||||
}
|
||||
|
||||
interface IOLog {
|
||||
interface IoLog {
|
||||
timestamp: string;
|
||||
arguments: string[];
|
||||
executingPath: string;
|
||||
currentDirectory: string;
|
||||
useCustomLibraryFile?: boolean;
|
||||
filesRead: IOLogFile[];
|
||||
filesRead: IoLogFile[];
|
||||
filesWritten: {
|
||||
path: string;
|
||||
contents?: string;
|
||||
@@ -80,15 +80,16 @@ interface IOLog {
|
||||
interface PlaybackControl {
|
||||
startReplayFromFile(logFileName: string): void;
|
||||
startReplayFromString(logContents: string): void;
|
||||
startReplayFromData(log: IOLog): void;
|
||||
startReplayFromData(log: IoLog): void;
|
||||
endReplay(): void;
|
||||
startRecord(logFileName: string): void;
|
||||
endRecord(): void;
|
||||
}
|
||||
|
||||
namespace Playback {
|
||||
let recordLog: IOLog = undefined;
|
||||
let replayLog: IOLog = undefined;
|
||||
let recordLog: IoLog = undefined;
|
||||
let replayLog: IoLog = undefined;
|
||||
let replayFilesRead: ts.Map<IoLogFile> | undefined = undefined;
|
||||
let recordLogFileNameBase = "";
|
||||
|
||||
interface Memoized<T> {
|
||||
@@ -109,11 +110,11 @@ namespace Playback {
|
||||
return run;
|
||||
}
|
||||
|
||||
export interface PlaybackIO extends Harness.IO, PlaybackControl { }
|
||||
export interface PlaybackIO extends Harness.Io, PlaybackControl { }
|
||||
|
||||
export interface PlaybackSystem extends ts.System, PlaybackControl { }
|
||||
|
||||
function createEmptyLog(): IOLog {
|
||||
function createEmptyLog(): IoLog {
|
||||
return {
|
||||
timestamp: (new Date()).toString(),
|
||||
arguments: [],
|
||||
@@ -133,7 +134,7 @@ namespace Playback {
|
||||
};
|
||||
}
|
||||
|
||||
export function newStyleLogIntoOldStyleLog(log: IOLog, host: ts.System | Harness.IO, baseName: string) {
|
||||
export function newStyleLogIntoOldStyleLog(log: IoLog, host: ts.System | Harness.Io, baseName: string) {
|
||||
for (const file of log.filesAppended) {
|
||||
if (file.contentsPath) {
|
||||
file.contents = host.readFile(ts.combinePaths(baseName, file.contentsPath));
|
||||
@@ -166,7 +167,7 @@ namespace Playback {
|
||||
return path;
|
||||
}
|
||||
|
||||
export function oldStyleLogIntoNewStyleLog(log: IOLog, writeFile: typeof Harness.IO.writeFile, baseTestName: string) {
|
||||
export function oldStyleLogIntoNewStyleLog(log: IoLog, writeFile: typeof Harness.IO.writeFile, baseTestName: string) {
|
||||
if (log.filesAppended) {
|
||||
for (const file of log.filesAppended) {
|
||||
if (file.contents !== undefined) {
|
||||
@@ -209,8 +210,8 @@ namespace Playback {
|
||||
}
|
||||
|
||||
function initWrapper(wrapper: PlaybackSystem, underlying: ts.System): void;
|
||||
function initWrapper(wrapper: PlaybackIO, underlying: Harness.IO): void;
|
||||
function initWrapper(wrapper: PlaybackSystem | PlaybackIO, underlying: ts.System | Harness.IO): void {
|
||||
function initWrapper(wrapper: PlaybackIO, underlying: Harness.Io): void;
|
||||
function initWrapper(wrapper: PlaybackSystem | PlaybackIO, underlying: ts.System | Harness.Io): void {
|
||||
ts.forEach(Object.keys(underlying), prop => {
|
||||
(<any>wrapper)[prop] = (<any>underlying)[prop];
|
||||
});
|
||||
@@ -222,10 +223,15 @@ namespace Playback {
|
||||
replayLog = log;
|
||||
// Remove non-found files from the log (shouldn't really need them, but we still record them for diagnostic purposes)
|
||||
replayLog.filesRead = replayLog.filesRead.filter(f => f.result.contents !== undefined);
|
||||
replayFilesRead = ts.createMap();
|
||||
for (const file of replayLog.filesRead) {
|
||||
replayFilesRead.set(ts.normalizeSlashes(file.path).toLowerCase(), file);
|
||||
}
|
||||
};
|
||||
|
||||
wrapper.endReplay = () => {
|
||||
replayLog = undefined;
|
||||
replayFilesRead = undefined;
|
||||
};
|
||||
|
||||
wrapper.startRecord = (fileNameBase) => {
|
||||
@@ -243,18 +249,38 @@ namespace Playback {
|
||||
wrapper.endRecord = () => {
|
||||
if (recordLog !== undefined) {
|
||||
let i = 0;
|
||||
const fn = () => recordLogFileNameBase + i;
|
||||
while (underlying.fileExists(ts.combinePaths(fn(), "test.json"))) i++;
|
||||
underlying.writeFile(ts.combinePaths(fn(), "test.json"), JSON.stringify(oldStyleLogIntoNewStyleLog(recordLog, (path, string) => underlying.writeFile(path, string), fn()), null, 4)); // tslint:disable-line:no-null-keyword
|
||||
const getBase = () => recordLogFileNameBase + i;
|
||||
while (underlying.fileExists(ts.combinePaths(getBase(), "test.json"))) i++;
|
||||
const newLog = oldStyleLogIntoNewStyleLog(recordLog, (path, string) => underlying.writeFile(path, string), getBase());
|
||||
underlying.writeFile(ts.combinePaths(getBase(), "test.json"), JSON.stringify(newLog, null, 4)); // tslint:disable-line:no-null-keyword
|
||||
const syntheticTsconfig = generateTsconfig(newLog);
|
||||
if (syntheticTsconfig) {
|
||||
underlying.writeFile(ts.combinePaths(getBase(), "tsconfig.json"), JSON.stringify(syntheticTsconfig, null, 4)); // tslint:disable-line:no-null-keyword
|
||||
}
|
||||
recordLog = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
function generateTsconfig(newLog: IoLog): undefined | { compilerOptions: ts.CompilerOptions, files: string[] } {
|
||||
if (newLog.filesRead.some(file => /tsconfig.+json$/.test(file.path))) {
|
||||
return;
|
||||
}
|
||||
const files = [];
|
||||
for (const file of newLog.filesRead) {
|
||||
if (file.result.contentsPath &&
|
||||
Harness.isDefaultLibraryFile(file.result.contentsPath) &&
|
||||
/\.[tj]s$/.test(file.result.contentsPath)) {
|
||||
files.push(file.result.contentsPath);
|
||||
}
|
||||
}
|
||||
return { compilerOptions: ts.parseCommandLine(newLog.arguments).options, files };
|
||||
}
|
||||
|
||||
wrapper.fileExists = recordReplay(wrapper.fileExists, underlying)(
|
||||
path => callAndRecord(underlying.fileExists(path), recordLog.fileExists, { path }),
|
||||
memoize(path => {
|
||||
// If we read from the file, it must exist
|
||||
if (findFileByPath(replayLog.filesRead, path, /*throwFileNotFoundError*/ false)) {
|
||||
if (findFileByPath(path, /*throwFileNotFoundError*/ false)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@@ -298,7 +324,7 @@ namespace Playback {
|
||||
recordLog.filesRead.push(logEntry);
|
||||
return result;
|
||||
},
|
||||
memoize(path => findFileByPath(replayLog.filesRead, path, /*throwFileNotFoundError*/ true).contents));
|
||||
memoize(path => findFileByPath(path, /*throwFileNotFoundError*/ true).contents));
|
||||
|
||||
wrapper.readDirectory = recordReplay(wrapper.readDirectory, underlying)(
|
||||
(path, extensions, exclude, include, depth) => {
|
||||
@@ -340,6 +366,7 @@ namespace Playback {
|
||||
|
||||
function recordReplay<T extends Function>(original: T, underlying: any) {
|
||||
function createWrapper(record: T, replay: T): T {
|
||||
// tslint:disable-next-line only-arrow-functions
|
||||
return <any>(function () {
|
||||
if (replayLog !== undefined) {
|
||||
return replay.apply(undefined, arguments);
|
||||
@@ -379,14 +406,12 @@ namespace Playback {
|
||||
return results[0].result;
|
||||
}
|
||||
|
||||
function findFileByPath(logArray: IOLogFile[],
|
||||
expectedPath: string, throwFileNotFoundError: boolean): FileInformation {
|
||||
function findFileByPath(expectedPath: string, throwFileNotFoundError: boolean): FileInformation {
|
||||
const normalizedName = ts.normalizePath(expectedPath).toLowerCase();
|
||||
// Try to find the result through normal fileName
|
||||
for (const log of logArray) {
|
||||
if (ts.normalizeSlashes(log.path).toLowerCase() === normalizedName) {
|
||||
return log.result;
|
||||
}
|
||||
const result = replayFilesRead.get(normalizedName);
|
||||
if (result) {
|
||||
return result.result;
|
||||
}
|
||||
|
||||
// If we got here, we didn't find a match
|
||||
@@ -402,7 +427,7 @@ namespace Playback {
|
||||
// console.log("Swallowed write operation during replay: " + name);
|
||||
}
|
||||
|
||||
export function wrapIO(underlying: Harness.IO): PlaybackIO {
|
||||
export function wrapIO(underlying: Harness.Io): PlaybackIO {
|
||||
const wrapper: PlaybackIO = <any>{};
|
||||
initWrapper(wrapper, underlying);
|
||||
|
||||
|
||||
@@ -314,8 +314,7 @@ namespace Harness.Parallel.Host {
|
||||
stats.failures = errorResults.length;
|
||||
stats.tests = totalPassing + errorResults.length;
|
||||
stats.duration = duration;
|
||||
for (let j = 0; j < errorResults.length; j++) {
|
||||
const failure = errorResults[j];
|
||||
for (const failure of errorResults) {
|
||||
failures.push(makeMochaTest(failure));
|
||||
}
|
||||
if (noColors) {
|
||||
|
||||
@@ -140,12 +140,12 @@ class ProjectRunner extends RunnerBase {
|
||||
|
||||
// Clean up source map data that will be used in baselining
|
||||
if (sourceMapData) {
|
||||
for (let i = 0; i < sourceMapData.length; i++) {
|
||||
for (let j = 0; j < sourceMapData[i].sourceMapSources.length; j++) {
|
||||
sourceMapData[i].sourceMapSources[j] = cleanProjectUrl(sourceMapData[i].sourceMapSources[j]);
|
||||
for (const data of sourceMapData) {
|
||||
for (let j = 0; j < data.sourceMapSources.length; j++) {
|
||||
data.sourceMapSources[j] = cleanProjectUrl(data.sourceMapSources[j]);
|
||||
}
|
||||
sourceMapData[i].jsSourceMappingURL = cleanProjectUrl(sourceMapData[i].jsSourceMappingURL);
|
||||
sourceMapData[i].sourceMapSourceRoot = cleanProjectUrl(sourceMapData[i].sourceMapSourceRoot);
|
||||
data.jsSourceMappingURL = cleanProjectUrl(data.jsSourceMappingURL);
|
||||
data.sourceMapSourceRoot = cleanProjectUrl(data.sourceMapSourceRoot);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-3
@@ -18,6 +18,7 @@
|
||||
/// <reference path="fourslashRunner.ts" />
|
||||
/// <reference path="projectsRunner.ts" />
|
||||
/// <reference path="rwcRunner.ts" />
|
||||
/// <reference path="userRunner.ts" />
|
||||
/// <reference path="harness.ts" />
|
||||
/// <reference path="./parallel/shared.ts" />
|
||||
|
||||
@@ -26,8 +27,8 @@ let iterations = 1;
|
||||
|
||||
function runTests(runners: RunnerBase[]) {
|
||||
for (let i = iterations; i > 0; i--) {
|
||||
for (let j = 0; j < runners.length; j++) {
|
||||
runners[j].initializeTests();
|
||||
for (const runner of runners) {
|
||||
runner.initializeTests();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,6 +60,8 @@ function createRunner(kind: TestRunnerKind): RunnerBase {
|
||||
return new RWCRunner();
|
||||
case "test262":
|
||||
return new Test262BaselineRunner();
|
||||
case "user":
|
||||
return new UserCodeRunner();
|
||||
}
|
||||
ts.Debug.fail(`Unknown runner kind ${kind}`);
|
||||
}
|
||||
@@ -175,6 +178,9 @@ function handleTestConfig() {
|
||||
case "test262":
|
||||
runners.push(new Test262BaselineRunner());
|
||||
break;
|
||||
case "user":
|
||||
runners.push(new UserCodeRunner());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,6 +202,11 @@ function handleTestConfig() {
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.ShimsWithPreprocess));
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Server));
|
||||
// runners.push(new GeneratedFourslashRunner());
|
||||
|
||||
// CRON-only tests
|
||||
if (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser && process.env.TRAVIS_EVENT_TYPE === "cron") {
|
||||
runners.push(new UserCodeRunner());
|
||||
}
|
||||
}
|
||||
if (runUnitTests === undefined) {
|
||||
runUnitTests = runners.length !== 1; // Don't run unit tests when running only one runner if unit tests were not explicitly asked for
|
||||
@@ -223,8 +234,9 @@ function beginTests() {
|
||||
}
|
||||
}
|
||||
|
||||
let isWorker: boolean;
|
||||
function startTestEnvironment() {
|
||||
const isWorker = handleTestConfig();
|
||||
isWorker = handleTestConfig();
|
||||
if (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser) {
|
||||
if (isWorker) {
|
||||
return Harness.Parallel.Worker.start();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// <reference path="harness.ts" />
|
||||
|
||||
|
||||
type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262";
|
||||
type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262" | "user";
|
||||
type CompilerTestKind = "conformance" | "compiler";
|
||||
type FourslashTestKind = "fourslash" | "fourslash-shims" | "fourslash-shims-pp" | "fourslash-server";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* tslint:disable:no-null-keyword */
|
||||
|
||||
namespace RWC {
|
||||
function runWithIOLog(ioLog: IOLog, fn: (oldIO: Harness.IO) => void) {
|
||||
function runWithIOLog(ioLog: IoLog, fn: (oldIO: Harness.Io) => void) {
|
||||
const oldIO = Harness.IO;
|
||||
|
||||
const wrappedIO = Playback.wrapIO(oldIO);
|
||||
@@ -39,8 +39,6 @@ namespace RWC {
|
||||
const baseName = ts.getBaseFileName(jsonPath);
|
||||
let currentDirectory: string;
|
||||
let useCustomLibraryFile: boolean;
|
||||
let skipTypeBaselines = false;
|
||||
const typeSizeLimit = 10000000;
|
||||
after(() => {
|
||||
// Mocha holds onto the closure environment of the describe callback even after the test is done.
|
||||
// Therefore we have to clean out large objects after the test is done.
|
||||
@@ -54,17 +52,15 @@ namespace RWC {
|
||||
// or to use lib.d.ts inside the json object. If the flag is true, use the lib.d.ts inside json file
|
||||
// otherwise use the lib.d.ts from built/local
|
||||
useCustomLibraryFile = undefined;
|
||||
skipTypeBaselines = false;
|
||||
});
|
||||
|
||||
it("can compile", function(this: Mocha.ITestCallbackContext) {
|
||||
this.timeout(800000); // Allow long timeouts for RWC compilations
|
||||
let opts: ts.ParsedCommandLine;
|
||||
|
||||
const ioLog: IOLog = Playback.newStyleLogIntoOldStyleLog(JSON.parse(Harness.IO.readFile(`internal/cases/rwc/${jsonPath}/test.json`)), Harness.IO, `internal/cases/rwc/${baseName}`);
|
||||
const ioLog: IoLog = Playback.newStyleLogIntoOldStyleLog(JSON.parse(Harness.IO.readFile(`internal/cases/rwc/${jsonPath}/test.json`)), Harness.IO, `internal/cases/rwc/${baseName}`);
|
||||
currentDirectory = ioLog.currentDirectory;
|
||||
useCustomLibraryFile = ioLog.useCustomLibraryFile;
|
||||
skipTypeBaselines = ioLog.filesRead.reduce((acc, elem) => (elem && elem.result && elem.result.contents) ? acc + elem.result.contents.length : acc, 0) > typeSizeLimit;
|
||||
runWithIOLog(ioLog, () => {
|
||||
opts = ts.parseCommandLine(ioLog.arguments, fileName => Harness.IO.readFile(fileName));
|
||||
assert.equal(opts.errors.length, 0);
|
||||
@@ -199,14 +195,6 @@ namespace RWC {
|
||||
}, baselineOpts, [".map"]);
|
||||
});
|
||||
|
||||
/*it("has correct source map record", () => {
|
||||
if (compilerOptions.sourceMap) {
|
||||
Harness.Baseline.runBaseline(baseName + ".sourcemap.txt", () => {
|
||||
return compilerResult.getSourceMapRecord();
|
||||
}, baselineOpts);
|
||||
}
|
||||
});*/
|
||||
|
||||
it("has the expected errors", () => {
|
||||
Harness.Baseline.runMultifileBaseline(baseName, ".errors.txt", () => {
|
||||
if (compilerResult.errors.length === 0) {
|
||||
@@ -219,14 +207,6 @@ namespace RWC {
|
||||
}, baselineOpts);
|
||||
});
|
||||
|
||||
it("has the expected types", () => {
|
||||
// We don't need to pass the extension here because "doTypeAndSymbolBaseline" will append appropriate extension of ".types" or ".symbols"
|
||||
Harness.Compiler.doTypeAndSymbolBaseline(baseName, compilerResult.program, inputFiles
|
||||
.concat(otherFiles)
|
||||
.filter(file => !!compilerResult.program.getSourceFile(file.unitName))
|
||||
.filter(e => !Harness.isDefaultLibraryFile(e.unitName)), baselineOpts, /*multifile*/ true, skipTypeBaselines, /*skipSymbolbaselines*/ true);
|
||||
});
|
||||
|
||||
// Ideally, a generated declaration file will have no errors. But we allow generated
|
||||
// declaration file errors as part of the baseline.
|
||||
it("has the expected errors in generated declaration files", () => {
|
||||
@@ -265,10 +245,8 @@ class RWCRunner extends RunnerBase {
|
||||
*/
|
||||
public initializeTests(): void {
|
||||
// Read in and evaluate the test list
|
||||
const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles();
|
||||
|
||||
for (let i = 0; i < testList.length; i++) {
|
||||
this.runTest(testList[i]);
|
||||
for (const test of this.tests && this.tests.length ? this.tests : this.enumerateTestFiles()) {
|
||||
this.runTest(test);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -386,9 +386,9 @@ namespace Harness.SourceMapRecorder {
|
||||
|
||||
if (currentSpan.decodeErrors) {
|
||||
// If there are decode errors, write
|
||||
for (let i = 0; i < currentSpan.decodeErrors.length; i++) {
|
||||
for (const decodeError of currentSpan.decodeErrors) {
|
||||
writeSourceMapIndent(prevEmittedCol, markerIds[index]);
|
||||
sourceMapRecorder.WriteLine(currentSpan.decodeErrors[i]);
|
||||
sourceMapRecorder.WriteLine(decodeError);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,8 +442,7 @@ namespace Harness.SourceMapRecorder {
|
||||
let prevSourceFile: ts.SourceFile;
|
||||
|
||||
SourceMapSpanWriter.initializeSourceMapSpanWriter(sourceMapRecorder, sourceMapData, jsFiles[i]);
|
||||
for (let j = 0; j < sourceMapData.sourceMapDecodedMappings.length; j++) {
|
||||
const decodedSourceMapping = sourceMapData.sourceMapDecodedMappings[j];
|
||||
for (const decodedSourceMapping of sourceMapData.sourceMapDecodedMappings) {
|
||||
const currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex]);
|
||||
if (currentSourceFile !== prevSourceFile) {
|
||||
SourceMapSpanWriter.recordNewSourceFileSpan(decodedSourceMapping, currentSourceFile.text);
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
"projectsRunner.ts",
|
||||
"loggedIO.ts",
|
||||
"rwcRunner.ts",
|
||||
"userRunner.ts",
|
||||
"test262Runner.ts",
|
||||
"./parallel/shared.ts",
|
||||
"./parallel/host.ts",
|
||||
|
||||
@@ -52,7 +52,7 @@ class TypeWriterWalker {
|
||||
}
|
||||
|
||||
private *visitNode(node: ts.Node, isSymbolWalk: boolean): IterableIterator<TypeWriterResult> {
|
||||
if (ts.isPartOfExpression(node) || node.kind === ts.SyntaxKind.Identifier) {
|
||||
if (ts.isExpressionNode(node) || node.kind === ts.SyntaxKind.Identifier) {
|
||||
const result = this.writeTypeOrSymbol(node, isSymbolWalk);
|
||||
if (result) {
|
||||
yield result;
|
||||
|
||||
@@ -421,6 +421,24 @@ namespace ts {
|
||||
);
|
||||
});
|
||||
|
||||
it("Convert negative numbers in tsconfig.json ", () => {
|
||||
assertCompilerOptions(
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"maxNodeModuleJsDepth": -1
|
||||
}
|
||||
}, "tsconfig.json",
|
||||
{
|
||||
compilerOptions: {
|
||||
allowJs: true,
|
||||
maxNodeModuleJsDepth: -1
|
||||
},
|
||||
errors: []
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// jsconfig.json
|
||||
it("Convert correctly format jsconfig.json to compiler-options ", () => {
|
||||
assertCompilerOptions(
|
||||
|
||||
@@ -362,27 +362,32 @@ function parsePrimaryExpression(): any {
|
||||
}`);
|
||||
|
||||
testExtractFunction("extractFunction_VariableDeclaration_Var", `
|
||||
[#|var x = 1;|]
|
||||
[#|var x = 1;
|
||||
"hello"|]
|
||||
x;
|
||||
`);
|
||||
|
||||
testExtractFunction("extractFunction_VariableDeclaration_Let_Type", `
|
||||
[#|let x: number = 1;|]
|
||||
[#|let x: number = 1;
|
||||
"hello";|]
|
||||
x;
|
||||
`);
|
||||
|
||||
testExtractFunction("extractFunction_VariableDeclaration_Let_NoType", `
|
||||
[#|let x = 1;|]
|
||||
[#|let x = 1;
|
||||
"hello";|]
|
||||
x;
|
||||
`);
|
||||
|
||||
testExtractFunction("extractFunction_VariableDeclaration_Const_Type", `
|
||||
[#|const x: number = 1;|]
|
||||
[#|const x: number = 1;
|
||||
"hello";|]
|
||||
x;
|
||||
`);
|
||||
|
||||
testExtractFunction("extractFunction_VariableDeclaration_Const_NoType", `
|
||||
[#|const x = 1;|]
|
||||
[#|const x = 1;
|
||||
"hello";|]
|
||||
x;
|
||||
`);
|
||||
|
||||
@@ -404,7 +409,8 @@ x; y; z;
|
||||
`);
|
||||
|
||||
testExtractFunction("extractFunction_VariableDeclaration_ConsumedTwice", `
|
||||
[#|const x: number = 1;|]
|
||||
[#|const x: number = 1;
|
||||
"hello";|]
|
||||
x; x;
|
||||
`);
|
||||
|
||||
|
||||
@@ -162,6 +162,19 @@ namespace ts {
|
||||
}|]|]
|
||||
}
|
||||
`);
|
||||
|
||||
// Variable statements
|
||||
testExtractRange(`[#|let x = [$|1|];|]`);
|
||||
testExtractRange(`[#|let x = [$|1|], y;|]`);
|
||||
testExtractRange(`[#|[$|let x = 1, y = 1;|]|]`);
|
||||
|
||||
// Variable declarations
|
||||
testExtractRange(`let [#|x = [$|1|]|];`);
|
||||
testExtractRange(`let [#|x = [$|1|]|], y = 2;`);
|
||||
testExtractRange(`let x = 1, [#|y = [$|2|]|];`);
|
||||
|
||||
// Return statements
|
||||
testExtractRange(`[#|return [$|1|];|]`);
|
||||
});
|
||||
|
||||
testExtractRangeFailed("extractRangeFailed1",
|
||||
@@ -340,6 +353,18 @@ switch (x) {
|
||||
refactor.extractSymbol.Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements.message
|
||||
]);
|
||||
|
||||
testExtractRangeFailed("extractRangeFailed12",
|
||||
`let [#|x|];`,
|
||||
[
|
||||
refactor.extractSymbol.Messages.StatementOrExpressionExpected.message
|
||||
]);
|
||||
|
||||
testExtractRangeFailed("extractRangeFailed13",
|
||||
`[#|return;|]`,
|
||||
[
|
||||
refactor.extractSymbol.Messages.CannotExtractRange.message
|
||||
]);
|
||||
|
||||
testExtractRangeFailed("extract-method-not-for-token-expression-statement", `[#|a|]`, [refactor.extractSymbol.Messages.CannotExtractIdentifier.message]);
|
||||
});
|
||||
}
|
||||
@@ -67,7 +67,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
export const newLineCharacter = "\n";
|
||||
export function getRuleProvider(action?: (opts: FormatCodeSettings) => void) {
|
||||
export const getRuleProvider = memoize(getRuleProviderInternal);
|
||||
function getRuleProviderInternal() {
|
||||
const options = {
|
||||
indentSize: 4,
|
||||
tabSize: 4,
|
||||
@@ -89,9 +90,6 @@ namespace ts {
|
||||
placeOpenBraceOnNewLineForFunctions: false,
|
||||
placeOpenBraceOnNewLineForControlBlocks: false,
|
||||
};
|
||||
if (action) {
|
||||
action(options);
|
||||
}
|
||||
const rulesProvider = new formatting.RulesProvider();
|
||||
rulesProvider.ensureUpToDate(options);
|
||||
return rulesProvider;
|
||||
|
||||
@@ -591,7 +591,7 @@ module m3 { }\
|
||||
const index = 0;
|
||||
const newTextAndChange = withInsert(oldText, index, "declare ");
|
||||
|
||||
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 3);
|
||||
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 0);
|
||||
});
|
||||
|
||||
it("Insert function above arrow function with comment", () => {
|
||||
@@ -674,7 +674,7 @@ module m3 { }\
|
||||
const oldText = ScriptSnapshot.fromString(source);
|
||||
const newTextAndChange = withInsert(oldText, 0, "{");
|
||||
|
||||
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9);
|
||||
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
|
||||
});
|
||||
|
||||
it("Removing block around function declarations", () => {
|
||||
@@ -683,7 +683,7 @@ module m3 { }\
|
||||
const oldText = ScriptSnapshot.fromString(source);
|
||||
const newTextAndChange = withDelete(oldText, 0, "{".length);
|
||||
|
||||
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 9);
|
||||
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
|
||||
});
|
||||
|
||||
it("Moving methods from class to object literal", () => {
|
||||
|
||||
@@ -6,7 +6,7 @@ interface ClassificationEntry {
|
||||
position?: number;
|
||||
}
|
||||
|
||||
describe("Colorization", function () {
|
||||
describe("Colorization", () => {
|
||||
// Use the shim adapter to ensure test coverage of the shim layer for the classifier
|
||||
const languageServiceAdapter = new Harness.LanguageService.ShimLanguageServiceAdapter(/*preprocessToResolve*/ false);
|
||||
const classifier = languageServiceAdapter.getClassifier();
|
||||
@@ -55,8 +55,8 @@ describe("Colorization", function () {
|
||||
}
|
||||
}
|
||||
|
||||
describe("test getClassifications", function () {
|
||||
it("Returns correct token classes", function () {
|
||||
describe("test getClassifications", () => {
|
||||
it("Returns correct token classes", () => {
|
||||
testLexicalClassification("var x: string = \"foo\"; //Hello",
|
||||
ts.EndOfLineState.None,
|
||||
keyword("var"),
|
||||
@@ -70,7 +70,7 @@ describe("Colorization", function () {
|
||||
punctuation(";"));
|
||||
});
|
||||
|
||||
it("correctly classifies a comment after a divide operator", function () {
|
||||
it("correctly classifies a comment after a divide operator", () => {
|
||||
testLexicalClassification("1 / 2 // comment",
|
||||
ts.EndOfLineState.None,
|
||||
numberLiteral("1"),
|
||||
@@ -80,7 +80,7 @@ describe("Colorization", function () {
|
||||
comment("// comment"));
|
||||
});
|
||||
|
||||
it("correctly classifies a literal after a divide operator", function () {
|
||||
it("correctly classifies a literal after a divide operator", () => {
|
||||
testLexicalClassification("1 / 2, 3 / 4",
|
||||
ts.EndOfLineState.None,
|
||||
numberLiteral("1"),
|
||||
@@ -92,131 +92,131 @@ describe("Colorization", function () {
|
||||
operator(","));
|
||||
});
|
||||
|
||||
it("correctly classifies a multi-line string with one backslash", function () {
|
||||
it("correctly classifies a multi-line string with one backslash", () => {
|
||||
testLexicalClassification("'line1\\",
|
||||
ts.EndOfLineState.None,
|
||||
stringLiteral("'line1\\"),
|
||||
finalEndOfLineState(ts.EndOfLineState.InSingleQuoteStringLiteral));
|
||||
});
|
||||
|
||||
it("correctly classifies a multi-line string with three backslashes", function () {
|
||||
it("correctly classifies a multi-line string with three backslashes", () => {
|
||||
testLexicalClassification("'line1\\\\\\",
|
||||
ts.EndOfLineState.None,
|
||||
stringLiteral("'line1\\\\\\"),
|
||||
finalEndOfLineState(ts.EndOfLineState.InSingleQuoteStringLiteral));
|
||||
});
|
||||
|
||||
it("correctly classifies an unterminated single-line string with no backslashes", function () {
|
||||
it("correctly classifies an unterminated single-line string with no backslashes", () => {
|
||||
testLexicalClassification("'line1",
|
||||
ts.EndOfLineState.None,
|
||||
stringLiteral("'line1"),
|
||||
finalEndOfLineState(ts.EndOfLineState.None));
|
||||
});
|
||||
|
||||
it("correctly classifies an unterminated single-line string with two backslashes", function () {
|
||||
it("correctly classifies an unterminated single-line string with two backslashes", () => {
|
||||
testLexicalClassification("'line1\\\\",
|
||||
ts.EndOfLineState.None,
|
||||
stringLiteral("'line1\\\\"),
|
||||
finalEndOfLineState(ts.EndOfLineState.None));
|
||||
});
|
||||
|
||||
it("correctly classifies an unterminated single-line string with four backslashes", function () {
|
||||
it("correctly classifies an unterminated single-line string with four backslashes", () => {
|
||||
testLexicalClassification("'line1\\\\\\\\",
|
||||
ts.EndOfLineState.None,
|
||||
stringLiteral("'line1\\\\\\\\"),
|
||||
finalEndOfLineState(ts.EndOfLineState.None));
|
||||
});
|
||||
|
||||
it("correctly classifies the continuing line of a multi-line string ending in one backslash", function () {
|
||||
it("correctly classifies the continuing line of a multi-line string ending in one backslash", () => {
|
||||
testLexicalClassification("\\",
|
||||
ts.EndOfLineState.InDoubleQuoteStringLiteral,
|
||||
stringLiteral("\\"),
|
||||
finalEndOfLineState(ts.EndOfLineState.InDoubleQuoteStringLiteral));
|
||||
});
|
||||
|
||||
it("correctly classifies the continuing line of a multi-line string ending in three backslashes", function () {
|
||||
it("correctly classifies the continuing line of a multi-line string ending in three backslashes", () => {
|
||||
testLexicalClassification("\\",
|
||||
ts.EndOfLineState.InDoubleQuoteStringLiteral,
|
||||
stringLiteral("\\"),
|
||||
finalEndOfLineState(ts.EndOfLineState.InDoubleQuoteStringLiteral));
|
||||
});
|
||||
|
||||
it("correctly classifies the last line of an unterminated multi-line string ending in no backslashes", function () {
|
||||
it("correctly classifies the last line of an unterminated multi-line string ending in no backslashes", () => {
|
||||
testLexicalClassification(" ",
|
||||
ts.EndOfLineState.InDoubleQuoteStringLiteral,
|
||||
stringLiteral(" "),
|
||||
finalEndOfLineState(ts.EndOfLineState.None));
|
||||
});
|
||||
|
||||
it("correctly classifies the last line of an unterminated multi-line string ending in two backslashes", function () {
|
||||
it("correctly classifies the last line of an unterminated multi-line string ending in two backslashes", () => {
|
||||
testLexicalClassification("\\\\",
|
||||
ts.EndOfLineState.InDoubleQuoteStringLiteral,
|
||||
stringLiteral("\\\\"),
|
||||
finalEndOfLineState(ts.EndOfLineState.None));
|
||||
});
|
||||
|
||||
it("correctly classifies the last line of an unterminated multi-line string ending in four backslashes", function () {
|
||||
it("correctly classifies the last line of an unterminated multi-line string ending in four backslashes", () => {
|
||||
testLexicalClassification("\\\\\\\\",
|
||||
ts.EndOfLineState.InDoubleQuoteStringLiteral,
|
||||
stringLiteral("\\\\\\\\"),
|
||||
finalEndOfLineState(ts.EndOfLineState.None));
|
||||
});
|
||||
|
||||
it("correctly classifies the last line of a multi-line string", function () {
|
||||
it("correctly classifies the last line of a multi-line string", () => {
|
||||
testLexicalClassification("'",
|
||||
ts.EndOfLineState.InSingleQuoteStringLiteral,
|
||||
stringLiteral("'"),
|
||||
finalEndOfLineState(ts.EndOfLineState.None));
|
||||
});
|
||||
|
||||
it("correctly classifies an unterminated multiline comment", function () {
|
||||
it("correctly classifies an unterminated multiline comment", () => {
|
||||
testLexicalClassification("/*",
|
||||
ts.EndOfLineState.None,
|
||||
comment("/*"),
|
||||
finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia));
|
||||
});
|
||||
|
||||
it("correctly classifies the termination of a multiline comment", function () {
|
||||
it("correctly classifies the termination of a multiline comment", () => {
|
||||
testLexicalClassification(" */ ",
|
||||
ts.EndOfLineState.InMultiLineCommentTrivia,
|
||||
comment(" */"),
|
||||
finalEndOfLineState(ts.EndOfLineState.None));
|
||||
});
|
||||
|
||||
it("correctly classifies the continuation of a multiline comment", function () {
|
||||
it("correctly classifies the continuation of a multiline comment", () => {
|
||||
testLexicalClassification("LOREM IPSUM DOLOR ",
|
||||
ts.EndOfLineState.InMultiLineCommentTrivia,
|
||||
comment("LOREM IPSUM DOLOR "),
|
||||
finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia));
|
||||
});
|
||||
|
||||
it("correctly classifies an unterminated multiline comment on a line ending in '/*/'", function () {
|
||||
it("correctly classifies an unterminated multiline comment on a line ending in '/*/'", () => {
|
||||
testLexicalClassification(" /*/",
|
||||
ts.EndOfLineState.None,
|
||||
comment("/*/"),
|
||||
finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia));
|
||||
});
|
||||
|
||||
it("correctly classifies an unterminated multiline comment with trailing space", function () {
|
||||
it("correctly classifies an unterminated multiline comment with trailing space", () => {
|
||||
testLexicalClassification("/* ",
|
||||
ts.EndOfLineState.None,
|
||||
comment("/* "),
|
||||
finalEndOfLineState(ts.EndOfLineState.InMultiLineCommentTrivia));
|
||||
});
|
||||
|
||||
it("correctly classifies a keyword after a dot", function () {
|
||||
it("correctly classifies a keyword after a dot", () => {
|
||||
testLexicalClassification("a.var",
|
||||
ts.EndOfLineState.None,
|
||||
identifier("var"));
|
||||
});
|
||||
|
||||
it("correctly classifies a string literal after a dot", function () {
|
||||
it("correctly classifies a string literal after a dot", () => {
|
||||
testLexicalClassification("a.\"var\"",
|
||||
ts.EndOfLineState.None,
|
||||
stringLiteral("\"var\""));
|
||||
});
|
||||
|
||||
it("correctly classifies a keyword after a dot separated by comment trivia", function () {
|
||||
it("correctly classifies a keyword after a dot separated by comment trivia", () => {
|
||||
testLexicalClassification("a./*hello world*/ var",
|
||||
ts.EndOfLineState.None,
|
||||
identifier("a"),
|
||||
@@ -225,21 +225,21 @@ describe("Colorization", function () {
|
||||
identifier("var"));
|
||||
});
|
||||
|
||||
it("classifies a property access with whitespace around the dot", function () {
|
||||
it("classifies a property access with whitespace around the dot", () => {
|
||||
testLexicalClassification(" x .\tfoo ()",
|
||||
ts.EndOfLineState.None,
|
||||
identifier("x"),
|
||||
identifier("foo"));
|
||||
});
|
||||
|
||||
it("classifies a keyword after a dot on previous line", function () {
|
||||
it("classifies a keyword after a dot on previous line", () => {
|
||||
testLexicalClassification("var",
|
||||
ts.EndOfLineState.None,
|
||||
keyword("var"),
|
||||
finalEndOfLineState(ts.EndOfLineState.None));
|
||||
});
|
||||
|
||||
it("classifies multiple keywords properly", function () {
|
||||
it("classifies multiple keywords properly", () => {
|
||||
testLexicalClassification("public static",
|
||||
ts.EndOfLineState.None,
|
||||
keyword("public"),
|
||||
@@ -353,7 +353,7 @@ describe("Colorization", function () {
|
||||
}
|
||||
});
|
||||
|
||||
it("classifies partially written generics correctly.", function () {
|
||||
it("classifies partially written generics correctly.", () => {
|
||||
testLexicalClassification("Foo<number",
|
||||
ts.EndOfLineState.None,
|
||||
identifier("Foo"),
|
||||
@@ -466,7 +466,7 @@ class D { }\r\n\
|
||||
finalEndOfLineState(ts.EndOfLineState.None));
|
||||
});
|
||||
|
||||
it("'of' keyword", function () {
|
||||
it("'of' keyword", () => {
|
||||
testLexicalClassification("for (var of of of) { }",
|
||||
ts.EndOfLineState.None,
|
||||
keyword("for"),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// <reference path="..\..\..\services\patternMatcher.ts" />
|
||||
|
||||
describe("PatternMatcher", function () {
|
||||
describe("BreakIntoCharacterSpans", function () {
|
||||
describe("PatternMatcher", () => {
|
||||
describe("BreakIntoCharacterSpans", () => {
|
||||
it("EmptyIdentifier", () => {
|
||||
verifyBreakIntoCharacterSpans("");
|
||||
});
|
||||
@@ -55,7 +55,7 @@ describe("PatternMatcher", function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe("BreakIntoWordSpans", function () {
|
||||
describe("BreakIntoWordSpans", () => {
|
||||
it("VarbatimIdentifier", () => {
|
||||
verifyBreakIntoWordSpans("@int:", "int");
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/// <reference path="..\..\harnessLanguageService.ts" />
|
||||
|
||||
describe("PreProcessFile:", function () {
|
||||
describe("PreProcessFile:", () => {
|
||||
function test(sourceText: string, readImportFile: boolean, detectJavaScriptImports: boolean, expectedPreProcess: ts.PreProcessedFileInfo): void {
|
||||
const resultPreProcess = ts.preProcessFile(sourceText, readImportFile, detectJavaScriptImports);
|
||||
|
||||
@@ -31,8 +31,8 @@ describe("PreProcessFile:", function () {
|
||||
}
|
||||
}
|
||||
|
||||
describe("Test preProcessFiles,", function () {
|
||||
it("Correctly return referenced files from triple slash", function () {
|
||||
describe("Test preProcessFiles,", () => {
|
||||
it("Correctly return referenced files from triple slash", () => {
|
||||
test("///<reference path = \"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\"/>" + "\n" + "///<reference path=\"refFile3.ts\" />" + "\n" + "///<reference path= \"..\\refFile4d.ts\" />",
|
||||
/*readImportFile*/ true,
|
||||
/*detectJavaScriptImports*/ false,
|
||||
@@ -46,7 +46,7 @@ describe("PreProcessFile:", function () {
|
||||
});
|
||||
}),
|
||||
|
||||
it("Do not return reference path because of invalid triple-slash syntax", function () {
|
||||
it("Do not return reference path because of invalid triple-slash syntax", () => {
|
||||
test("///<reference path\"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\">" + "\n" + "///<referencepath=\"refFile3.ts\" />" + "\n" + "///<reference pat= \"refFile4d.ts\" />",
|
||||
/*readImportFile*/ true,
|
||||
/*detectJavaScriptImports*/ false,
|
||||
@@ -59,7 +59,7 @@ describe("PreProcessFile:", function () {
|
||||
});
|
||||
}),
|
||||
|
||||
it("Correctly return imported files", function () {
|
||||
it("Correctly return imported files", () => {
|
||||
test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");",
|
||||
/*readImportFile*/ true,
|
||||
/*detectJavaScriptImports*/ false,
|
||||
@@ -73,7 +73,7 @@ describe("PreProcessFile:", function () {
|
||||
});
|
||||
}),
|
||||
|
||||
it("Do not return imported files if readImportFiles argument is false", function () {
|
||||
it("Do not return imported files if readImportFiles argument is false", () => {
|
||||
test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");",
|
||||
/*readImportFile*/ false,
|
||||
/*detectJavaScriptImports*/ false,
|
||||
@@ -86,7 +86,7 @@ describe("PreProcessFile:", function () {
|
||||
});
|
||||
}),
|
||||
|
||||
it("Do not return import path because of invalid import syntax", function () {
|
||||
it("Do not return import path because of invalid import syntax", () => {
|
||||
test("import i1 require(\"r1.ts\"); import = require(\"r2.ts\") import i3= require(\"r3.ts\"); import i5",
|
||||
/*readImportFile*/ true,
|
||||
/*detectJavaScriptImports*/ false,
|
||||
@@ -99,7 +99,7 @@ describe("PreProcessFile:", function () {
|
||||
});
|
||||
}),
|
||||
|
||||
it("Correctly return referenced files and import files", function () {
|
||||
it("Correctly return referenced files and import files", () => {
|
||||
test("///<reference path=\"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\"/>" + "\n" + "import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\");",
|
||||
/*readImportFile*/ true,
|
||||
/*detectJavaScriptImports*/ false,
|
||||
@@ -112,7 +112,7 @@ describe("PreProcessFile:", function () {
|
||||
});
|
||||
}),
|
||||
|
||||
it("Correctly return referenced files and import files even with some invalid syntax", function () {
|
||||
it("Correctly return referenced files and import files even with some invalid syntax", () => {
|
||||
test("///<reference path=\"refFile1.ts\" />" + "\n" + "///<reference path \"refFile2.ts\"/>" + "\n" + "import i1 = require(\"r1.ts\"); import = require(\"r2.ts\"); import i2 = require(\"r3.ts\");",
|
||||
/*readImportFile*/ true,
|
||||
/*detectJavaScriptImports*/ false,
|
||||
@@ -125,7 +125,7 @@ describe("PreProcessFile:", function () {
|
||||
});
|
||||
});
|
||||
|
||||
it("Correctly return ES6 imports", function () {
|
||||
it("Correctly return ES6 imports", () => {
|
||||
test("import * as ns from \"m1\";" + "\n" +
|
||||
"import def, * as ns from \"m2\";" + "\n" +
|
||||
"import def from \"m3\";" + "\n" +
|
||||
@@ -152,7 +152,7 @@ describe("PreProcessFile:", function () {
|
||||
});
|
||||
});
|
||||
|
||||
it("Correctly return ES6 exports", function () {
|
||||
it("Correctly return ES6 exports", () => {
|
||||
test("export * from \"m1\";" + "\n" +
|
||||
"export {a} from \"m2\";" + "\n" +
|
||||
"export {a as A} from \"m3\";" + "\n" +
|
||||
@@ -192,7 +192,7 @@ describe("PreProcessFile:", function () {
|
||||
});
|
||||
});
|
||||
|
||||
it("Correctly handles export import declarations", function () {
|
||||
it("Correctly handles export import declarations", () => {
|
||||
test("export import a = require(\"m1\");",
|
||||
/*readImportFile*/ true,
|
||||
/*detectJavaScriptImports*/ false,
|
||||
@@ -206,7 +206,7 @@ describe("PreProcessFile:", function () {
|
||||
isLibFile: false
|
||||
});
|
||||
});
|
||||
it("Correctly handles export require calls in JavaScript files", function () {
|
||||
it("Correctly handles export require calls in JavaScript files", () => {
|
||||
test(`
|
||||
export import a = require("m1");
|
||||
var x = require('m2');
|
||||
@@ -228,7 +228,7 @@ describe("PreProcessFile:", function () {
|
||||
isLibFile: false
|
||||
});
|
||||
});
|
||||
it("Correctly handles dependency lists in define([deplist]) calls in JavaScript files", function () {
|
||||
it("Correctly handles dependency lists in define([deplist]) calls in JavaScript files", () => {
|
||||
test(`
|
||||
define(["mod1", "mod2"], (m1, m2) => {
|
||||
});
|
||||
@@ -246,7 +246,7 @@ describe("PreProcessFile:", function () {
|
||||
isLibFile: false
|
||||
});
|
||||
});
|
||||
it("Correctly handles dependency lists in define(modName, [deplist]) calls in JavaScript files", function () {
|
||||
it("Correctly handles dependency lists in define(modName, [deplist]) calls in JavaScript files", () => {
|
||||
test(`
|
||||
define("mod", ["mod1", "mod2"], (m1, m2) => {
|
||||
});
|
||||
|
||||
@@ -53,6 +53,17 @@ namespace ts.server {
|
||||
return new TestSession(opts);
|
||||
}
|
||||
|
||||
// Disable sourcemap support for the duration of the test, as sourcemapping the errors generated during this test is slow and not something we care to test
|
||||
let oldPrepare: Function;
|
||||
before(() => {
|
||||
oldPrepare = (Error as any).prepareStackTrace;
|
||||
delete (Error as any).prepareStackTrace;
|
||||
});
|
||||
|
||||
after(() => {
|
||||
(Error as any).prepareStackTrace = oldPrepare;
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
session = createSession();
|
||||
session.send = (msg: protocol.Message) => {
|
||||
@@ -117,7 +128,7 @@ namespace ts.server {
|
||||
body: undefined
|
||||
});
|
||||
});
|
||||
it ("should handle literal types in request", () => {
|
||||
it("should handle literal types in request", () => {
|
||||
const configureRequest: protocol.ConfigureRequest = {
|
||||
command: CommandNames.Configure,
|
||||
seq: 0,
|
||||
@@ -175,6 +186,8 @@ namespace ts.server {
|
||||
CommandNames.Configure,
|
||||
CommandNames.Definition,
|
||||
CommandNames.DefinitionFull,
|
||||
CommandNames.DefinitionAndBoundSpan,
|
||||
CommandNames.DefinitionAndBoundSpanFull,
|
||||
CommandNames.Implementation,
|
||||
CommandNames.ImplementationFull,
|
||||
CommandNames.Exit,
|
||||
@@ -341,7 +354,7 @@ namespace ts.server {
|
||||
session.addProtocolHandler(command, () => resp);
|
||||
|
||||
expect(() => session.addProtocolHandler(command, () => resp))
|
||||
.to.throw(`Protocol handler already exists for command "${command}"`);
|
||||
.to.throw(`Protocol handler already exists for command "${command}"`);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -387,6 +400,18 @@ namespace ts.server {
|
||||
});
|
||||
|
||||
describe("exceptions", () => {
|
||||
|
||||
// Disable sourcemap support for the duration of the test, as sourcemapping the errors generated during this test is slow and not something we care to test
|
||||
let oldPrepare: Function;
|
||||
before(() => {
|
||||
oldPrepare = (Error as any).prepareStackTrace;
|
||||
delete (Error as any).prepareStackTrace;
|
||||
});
|
||||
|
||||
after(() => {
|
||||
(Error as any).prepareStackTrace = oldPrepare;
|
||||
});
|
||||
|
||||
const command = "testhandler";
|
||||
class TestSession extends Session {
|
||||
lastSent: protocol.Message;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace ts {
|
||||
const printerOptions = { newLine: NewLineKind.LineFeed };
|
||||
const newLineCharacter = getNewLineCharacter(printerOptions);
|
||||
|
||||
function getRuleProvider(action?: (opts: FormatCodeSettings) => void) {
|
||||
const getRuleProviderDefault = memoize(() => {
|
||||
const options = {
|
||||
indentSize: 4,
|
||||
tabSize: 4,
|
||||
@@ -45,12 +45,38 @@ namespace ts {
|
||||
placeOpenBraceOnNewLineForFunctions: false,
|
||||
placeOpenBraceOnNewLineForControlBlocks: false,
|
||||
};
|
||||
if (action) {
|
||||
action(options);
|
||||
}
|
||||
const rulesProvider = new formatting.RulesProvider();
|
||||
rulesProvider.ensureUpToDate(options);
|
||||
return rulesProvider;
|
||||
});
|
||||
const getRuleProviderNewlineBrace = memoize(() => {
|
||||
const options = {
|
||||
indentSize: 4,
|
||||
tabSize: 4,
|
||||
newLineCharacter,
|
||||
convertTabsToSpaces: true,
|
||||
indentStyle: ts.IndentStyle.Smart,
|
||||
insertSpaceAfterConstructor: false,
|
||||
insertSpaceAfterCommaDelimiter: true,
|
||||
insertSpaceAfterSemicolonInForStatements: true,
|
||||
insertSpaceBeforeAndAfterBinaryOperators: true,
|
||||
insertSpaceAfterKeywordsInControlFlowStatements: true,
|
||||
insertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true,
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
|
||||
insertSpaceBeforeFunctionParenthesis: false,
|
||||
placeOpenBraceOnNewLineForFunctions: true,
|
||||
placeOpenBraceOnNewLineForControlBlocks: false,
|
||||
};
|
||||
const rulesProvider = new formatting.RulesProvider();
|
||||
rulesProvider.ensureUpToDate(options);
|
||||
return rulesProvider;
|
||||
});
|
||||
function getRuleProvider(placeOpenBraceOnNewLineForFunctions: boolean) {
|
||||
return placeOpenBraceOnNewLineForFunctions ? getRuleProviderNewlineBrace() : getRuleProviderDefault();
|
||||
}
|
||||
|
||||
// validate that positions that were recovered from the printed text actually match positions that will be created if the same text is parsed.
|
||||
@@ -78,11 +104,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function runSingleFileTest(caption: string, setupFormatOptions: (opts: FormatCodeSettings) => void, text: string, validateNodes: boolean, testBlock: (sourceFile: SourceFile, changeTracker: textChanges.ChangeTracker) => void) {
|
||||
function runSingleFileTest(caption: string, placeOpenBraceOnNewLineForFunctions: boolean, text: string, validateNodes: boolean, testBlock: (sourceFile: SourceFile, changeTracker: textChanges.ChangeTracker) => void) {
|
||||
it(caption, () => {
|
||||
Harness.Baseline.runBaseline(`textChanges/${caption}.js`, () => {
|
||||
const sourceFile = createSourceFile("source.ts", text, ScriptTarget.ES2015, /*setParentNodes*/ true);
|
||||
const rulesProvider = getRuleProvider(setupFormatOptions);
|
||||
const rulesProvider = getRuleProvider(placeOpenBraceOnNewLineForFunctions);
|
||||
const changeTracker = new textChanges.ChangeTracker(printerOptions.newLine, rulesProvider, validateNodes ? verifyPositions : undefined);
|
||||
testBlock(sourceFile, changeTracker);
|
||||
const changes = changeTracker.getChanges();
|
||||
@@ -94,10 +120,6 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
function setNewLineForOpenBraceInFunctions(opts: FormatCodeSettings) {
|
||||
opts.placeOpenBraceOnNewLineForFunctions = true;
|
||||
}
|
||||
|
||||
{
|
||||
const text = `
|
||||
namespace M
|
||||
@@ -120,7 +142,7 @@ namespace M
|
||||
}
|
||||
}
|
||||
}`;
|
||||
runSingleFileTest("extractMethodLike", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("extractMethodLike", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
const statements = (<Block>(<FunctionDeclaration>findChild("foo", sourceFile)).body).statements.slice(1);
|
||||
const newFunction = createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
@@ -155,7 +177,7 @@ function bar() {
|
||||
return 2;
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("deleteRange1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteRange1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteRange(sourceFile, { pos: text.indexOf("function foo"), end: text.indexOf("function bar") });
|
||||
});
|
||||
}
|
||||
@@ -175,19 +197,19 @@ var x = 1; // some comment - 1
|
||||
var y = 2; // comment 3
|
||||
var z = 3; // comment 4
|
||||
`;
|
||||
runSingleFileTest("deleteNode1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNode1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNode(sourceFile, findVariableStatementContaining("y", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNode2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNode2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNode(sourceFile, findVariableStatementContaining("y", sourceFile), { useNonAdjustedStartPosition: true });
|
||||
});
|
||||
runSingleFileTest("deleteNode3", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNode3", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNode(sourceFile, findVariableStatementContaining("y", sourceFile), { useNonAdjustedEndPosition: true });
|
||||
});
|
||||
runSingleFileTest("deleteNode4", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNode4", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNode(sourceFile, findVariableStatementContaining("y", sourceFile), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true });
|
||||
});
|
||||
runSingleFileTest("deleteNode5", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNode5", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNode(sourceFile, findVariableStatementContaining("x", sourceFile));
|
||||
});
|
||||
}
|
||||
@@ -201,18 +223,18 @@ var z = 3; // comment 5
|
||||
// comment 6
|
||||
var a = 4; // comment 7
|
||||
`;
|
||||
runSingleFileTest("deleteNodeRange1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeRange1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeRange2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeRange2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile),
|
||||
{ useNonAdjustedStartPosition: true });
|
||||
});
|
||||
runSingleFileTest("deleteNodeRange3", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeRange3", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile),
|
||||
{ useNonAdjustedEndPosition: true });
|
||||
});
|
||||
runSingleFileTest("deleteNodeRange4", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeRange4", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile),
|
||||
{ useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true });
|
||||
});
|
||||
@@ -257,14 +279,14 @@ var y = 2; // comment 4
|
||||
var z = 3; // comment 5
|
||||
// comment 6
|
||||
var a = 4; // comment 7`;
|
||||
runSingleFileTest("replaceRange", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceRange", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceRange(sourceFile, { pos: text.indexOf("var y"), end: text.indexOf("var a") }, createTestClass(), { suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceRangeWithForcedIndentation", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceRangeWithForcedIndentation", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceRange(sourceFile, { pos: text.indexOf("var y"), end: text.indexOf("var a") }, createTestClass(), { suffix: newLineCharacter, indentation: 8, delta: 0 });
|
||||
});
|
||||
|
||||
runSingleFileTest("replaceRangeNoLineBreakBefore", setNewLineForOpenBraceInFunctions, `const x = 1, y = "2";`, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceRangeNoLineBreakBefore", /*placeOpenBraceOnNewLineForFunctions*/ true, `const x = 1, y = "2";`, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
const newNode = createTestVariableDeclaration("z1");
|
||||
changeTracker.replaceRange(sourceFile, { pos: sourceFile.text.indexOf("y"), end: sourceFile.text.indexOf(";") }, newNode);
|
||||
});
|
||||
@@ -275,7 +297,7 @@ namespace A {
|
||||
const x = 1, y = "2";
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("replaceNode1NoLineBreakBefore", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNode1NoLineBreakBefore", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
const newNode = createTestVariableDeclaration("z1");
|
||||
changeTracker.replaceNode(sourceFile, findChild("y", sourceFile), newNode);
|
||||
});
|
||||
@@ -289,19 +311,19 @@ var y = 2; // comment 4
|
||||
var z = 3; // comment 5
|
||||
// comment 6
|
||||
var a = 4; // comment 7`;
|
||||
runSingleFileTest("replaceNode1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNode1", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNode2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNode2", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, suffix: newLineCharacter, prefix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNode3", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNode3", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedEndPosition: true, suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNode4", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNode4", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true });
|
||||
});
|
||||
runSingleFileTest("replaceNode5", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNode5", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("x", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true });
|
||||
});
|
||||
}
|
||||
@@ -314,16 +336,16 @@ var y = 2; // comment 4
|
||||
var z = 3; // comment 5
|
||||
// comment 6
|
||||
var a = 4; // comment 7`;
|
||||
runSingleFileTest("replaceNodeRange1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNodeRange1", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNodeRange2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNodeRange2", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, suffix: newLineCharacter, prefix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNodeRange3", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNodeRange3", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedEndPosition: true, suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNodeRange4", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNodeRange4", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true });
|
||||
});
|
||||
}
|
||||
@@ -336,10 +358,10 @@ var y; // comment 4
|
||||
var z = 3; // comment 5
|
||||
// comment 6
|
||||
var a = 4; // comment 7`;
|
||||
runSingleFileTest("insertNodeAt1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAt1", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAt(sourceFile, text.indexOf("var y"), createTestClass(), { suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("insertNodeAt2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAt2", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAt(sourceFile, text.indexOf("; // comment 4"), createTestVariableDeclaration("z1"));
|
||||
});
|
||||
}
|
||||
@@ -354,16 +376,16 @@ namespace M {
|
||||
// comment 6
|
||||
var a = 4; // comment 7
|
||||
}`;
|
||||
runSingleFileTest("insertNodeBefore1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeBefore1", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeBefore(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("insertNodeBefore2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeBefore2", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeBefore(sourceFile, findChild("M", sourceFile), createTestClass(), { suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("insertNodeAfter1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAfter1", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAfter(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("insertNodeAfter2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAfter2", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAfter(sourceFile, findChild("M", sourceFile), createTestClass(), { prefix: newLineCharacter });
|
||||
});
|
||||
}
|
||||
@@ -389,7 +411,7 @@ class A {
|
||||
}
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeAfter3", noop, text1, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAfter3", /*placeOpenBraceOnNewLineForFunctions*/ false, text1, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAfter(sourceFile, findOpenBraceForConstructor(sourceFile), createTestSuperCall(), { suffix: newLineCharacter });
|
||||
});
|
||||
const text2 = `
|
||||
@@ -399,7 +421,7 @@ class A {
|
||||
}
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeAfter4", noop, text2, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAfter4", /*placeOpenBraceOnNewLineForFunctions*/ false, text2, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAfter(sourceFile, findVariableStatementContaining("x", sourceFile), createTestSuperCall(), { suffix: newLineCharacter });
|
||||
});
|
||||
const text3 = `
|
||||
@@ -409,31 +431,31 @@ class A {
|
||||
}
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeAfter3-block with newline", noop, text3, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAfter3-block with newline", /*placeOpenBraceOnNewLineForFunctions*/ false, text3, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAfter(sourceFile, findOpenBraceForConstructor(sourceFile), createTestSuperCall(), { suffix: newLineCharacter });
|
||||
});
|
||||
}
|
||||
{
|
||||
const text = `var a = 1, b = 2, c = 3;`;
|
||||
runSingleFileTest("deleteNodeInList1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList3", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList3", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile));
|
||||
});
|
||||
}
|
||||
{
|
||||
const text = `var a = 1,b = 2,c = 3;`;
|
||||
runSingleFileTest("deleteNodeInList1_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList1_1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList2_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList2_1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList3_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList3_1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile));
|
||||
});
|
||||
}
|
||||
@@ -444,13 +466,13 @@ namespace M {
|
||||
b = 2,
|
||||
c = 3;
|
||||
}`;
|
||||
runSingleFileTest("deleteNodeInList4", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList4", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList5", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList5", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList6", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList6", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile));
|
||||
});
|
||||
}
|
||||
@@ -463,13 +485,13 @@ namespace M {
|
||||
// comment 4
|
||||
c = 3; // comment 5
|
||||
}`;
|
||||
runSingleFileTest("deleteNodeInList4_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList4_1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList5_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList5_1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList6_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList6_1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile));
|
||||
});
|
||||
}
|
||||
@@ -478,13 +500,13 @@ namespace M {
|
||||
function foo(a: number, b: string, c = true) {
|
||||
return 1;
|
||||
}`;
|
||||
runSingleFileTest("deleteNodeInList7", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList7", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList8", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList8", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList9", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList9", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile));
|
||||
});
|
||||
}
|
||||
@@ -493,13 +515,13 @@ function foo(a: number, b: string, c = true) {
|
||||
function foo(a: number,b: string,c = true) {
|
||||
return 1;
|
||||
}`;
|
||||
runSingleFileTest("deleteNodeInList10", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList10", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList11", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList11", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList12", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList12", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile));
|
||||
});
|
||||
}
|
||||
@@ -511,40 +533,40 @@ function foo(
|
||||
c = true) {
|
||||
return 1;
|
||||
}`;
|
||||
runSingleFileTest("deleteNodeInList13", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList13", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList14", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList14", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList15", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList15", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile));
|
||||
});
|
||||
}
|
||||
{
|
||||
const text = `
|
||||
const x = 1, y = 2;`;
|
||||
runSingleFileTest("insertNodeInListAfter1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
runSingleFileTest("insertNodeInListAfter2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
}
|
||||
{
|
||||
const text = `
|
||||
const /*x*/ x = 1, /*y*/ y = 2;`;
|
||||
runSingleFileTest("insertNodeInListAfter3", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter3", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
runSingleFileTest("insertNodeInListAfter4", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter4", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
}
|
||||
{
|
||||
const text = `
|
||||
const x = 1;`;
|
||||
runSingleFileTest("insertNodeInListAfter5", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter5", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
}
|
||||
@@ -552,10 +574,10 @@ const x = 1;`;
|
||||
const text = `
|
||||
const x = 1,
|
||||
y = 2;`;
|
||||
runSingleFileTest("insertNodeInListAfter6", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter6", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
runSingleFileTest("insertNodeInListAfter7", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter7", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
}
|
||||
@@ -563,10 +585,10 @@ const x = 1,
|
||||
const text = `
|
||||
const /*x*/ x = 1,
|
||||
/*y*/ y = 2;`;
|
||||
runSingleFileTest("insertNodeInListAfter8", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter8", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
runSingleFileTest("insertNodeInListAfter9", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter9", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
}
|
||||
@@ -575,7 +597,7 @@ const /*x*/ x = 1,
|
||||
import {
|
||||
x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter10", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter10", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(createIdentifier("b"), createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -584,7 +606,7 @@ import {
|
||||
import {
|
||||
x // this is x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter11", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter11", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(createIdentifier("b"), createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -593,7 +615,7 @@ import {
|
||||
import {
|
||||
x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter12", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter12", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -602,7 +624,7 @@ import {
|
||||
import {
|
||||
x // this is x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter13", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter13", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -612,7 +634,7 @@ import {
|
||||
x0,
|
||||
x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter14", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter14", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(createIdentifier("b"), createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -622,7 +644,7 @@ import {
|
||||
x0,
|
||||
x // this is x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter15", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter15", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(createIdentifier("b"), createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -632,7 +654,7 @@ import {
|
||||
x0,
|
||||
x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter16", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter16", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -642,7 +664,7 @@ import {
|
||||
x0,
|
||||
x // this is x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter17", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter17", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -651,7 +673,7 @@ import {
|
||||
import {
|
||||
x0, x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter18", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter18", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -660,7 +682,7 @@ import {
|
||||
class A {
|
||||
x;
|
||||
}`;
|
||||
runSingleFileTest("insertNodeAfterMultipleNodes", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAfterMultipleNodes", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
const newNodes = [];
|
||||
for (let i = 0; i < 11 /*error doesn't occur with fewer nodes*/; ++i) {
|
||||
newNodes.push(
|
||||
@@ -678,7 +700,7 @@ class A {
|
||||
x
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeAfterInClass1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAfterInClass1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), createProperty(undefined, undefined, "a", undefined, createKeywordTypeNode(SyntaxKind.BooleanKeyword), undefined), { suffix: newLineCharacter });
|
||||
});
|
||||
}
|
||||
@@ -688,7 +710,7 @@ class A {
|
||||
x;
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeAfterInClass2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAfterInClass2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), createProperty(undefined, undefined, "a", undefined, createKeywordTypeNode(SyntaxKind.BooleanKeyword), undefined), { suffix: newLineCharacter });
|
||||
});
|
||||
}
|
||||
@@ -699,7 +721,7 @@ class A {
|
||||
y = 1;
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("deleteNodeAfterInClass1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeAfterInClass1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNode(sourceFile, findChild("x", sourceFile));
|
||||
});
|
||||
}
|
||||
@@ -710,7 +732,7 @@ class A {
|
||||
y = 1;
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("deleteNodeAfterInClass2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeAfterInClass2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNode(sourceFile, findChild("x", sourceFile));
|
||||
});
|
||||
}
|
||||
@@ -720,7 +742,7 @@ class A {
|
||||
x = foo
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeInClassAfterNodeWithoutSeparator1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInClassAfterNodeWithoutSeparator1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
const newNode = createProperty(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
@@ -738,7 +760,7 @@ class A {
|
||||
}
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeInClassAfterNodeWithoutSeparator2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInClassAfterNodeWithoutSeparator2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
const newNode = createProperty(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
@@ -755,7 +777,7 @@ interface A {
|
||||
x
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeInInterfaceAfterNodeWithoutSeparator1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInInterfaceAfterNodeWithoutSeparator1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
const newNode = createProperty(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
@@ -772,7 +794,7 @@ interface A {
|
||||
x()
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeInInterfaceAfterNodeWithoutSeparator2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInInterfaceAfterNodeWithoutSeparator2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
const newNode = createProperty(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
@@ -787,7 +809,7 @@ interface A {
|
||||
const text = `
|
||||
let x = foo
|
||||
`;
|
||||
runSingleFileTest("insertNodeInStatementListAfterNodeWithoutSeparator1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInStatementListAfterNodeWithoutSeparator1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
const newNode = createStatement(createParen(createLiteral(1)));
|
||||
changeTracker.insertNodeAfter(sourceFile, findVariableStatementContaining("x", sourceFile), newNode, { suffix: newLineCharacter });
|
||||
});
|
||||
|
||||
@@ -20,6 +20,15 @@ namespace ts {
|
||||
};
|
||||
return (file: ts.SourceFile) => file;
|
||||
}
|
||||
function replaceNumberWith2(context: ts.TransformationContext) {
|
||||
function visitor(node: Node): Node {
|
||||
if (isNumericLiteral(node)) {
|
||||
return createNumericLiteral("2");
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
return (file: ts.SourceFile) => visitNode(file, visitor);
|
||||
}
|
||||
|
||||
function replaceIdentifiersNamedOldNameWithNewName(context: ts.TransformationContext) {
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
@@ -101,6 +110,20 @@ namespace ts {
|
||||
}).outputText;
|
||||
});
|
||||
|
||||
testBaseline("transformTypesInExportDefault", () => {
|
||||
return ts.transpileModule(`
|
||||
export default (foo: string) => { return 1; }
|
||||
`, {
|
||||
transformers: {
|
||||
before: [replaceNumberWith2],
|
||||
},
|
||||
compilerOptions: {
|
||||
target: ts.ScriptTarget.ESNext,
|
||||
newLine: NewLineKind.CarriageReturnLineFeed,
|
||||
}
|
||||
}).outputText;
|
||||
});
|
||||
|
||||
testBaseline("synthesizedClassAndNamespaceCombination", () => {
|
||||
return ts.transpileModule("", {
|
||||
transformers: {
|
||||
|
||||
@@ -1988,7 +1988,7 @@ declare module "fs" {
|
||||
|
||||
checkProgramActualFiles(watch(), mapDefined(files, f => f === configFile ? undefined : f.path));
|
||||
file1.content = "var zz30 = 100;";
|
||||
host.reloadFS(files, /*invokeDirectoryWatcherInsteadOfFileChanged*/ true);
|
||||
host.reloadFS(files, { invokeDirectoryWatcherInsteadOfFileChanged: true });
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
checkProgramActualFiles(watch(), mapDefined(files, f => f === configFile ? undefined : f.path));
|
||||
|
||||
@@ -356,7 +356,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
function checkOpenFiles(projectService: server.ProjectService, expectedFiles: FileOrFolder[]) {
|
||||
checkFileNames("Open files", projectService.openFiles.map(info => info.fileName), expectedFiles.map(file => file.path));
|
||||
checkFileNames("Open files", arrayFrom(projectService.openFiles.keys(), path => projectService.getScriptInfoForPath(path as Path).fileName), expectedFiles.map(file => file.path));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1248,13 +1248,13 @@ namespace ts.projectSystem {
|
||||
service.checkNumberOfProjects({ externalProjects: 1 });
|
||||
checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]);
|
||||
|
||||
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2);
|
||||
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, { includeExternalModuleExports: false });
|
||||
// should contain completions for string
|
||||
assert.isTrue(completions1.entries.some(e => e.name === "charAt"), "should contain 'charAt'");
|
||||
assert.isFalse(completions1.entries.some(e => e.name === "toExponential"), "should not contain 'toExponential'");
|
||||
|
||||
service.closeClientFile(f2.path);
|
||||
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2);
|
||||
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, { includeExternalModuleExports: false });
|
||||
// should contain completions for string
|
||||
assert.isFalse(completions2.entries.some(e => e.name === "charAt"), "should not contain 'charAt'");
|
||||
assert.isTrue(completions2.entries.some(e => e.name === "toExponential"), "should contain 'toExponential'");
|
||||
@@ -1280,11 +1280,11 @@ namespace ts.projectSystem {
|
||||
service.checkNumberOfProjects({ externalProjects: 1 });
|
||||
checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]);
|
||||
|
||||
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0);
|
||||
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, { includeExternalModuleExports: false });
|
||||
assert.isTrue(completions1.entries.some(e => e.name === "somelongname"), "should contain 'somelongname'");
|
||||
|
||||
service.closeClientFile(f2.path);
|
||||
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0);
|
||||
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, { includeExternalModuleExports: false });
|
||||
assert.isFalse(completions2.entries.some(e => e.name === "somelongname"), "should not contain 'somelongname'");
|
||||
const sf2 = service.externalProjects[0].getLanguageService().getProgram().getSourceFile(f2.path);
|
||||
assert.equal(sf2.text, "");
|
||||
@@ -1845,7 +1845,7 @@ namespace ts.projectSystem {
|
||||
|
||||
// Check identifiers defined in HTML content are available in .ts file
|
||||
const project = configuredProjectAt(projectService, 0);
|
||||
let completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 1);
|
||||
let completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 1, { includeExternalModuleExports: false });
|
||||
assert(completions && completions.entries[0].name === "hello", `expected entry hello to be in completion list`);
|
||||
|
||||
// Close HTML file
|
||||
@@ -1859,7 +1859,7 @@ namespace ts.projectSystem {
|
||||
checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]);
|
||||
|
||||
// Check identifiers defined in HTML content are not available in .ts file
|
||||
completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 5);
|
||||
completions = project.getLanguageService().getCompletionsAtPosition(file1.path, 5, { includeExternalModuleExports: false });
|
||||
assert(completions && completions.entries[0].name !== "hello", `unexpected hello entry in completion list`);
|
||||
});
|
||||
|
||||
@@ -3445,6 +3445,117 @@ namespace ts.projectSystem {
|
||||
diags = session.executeCommand(getErrRequest).response as server.protocol.Diagnostic[];
|
||||
verifyNoDiagnostics(diags);
|
||||
});
|
||||
|
||||
function assertEvent(actualOutput: string, expectedEvent: protocol.Event, host: TestServerHost) {
|
||||
assert.equal(actualOutput, server.formatMessage(expectedEvent, nullLogger, Utils.byteLength, host.newLine));
|
||||
}
|
||||
|
||||
function checkErrorMessage(host: TestServerHost, eventName: "syntaxDiag" | "semanticDiag", diagnostics: protocol.DiagnosticEventBody) {
|
||||
const outputs = host.getOutput();
|
||||
assert.isTrue(outputs.length >= 1, outputs.toString());
|
||||
const event: protocol.Event = {
|
||||
seq: 0,
|
||||
type: "event",
|
||||
event: eventName,
|
||||
body: diagnostics
|
||||
};
|
||||
assertEvent(outputs[0], event, host);
|
||||
}
|
||||
|
||||
function checkCompleteEvent(host: TestServerHost, numberOfCurrentEvents: number, expectedSequenceId: number) {
|
||||
const outputs = host.getOutput();
|
||||
assert.equal(outputs.length, numberOfCurrentEvents, outputs.toString());
|
||||
const event: protocol.RequestCompletedEvent = {
|
||||
seq: 0,
|
||||
type: "event",
|
||||
event: "requestCompleted",
|
||||
body: {
|
||||
request_seq: expectedSequenceId
|
||||
}
|
||||
};
|
||||
assertEvent(outputs[numberOfCurrentEvents - 1], event, host);
|
||||
}
|
||||
|
||||
function checkProjectUpdatedInBackgroundEvent(host: TestServerHost, openFiles: string[]) {
|
||||
const outputs = host.getOutput();
|
||||
assert.equal(outputs.length, 1, outputs.toString());
|
||||
const event: protocol.ProjectsUpdatedInBackgroundEvent = {
|
||||
seq: 0,
|
||||
type: "event",
|
||||
event: "projectsUpdatedInBackground",
|
||||
body: {
|
||||
openFiles
|
||||
}
|
||||
};
|
||||
assertEvent(outputs[0], event, host);
|
||||
}
|
||||
|
||||
it("npm install @types works", () => {
|
||||
const folderPath = "/a/b/projects/temp";
|
||||
const file1: FileOrFolder = {
|
||||
path: `${folderPath}/a.ts`,
|
||||
content: 'import f = require("pad")'
|
||||
};
|
||||
const files = [file1, libFile];
|
||||
const host = createServerHost(files);
|
||||
const session = createSession(host, { canUseEvents: true });
|
||||
const service = session.getProjectService();
|
||||
session.executeCommandSeq<protocol.OpenRequest>({
|
||||
command: server.CommandNames.Open,
|
||||
arguments: {
|
||||
file: file1.path,
|
||||
fileContent: file1.content,
|
||||
scriptKindName: "TS",
|
||||
projectRootPath: folderPath
|
||||
}
|
||||
});
|
||||
checkNumberOfProjects(service, { inferredProjects: 1 });
|
||||
host.clearOutput();
|
||||
const expectedSequenceId = session.getNextSeq();
|
||||
session.executeCommandSeq<protocol.GeterrRequest>({
|
||||
command: server.CommandNames.Geterr,
|
||||
arguments: {
|
||||
delay: 0,
|
||||
files: [file1.path]
|
||||
}
|
||||
});
|
||||
|
||||
host.checkTimeoutQueueLengthAndRun(1);
|
||||
checkErrorMessage(host, "syntaxDiag", { file: file1.path, diagnostics: [] });
|
||||
host.clearOutput();
|
||||
|
||||
host.runQueuedImmediateCallbacks();
|
||||
const moduleNotFound = Diagnostics.Cannot_find_module_0;
|
||||
const startOffset = file1.content.indexOf('"') + 1;
|
||||
checkErrorMessage(host, "semanticDiag", {
|
||||
file: file1.path, diagnostics: [{
|
||||
start: { line: 1, offset: startOffset },
|
||||
end: { line: 1, offset: startOffset + '"pad"'.length },
|
||||
text: formatStringFromArgs(moduleNotFound.message, ["pad"]),
|
||||
code: moduleNotFound.code,
|
||||
category: DiagnosticCategory[moduleNotFound.category].toLowerCase()
|
||||
}]
|
||||
});
|
||||
checkCompleteEvent(host, 2, expectedSequenceId);
|
||||
host.clearOutput();
|
||||
|
||||
const padIndex: FileOrFolder = {
|
||||
path: `${folderPath}/node_modules/@types/pad/index.d.ts`,
|
||||
content: "export = pad;declare function pad(length: number, text: string, char ?: string): string;"
|
||||
};
|
||||
files.push(padIndex);
|
||||
host.reloadFS(files, { ignoreWatchInvokedWithTriggerAsFileCreate: true });
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkProjectUpdatedInBackgroundEvent(host, [file1.path]);
|
||||
host.clearOutput();
|
||||
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkErrorMessage(host, "syntaxDiag", { file: file1.path, diagnostics: [] });
|
||||
host.clearOutput();
|
||||
|
||||
host.runQueuedImmediateCallbacks();
|
||||
checkErrorMessage(host, "semanticDiag", { file: file1.path, diagnostics: [] });
|
||||
});
|
||||
});
|
||||
|
||||
describe("Configure file diagnostics events", () => {
|
||||
@@ -3893,6 +4004,96 @@ namespace ts.projectSystem {
|
||||
assert.equal(snap2.getText(0, snap2.getLength()), f1.content, "content should be equal to the content of original file");
|
||||
|
||||
});
|
||||
|
||||
it("should work when script info doesnt have any project open", () => {
|
||||
const f1 = {
|
||||
path: "/a/b/app.ts",
|
||||
content: "let x = 1"
|
||||
};
|
||||
const tmp = {
|
||||
path: "/a/b/app.tmp",
|
||||
content: "const y = 42"
|
||||
};
|
||||
const host = createServerHost([f1, tmp, libFile]);
|
||||
const session = createSession(host);
|
||||
const openContent = "let z = 1";
|
||||
// send open request
|
||||
session.executeCommandSeq(<server.protocol.OpenRequest>{
|
||||
command: server.protocol.CommandTypes.Open,
|
||||
arguments: { file: f1.path, fileContent: openContent }
|
||||
});
|
||||
|
||||
const projectService = session.getProjectService();
|
||||
checkNumberOfProjects(projectService, { inferredProjects: 1 });
|
||||
const info = projectService.getScriptInfo(f1.path);
|
||||
assert.isDefined(info);
|
||||
checkScriptInfoContents(openContent, "contents set during open request");
|
||||
|
||||
// send close request
|
||||
session.executeCommandSeq(<server.protocol.CloseRequest>{
|
||||
command: server.protocol.CommandTypes.Close,
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
checkScriptInfoAndProjects(0, f1.content, "contents of closed file");
|
||||
|
||||
// Can reload contents of the file when its not open and has no project
|
||||
// reload from temp file
|
||||
session.executeCommandSeq(<server.protocol.ReloadRequest>{
|
||||
command: server.protocol.CommandTypes.Reload,
|
||||
arguments: { file: f1.path, tmpfile: tmp.path }
|
||||
});
|
||||
checkScriptInfoAndProjects(0, tmp.content, "contents of temp file");
|
||||
|
||||
// reload from own file
|
||||
session.executeCommandSeq(<server.protocol.ReloadRequest>{
|
||||
command: server.protocol.CommandTypes.Reload,
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
checkScriptInfoAndProjects(0, f1.content, "contents of closed file");
|
||||
|
||||
// Open file again without setting its content
|
||||
session.executeCommandSeq(<server.protocol.OpenRequest>{
|
||||
command: server.protocol.CommandTypes.Open,
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
checkScriptInfoAndProjects(1, f1.content, "contents of file when opened without specifying contents");
|
||||
const snap = info.getSnapshot();
|
||||
|
||||
// send close request
|
||||
session.executeCommandSeq(<server.protocol.CloseRequest>{
|
||||
command: server.protocol.CommandTypes.Close,
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
checkScriptInfoAndProjects(0, f1.content, "contents of closed file");
|
||||
assert.strictEqual(info.getSnapshot(), snap);
|
||||
|
||||
// reload from temp file
|
||||
session.executeCommandSeq(<server.protocol.ReloadRequest>{
|
||||
command: server.protocol.CommandTypes.Reload,
|
||||
arguments: { file: f1.path, tmpfile: tmp.path }
|
||||
});
|
||||
checkScriptInfoAndProjects(0, tmp.content, "contents of temp file");
|
||||
assert.notStrictEqual(info.getSnapshot(), snap);
|
||||
|
||||
// reload from own file
|
||||
session.executeCommandSeq(<server.protocol.ReloadRequest>{
|
||||
command: server.protocol.CommandTypes.Reload,
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
checkScriptInfoAndProjects(0, f1.content, "contents of closed file");
|
||||
assert.notStrictEqual(info.getSnapshot(), snap);
|
||||
|
||||
function checkScriptInfoAndProjects(inferredProjects: number, contentsOfInfo: string, captionForContents: string) {
|
||||
checkNumberOfProjects(projectService, { inferredProjects });
|
||||
assert.strictEqual(projectService.getScriptInfo(f1.path), info);
|
||||
checkScriptInfoContents(contentsOfInfo, captionForContents);
|
||||
}
|
||||
|
||||
function checkScriptInfoContents(contentsOfInfo: string, captionForContents: string) {
|
||||
const snap = info.getSnapshot();
|
||||
assert.equal(snap.getText(0, snap.getLength()), contentsOfInfo, "content should be equal to " + captionForContents);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("Inferred projects", () => {
|
||||
@@ -4293,9 +4494,88 @@ namespace ts.projectSystem {
|
||||
checkNumberOfConfiguredProjects(service, 1);
|
||||
checkNumberOfInferredProjects(service, 0);
|
||||
});
|
||||
|
||||
it("should use projectRootPath when searching for inferred project again", () => {
|
||||
const projectDir = "/a/b/projects/project";
|
||||
const configFileLocation = `${projectDir}/src`;
|
||||
const f1 = {
|
||||
path: `${configFileLocation}/file1.ts`,
|
||||
content: ""
|
||||
};
|
||||
const configFile = {
|
||||
path: `${configFileLocation}/tsconfig.json`,
|
||||
content: "{}"
|
||||
};
|
||||
const configFile2 = {
|
||||
path: "/a/b/projects/tsconfig.json",
|
||||
content: "{}"
|
||||
};
|
||||
const host = createServerHost([f1, libFile, configFile, configFile2]);
|
||||
const service = createProjectService(host);
|
||||
service.openClientFile(f1.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, projectDir);
|
||||
checkNumberOfProjects(service, { configuredProjects: 1 });
|
||||
assert.isDefined(service.configuredProjects.get(configFile.path));
|
||||
checkWatchedFiles(host, [libFile.path, configFile.path]);
|
||||
checkWatchedDirectories(host, [], /*recursive*/ false);
|
||||
const typeRootLocations = getTypeRootsFromLocation(configFileLocation);
|
||||
checkWatchedDirectories(host, typeRootLocations.concat(configFileLocation), /*recursive*/ true);
|
||||
|
||||
// Delete config file - should create inferred project and not configured project
|
||||
host.reloadFS([f1, libFile, configFile2]);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkNumberOfProjects(service, { inferredProjects: 1 });
|
||||
checkWatchedFiles(host, [libFile.path, configFile.path, `${configFileLocation}/jsconfig.json`, `${projectDir}/tsconfig.json`, `${projectDir}/jsconfig.json`]);
|
||||
checkWatchedDirectories(host, [], /*recursive*/ false);
|
||||
checkWatchedDirectories(host, typeRootLocations, /*recursive*/ true);
|
||||
});
|
||||
|
||||
it("should use projectRootPath when searching for inferred project again 2", () => {
|
||||
const projectDir = "/a/b/projects/project";
|
||||
const configFileLocation = `${projectDir}/src`;
|
||||
const f1 = {
|
||||
path: `${configFileLocation}/file1.ts`,
|
||||
content: ""
|
||||
};
|
||||
const configFile = {
|
||||
path: `${configFileLocation}/tsconfig.json`,
|
||||
content: "{}"
|
||||
};
|
||||
const configFile2 = {
|
||||
path: "/a/b/projects/tsconfig.json",
|
||||
content: "{}"
|
||||
};
|
||||
const host = createServerHost([f1, libFile, configFile, configFile2]);
|
||||
const service = createProjectService(host, { useSingleInferredProject: true }, { useInferredProjectPerProjectRoot: true });
|
||||
service.openClientFile(f1.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, projectDir);
|
||||
checkNumberOfProjects(service, { configuredProjects: 1 });
|
||||
assert.isDefined(service.configuredProjects.get(configFile.path));
|
||||
checkWatchedFiles(host, [libFile.path, configFile.path]);
|
||||
checkWatchedDirectories(host, [], /*recursive*/ false);
|
||||
checkWatchedDirectories(host, getTypeRootsFromLocation(configFileLocation).concat(configFileLocation), /*recursive*/ true);
|
||||
|
||||
// Delete config file - should create inferred project with project root path set
|
||||
host.reloadFS([f1, libFile, configFile2]);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkNumberOfProjects(service, { inferredProjects: 1 });
|
||||
assert.equal(service.inferredProjects[0].projectRootPath, projectDir);
|
||||
checkWatchedFiles(host, [libFile.path, configFile.path, `${configFileLocation}/jsconfig.json`, `${projectDir}/tsconfig.json`, `${projectDir}/jsconfig.json`]);
|
||||
checkWatchedDirectories(host, [], /*recursive*/ false);
|
||||
checkWatchedDirectories(host, getTypeRootsFromLocation(projectDir), /*recursive*/ true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("cancellationToken", () => {
|
||||
// Disable sourcemap support for the duration of the test, as sourcemapping the errors generated during this test is slow and not something we care to test
|
||||
let oldPrepare: Function;
|
||||
before(() => {
|
||||
oldPrepare = (Error as any).prepareStackTrace;
|
||||
delete (Error as any).prepareStackTrace;
|
||||
});
|
||||
|
||||
after(() => {
|
||||
(Error as any).prepareStackTrace = oldPrepare;
|
||||
});
|
||||
|
||||
it("is attached to request", () => {
|
||||
const f1 = {
|
||||
path: "/a/b/app.ts",
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/// <reference path="harness.ts"/>
|
||||
/// <reference path="runnerbase.ts" />
|
||||
class UserCodeRunner extends RunnerBase {
|
||||
private static readonly testDir = "tests/cases/user/";
|
||||
public enumerateTestFiles() {
|
||||
return Harness.IO.getDirectories(UserCodeRunner.testDir);
|
||||
}
|
||||
|
||||
public kind(): TestRunnerKind {
|
||||
return "user";
|
||||
}
|
||||
|
||||
/** Setup the runner's tests so that they are ready to be executed by the harness
|
||||
* The first test should be a describe/it block that sets up the harness's compiler instance appropriately
|
||||
*/
|
||||
public initializeTests(): void {
|
||||
// Read in and evaluate the test list
|
||||
const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles();
|
||||
|
||||
describe(`${this.kind()} code samples`, () => {
|
||||
for (const test of testList) {
|
||||
this.runTest(test);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private runTest(directoryName: string) {
|
||||
describe(directoryName, () => {
|
||||
const cp = require("child_process");
|
||||
const path = require("path");
|
||||
|
||||
it("should build successfully", () => {
|
||||
const cwd = path.join(__dirname, "../../", UserCodeRunner.testDir, directoryName);
|
||||
const timeout = 600000; // 10 minutes
|
||||
const stdio = isWorker ? "pipe" : "inherit";
|
||||
const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio });
|
||||
if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed!`);
|
||||
Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => {
|
||||
const result = cp.spawnSync(`node`, ["../../../../built/local/tsc.js"], { cwd, timeout, shell: true });
|
||||
return `Exit Code: ${result.status}
|
||||
Standard output:
|
||||
${result.stdout.toString().replace(/\r\n/g, "\n")}
|
||||
|
||||
|
||||
Standard error:
|
||||
${result.stderr.toString().replace(/\r\n/g, "\n")}`;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,17 @@
|
||||
/// <reference path="harness.ts" />
|
||||
|
||||
namespace ts.TestFSWithWatch {
|
||||
const { content: libFileContent } = Harness.getDefaultLibraryFile(Harness.IO);
|
||||
export const libFile: FileOrFolder = {
|
||||
path: "/a/lib/lib.d.ts",
|
||||
content: libFileContent
|
||||
content: `/// <reference no-default-lib="true"/>
|
||||
interface Boolean {}
|
||||
interface Function {}
|
||||
interface IArguments {}
|
||||
interface Number { toExponential: any; }
|
||||
interface Object {}
|
||||
interface RegExp {}
|
||||
interface String { charAt: any; }
|
||||
interface Array<T> {}`
|
||||
};
|
||||
|
||||
export const safeList = {
|
||||
@@ -219,6 +226,11 @@ namespace ts.TestFSWithWatch {
|
||||
directoryName: string;
|
||||
}
|
||||
|
||||
export interface ReloadWatchInvokeOptions {
|
||||
invokeDirectoryWatcherInsteadOfFileChanged: boolean;
|
||||
ignoreWatchInvokedWithTriggerAsFileCreate: boolean;
|
||||
}
|
||||
|
||||
export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost {
|
||||
args: string[] = [];
|
||||
|
||||
@@ -263,7 +275,7 @@ namespace ts.TestFSWithWatch {
|
||||
return s;
|
||||
}
|
||||
|
||||
reloadFS(fileOrFolderList: ReadonlyArray<FileOrFolder>, invokeDirectoryWatcherInsteadOfFileChanged?: boolean) {
|
||||
reloadFS(fileOrFolderList: ReadonlyArray<FileOrFolder>, options?: Partial<ReloadWatchInvokeOptions>) {
|
||||
const mapNewLeaves = createMap<true>();
|
||||
const isNewFs = this.fs.size === 0;
|
||||
fileOrFolderList = fileOrFolderList.concat(this.withSafeList ? safeList : []);
|
||||
@@ -284,7 +296,7 @@ namespace ts.TestFSWithWatch {
|
||||
// Update file
|
||||
if (currentEntry.content !== fileOrDirectory.content) {
|
||||
currentEntry.content = fileOrDirectory.content;
|
||||
if (invokeDirectoryWatcherInsteadOfFileChanged) {
|
||||
if (options && options.invokeDirectoryWatcherInsteadOfFileChanged) {
|
||||
this.invokeDirectoryWatcher(getDirectoryPath(currentEntry.fullPath), currentEntry.fullPath);
|
||||
}
|
||||
else {
|
||||
@@ -307,7 +319,7 @@ namespace ts.TestFSWithWatch {
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.ensureFileOrFolder(fileOrDirectory);
|
||||
this.ensureFileOrFolder(fileOrDirectory, options && options.ignoreWatchInvokedWithTriggerAsFileCreate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,12 +336,12 @@ namespace ts.TestFSWithWatch {
|
||||
}
|
||||
}
|
||||
|
||||
ensureFileOrFolder(fileOrDirectory: FileOrFolder) {
|
||||
ensureFileOrFolder(fileOrDirectory: FileOrFolder, ignoreWatchInvokedWithTriggerAsFileCreate?: boolean) {
|
||||
if (isString(fileOrDirectory.content)) {
|
||||
const file = this.toFile(fileOrDirectory);
|
||||
Debug.assert(!this.fs.get(file.path));
|
||||
const baseFolder = this.ensureFolder(getDirectoryPath(file.fullPath));
|
||||
this.addFileOrFolderInFolder(baseFolder, file);
|
||||
this.addFileOrFolderInFolder(baseFolder, file, ignoreWatchInvokedWithTriggerAsFileCreate);
|
||||
}
|
||||
else {
|
||||
const fullPath = getNormalizedAbsolutePath(fileOrDirectory.path, this.currentDirectory);
|
||||
@@ -358,10 +370,13 @@ namespace ts.TestFSWithWatch {
|
||||
return folder;
|
||||
}
|
||||
|
||||
private addFileOrFolderInFolder(folder: Folder, fileOrDirectory: File | Folder) {
|
||||
private addFileOrFolderInFolder(folder: Folder, fileOrDirectory: File | Folder, ignoreWatch?: boolean) {
|
||||
folder.entries.push(fileOrDirectory);
|
||||
this.fs.set(fileOrDirectory.path, fileOrDirectory);
|
||||
|
||||
if (ignoreWatch) {
|
||||
return;
|
||||
}
|
||||
if (isFile(fileOrDirectory)) {
|
||||
this.invokeFileWatcher(fileOrDirectory.fullPath, FileWatcherEventKind.Created);
|
||||
}
|
||||
|
||||
Vendored
+779
-776
File diff suppressed because it is too large
Load Diff
Vendored
+7
-1
@@ -50,10 +50,16 @@ interface ArrayConstructor {
|
||||
/**
|
||||
* Creates an array from an array-like object.
|
||||
* @param arrayLike An array-like object to convert to an array.
|
||||
*/
|
||||
from<T>(arrayLike: ArrayLike<T>): T[];
|
||||
|
||||
/**
|
||||
* Creates an array from an iterable object.
|
||||
* @param arrayLike An array-like object to convert to an array.
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from<T, U = T>(arrayLike: ArrayLike<T>, mapfn?: (v: T, k: number) => U, thisArg?: any): U[];
|
||||
from<T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[];
|
||||
|
||||
/**
|
||||
* Returns a new array from a set of elements.
|
||||
|
||||
Vendored
+7
-1
@@ -48,13 +48,19 @@ interface Array<T> {
|
||||
}
|
||||
|
||||
interface ArrayConstructor {
|
||||
/**
|
||||
* Creates an array from an iterable object.
|
||||
* @param iterable An iterable object to convert to an array.
|
||||
*/
|
||||
from<T>(iterable: Iterable<T>): T[];
|
||||
|
||||
/**
|
||||
* Creates an array from an iterable object.
|
||||
* @param iterable An iterable object to convert to an array.
|
||||
* @param mapfn A mapping function to call on every element of the array.
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from<T, U = T>(iterable: Iterable<T>, mapfn?: (v: T, k: number) => U, thisArg?: any): U[];
|
||||
from<T, U>(iterable: Iterable<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[];
|
||||
}
|
||||
|
||||
interface ReadonlyArray<T> {
|
||||
|
||||
Vendored
+91
-87
@@ -37,7 +37,7 @@ interface IDBIndexParameters {
|
||||
|
||||
interface IDBObjectStoreParameters {
|
||||
autoIncrement?: boolean;
|
||||
keyPath?: IDBKeyPath | null;
|
||||
keyPath?: string | string[];
|
||||
}
|
||||
|
||||
interface KeyAlgorithm {
|
||||
@@ -74,7 +74,7 @@ interface RequestInit {
|
||||
body?: any;
|
||||
cache?: RequestCache;
|
||||
credentials?: RequestCredentials;
|
||||
headers?: Headers | string[][];
|
||||
headers?: HeadersInit;
|
||||
integrity?: string;
|
||||
keepalive?: boolean;
|
||||
method?: string;
|
||||
@@ -86,7 +86,7 @@ interface RequestInit {
|
||||
}
|
||||
|
||||
interface ResponseInit {
|
||||
headers?: Headers | string[][];
|
||||
headers?: HeadersInit;
|
||||
status?: number;
|
||||
statusText?: string;
|
||||
}
|
||||
@@ -441,10 +441,10 @@ interface FileReader extends EventTarget, MSBaseReader {
|
||||
readAsBinaryString(blob: Blob): void;
|
||||
readAsDataURL(blob: Blob): void;
|
||||
readAsText(blob: Blob, encoding?: string): void;
|
||||
addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var FileReader: {
|
||||
@@ -472,7 +472,7 @@ interface Headers {
|
||||
|
||||
declare var Headers: {
|
||||
prototype: Headers;
|
||||
new(init?: Headers | string[][] | object): Headers;
|
||||
new(init?: HeadersInit): Headers;
|
||||
};
|
||||
|
||||
interface IDBCursor {
|
||||
@@ -524,11 +524,12 @@ interface IDBDatabase extends EventTarget {
|
||||
createObjectStore(name: string, optionalParameters?: IDBObjectStoreParameters): IDBObjectStore;
|
||||
deleteObjectStore(name: string): void;
|
||||
transaction(storeNames: string | string[], mode?: IDBTransactionMode): IDBTransaction;
|
||||
addEventListener(type: "versionchange", listener: (ev: IDBVersionChangeEvent) => any, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener(type: "versionchange", listener: (this: IDBDatabase, ev: IDBVersionChangeEvent) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener(type: "versionchange", listener: (this: IDBDatabase, ev: IDBVersionChangeEvent) => any, options?: boolean | EventListenerOptions): void;
|
||||
addEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var IDBDatabase: {
|
||||
@@ -612,10 +613,10 @@ interface IDBOpenDBRequestEventMap extends IDBRequestEventMap {
|
||||
interface IDBOpenDBRequest extends IDBRequest {
|
||||
onblocked: (this: IDBOpenDBRequest, ev: Event) => any;
|
||||
onupgradeneeded: (this: IDBOpenDBRequest, ev: IDBVersionChangeEvent) => any;
|
||||
addEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var IDBOpenDBRequest: {
|
||||
@@ -636,10 +637,10 @@ interface IDBRequest extends EventTarget {
|
||||
readonly result: any;
|
||||
source: IDBObjectStore | IDBIndex | IDBCursor;
|
||||
readonly transaction: IDBTransaction;
|
||||
addEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var IDBRequest: {
|
||||
@@ -665,10 +666,10 @@ interface IDBTransaction extends EventTarget {
|
||||
readonly READ_ONLY: string;
|
||||
readonly READ_WRITE: string;
|
||||
readonly VERSION_CHANGE: string;
|
||||
addEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var IDBTransaction: {
|
||||
@@ -733,10 +734,10 @@ interface MessagePort extends EventTarget {
|
||||
close(): void;
|
||||
postMessage(message?: any, transfer?: any[]): void;
|
||||
start(): void;
|
||||
addEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var MessagePort: {
|
||||
@@ -764,10 +765,10 @@ interface Notification extends EventTarget {
|
||||
readonly tag: string;
|
||||
readonly title: string;
|
||||
close(): void;
|
||||
addEventListener<K extends keyof NotificationEventMap>(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof NotificationEventMap>(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof NotificationEventMap>(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof NotificationEventMap>(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var Notification: {
|
||||
@@ -994,10 +995,10 @@ interface ServiceWorker extends EventTarget, AbstractWorker {
|
||||
readonly scriptURL: USVString;
|
||||
readonly state: ServiceWorkerState;
|
||||
postMessage(message: any, transfer?: any[]): void;
|
||||
addEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var ServiceWorker: {
|
||||
@@ -1021,10 +1022,10 @@ interface ServiceWorkerRegistration extends EventTarget {
|
||||
showNotification(title: string, options?: NotificationOptions): Promise<void>;
|
||||
unregister(): Promise<boolean>;
|
||||
update(): Promise<void>;
|
||||
addEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var ServiceWorkerRegistration: {
|
||||
@@ -1089,10 +1090,10 @@ interface WebSocket extends EventTarget {
|
||||
readonly CLOSING: number;
|
||||
readonly CONNECTING: number;
|
||||
readonly OPEN: number;
|
||||
addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var WebSocket: {
|
||||
@@ -1112,10 +1113,10 @@ interface Worker extends EventTarget, AbstractWorker {
|
||||
onmessage: (this: Worker, ev: MessageEvent) => any;
|
||||
postMessage(message: any, transfer?: any[]): void;
|
||||
terminate(): void;
|
||||
addEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var Worker: {
|
||||
@@ -1155,10 +1156,10 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
|
||||
readonly LOADING: number;
|
||||
readonly OPENED: number;
|
||||
readonly UNSENT: number;
|
||||
addEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var XMLHttpRequest: {
|
||||
@@ -1172,10 +1173,10 @@ declare var XMLHttpRequest: {
|
||||
};
|
||||
|
||||
interface XMLHttpRequestUpload extends EventTarget, XMLHttpRequestEventTarget {
|
||||
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var XMLHttpRequestUpload: {
|
||||
@@ -1189,10 +1190,10 @@ interface AbstractWorkerEventMap {
|
||||
|
||||
interface AbstractWorker {
|
||||
onerror: (this: AbstractWorker, ev: ErrorEvent) => any;
|
||||
addEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
interface Body {
|
||||
@@ -1229,10 +1230,10 @@ interface MSBaseReader {
|
||||
readonly DONE: number;
|
||||
readonly EMPTY: number;
|
||||
readonly LOADING: number;
|
||||
addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
interface NavigatorBeacon {
|
||||
@@ -1286,10 +1287,10 @@ interface XMLHttpRequestEventTarget {
|
||||
onloadstart: (this: XMLHttpRequest, ev: Event) => any;
|
||||
onprogress: (this: XMLHttpRequest, ev: ProgressEvent) => any;
|
||||
ontimeout: (this: XMLHttpRequest, ev: ProgressEvent) => any;
|
||||
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
interface Client {
|
||||
@@ -1324,10 +1325,10 @@ interface DedicatedWorkerGlobalScope extends WorkerGlobalScope {
|
||||
onmessage: (this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any;
|
||||
close(): void;
|
||||
postMessage(message: any, transfer?: any[]): void;
|
||||
addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var DedicatedWorkerGlobalScope: {
|
||||
@@ -1437,10 +1438,10 @@ interface ServiceWorkerGlobalScope extends WorkerGlobalScope {
|
||||
onsync: (this: ServiceWorkerGlobalScope, ev: SyncEvent) => any;
|
||||
readonly registration: ServiceWorkerRegistration;
|
||||
skipWaiting(): Promise<void>;
|
||||
addEventListener<K extends keyof ServiceWorkerGlobalScopeEventMap>(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof ServiceWorkerGlobalScopeEventMap>(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof ServiceWorkerGlobalScopeEventMap>(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof ServiceWorkerGlobalScopeEventMap>(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var ServiceWorkerGlobalScope: {
|
||||
@@ -1484,10 +1485,10 @@ interface WorkerGlobalScope extends EventTarget, WorkerUtils, WindowConsole, Glo
|
||||
msWriteProfilerMark(profilerMarkName: string): void;
|
||||
createImageBitmap(image: ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise<ImageBitmap>;
|
||||
createImageBitmap(image: ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
|
||||
addEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var WorkerGlobalScope: {
|
||||
@@ -1544,8 +1545,10 @@ interface BroadcastChannel extends EventTarget {
|
||||
onmessageerror: (ev: MessageEvent) => any;
|
||||
close(): void;
|
||||
postMessage(message: any): void;
|
||||
addEventListener<K extends keyof BroadcastChannelEventMap>(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof BroadcastChannelEventMap>(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
removeEventListener<K extends keyof BroadcastChannelEventMap>(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
}
|
||||
|
||||
declare var BroadcastChannel: {
|
||||
@@ -1875,10 +1878,10 @@ declare function btoa(rawString: string): string;
|
||||
declare var console: Console;
|
||||
declare function fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
||||
declare function dispatchEvent(evt: Event): boolean;
|
||||
declare function addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
declare function removeEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
declare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
declare function addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
declare function removeEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
||||
declare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
type AlgorithmIdentifier = string | Algorithm;
|
||||
type BodyInit = any;
|
||||
type IDBKeyPath = string;
|
||||
@@ -1887,6 +1890,7 @@ type USVString = string;
|
||||
type IDBValidKey = number | string | Date | IDBArrayKey;
|
||||
type BufferSource = ArrayBuffer | ArrayBufferView;
|
||||
type FormDataEntryValue = string | File;
|
||||
type HeadersInit = string[][] | { [key: string]: string };
|
||||
type IDBCursorDirection = "next" | "nextunique" | "prev" | "prevunique";
|
||||
type IDBRequestReadyState = "pending" | "done";
|
||||
type IDBTransactionMode = "readonly" | "readwrite" | "versionchange";
|
||||
|
||||
@@ -830,12 +830,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[将 {0} 从 {1} 添加到现有导入声明。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2898,6 +2898,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[应为 {0}-{1} 类型参数;请为这些参数添加 "@extends" 标记。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2925,6 +2934,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[应为 {0} 类型参数;请为这些参数添加 "@extends" 标记。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3680,12 +3698,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[从 {1} 导入 {0}。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6366,11 +6384,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[后续变量声明必须属于同一类型。变量“{0}”必须属于类型“{1}”,但此处却为类型“{2}”。]]></Val>
|
||||
<Val><![CDATA[后续变量声明必须属于同一类型。变量 "{0}" 在“{2}”中必须为类型“{1}”,但此处却为类型“{3}”。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -830,12 +830,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[從 {1} 將 {0} 新增至現有的匯入宣告。]]></Val>
|
||||
<Val><![CDATA[從 "{1}" 將 '{0}' 新增至現有的匯入宣告。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2898,6 +2898,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[必須是 {0}-{1} 型別引數; 請提供有 '@ extends' 標記的這類型引數。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2925,6 +2934,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[必須是 {0} 型別引數; 請提供有 '@ extends' 標記的這類引數。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3680,12 +3698,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[將 {0} 從 {1} 匯入。]]></Val>
|
||||
<Val><![CDATA[從 "{1}" 匯入 '{0}'。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6366,11 +6384,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[後續的變數宣告必須具有相同的類型。變數 '{0}' 的類型必須是 '{1}' 但卻是 '{2}'。]]></Val>
|
||||
<Val><![CDATA[後續的變數宣告必須具有相同的類型。變數 '{0}' 必須在 {2} 有類型 '{1}' 但卻是 '{3}'。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -839,12 +839,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Přidat {0} k existující deklaraci importu z {1}]]></Val>
|
||||
<Val><![CDATA[Přidá {0} k existující deklaraci importu z {1}.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2907,6 +2907,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Očekávané argumenty typu {0}–{1}; zadejte je se značkou @extends.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2934,6 +2943,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Očekávané argumenty typu {0}; zadejte je se značkou @extends.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3689,12 +3707,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Importovat {0} z {1}]]></Val>
|
||||
<Val><![CDATA[Importujte {0} z: {1}.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6375,11 +6393,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Deklarace následných proměnných musí obsahovat stejný typ. Proměnná {0} musí být typu {1}, ale tady je typu {2}.]]></Val>
|
||||
<Val><![CDATA[Deklarace následných proměnných musí obsahovat stejný typ. Proměnná {0} musí být typu {1} v {2}, ale tady je typu {3}.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -827,10 +827,13 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA["{0}" zur vorhandenen Importdeklaration aus "{1}" hinzufügen.]]></Val>
|
||||
<Val><![CDATA[Fügen Sie "{0}" zur vorhandenen Importdeklaration aus "{1}" hinzu.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -2886,6 +2889,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0}-{1} Typargumente erwartet; geben Sie diese mit einem @extends-Tag an.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2913,6 +2925,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0} Typargumente erwartet; geben Sie diese mit einem @extends-Tag an.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2940,6 +2961,12 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_corresponding_closing_tag_for_JSX_fragment_17015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected corresponding closing tag for JSX fragment.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_type_of_0_field_in_package_json_to_be_string_got_1_6105" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected type of '{0}' field in 'package.json' to be 'string', got '{1}'.]]></Val>
|
||||
@@ -3163,7 +3190,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1}]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Nach {0} in {1} extrahieren]]></Val>
|
||||
<Val><![CDATA[Als {0} nach {1} extrahieren]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3172,7 +3199,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in {1} scope]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Nach {0} in {1}-Bereich extrahieren]]></Val>
|
||||
<Val><![CDATA[Als {0} in {1}-Bereich extrahieren]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3181,7 +3208,7 @@
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Extract to {0} in enclosing scope]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Nach {0} in einschließenden Bereich extrahieren]]></Val>
|
||||
<Val><![CDATA[Als {0} in einschließenden Bereich extrahieren]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3665,10 +3692,13 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA["{0}" aus "{1}" importieren.]]></Val>
|
||||
<Val><![CDATA[Importieren Sie "{0}" aus "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -4176,6 +4206,18 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSX_fragment_has_no_corresponding_closing_tag_17014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSX fragment has no corresponding closing tag.]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSX_fragment_is_not_supported_when_using_jsxFactory_17016" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSX fragment is not supported when using --jsxFactory]]></Val>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSX_spread_child_must_be_an_array_type_2609" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSX spread child must be an array type.]]></Val>
|
||||
@@ -6339,11 +6381,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Nachfolgende Variablendeklarationen müssen den gleichen Typ aufweisen. Die Variable "{0}" muss den Typ "{1}" aufweisen, ist hier aber vom Typ "{2}".]]></Val>
|
||||
<Val><![CDATA[Nachfolgende Variablendeklarationen müssen den gleichen Typ aufweisen. Die Variable "{0}" muss bei "{2}" den Typ "{1}" aufweisen, ist hier aber vom Typ "{3}".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -839,12 +839,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Agrega {0} a una declaración de importación existente desde {1}.]]></Val>
|
||||
<Val><![CDATA[Agregue "{0}" a una declaración de importación existente desde "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2907,6 +2907,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Se esperaban argumentos de tipo {0}-{1}; proporciónelos con una etiqueta "@extends".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2934,6 +2943,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Se esperaban argumentos de tipo {0}; proporciónelos con una etiqueta "@extends".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3689,12 +3707,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Importa {0} desde {1}.]]></Val>
|
||||
<Val><![CDATA[Importe "{0}" desde "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6375,11 +6393,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Las declaraciones de variable subsiguientes deben tener el mismo tipo. La variable '{0}' debe ser de tipo '{1}', pero aquí tiene el tipo '{2}'.]]></Val>
|
||||
<Val><![CDATA[Las declaraciones de variable subsiguientes deben tener el mismo tipo. La variable "{0}" tiene el tipo "{1}" en {2}, pero aquí tiene el tipo "{3}".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -839,12 +839,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ajoutez {0} à une déclaration d'importation existante à partir de {1}.]]></Val>
|
||||
<Val><![CDATA[Ajoutez '{0}' à une déclaration d'importation existante à partir de "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2907,6 +2907,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Arguments de type {0}-{1} attendus ; indiquez-les avec la balise '@extends'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2934,6 +2943,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Arguments de type {0} attendus ; indiquez-les avec la balise '@extends'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3689,12 +3707,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Importez {0} à partir de {1}.]]></Val>
|
||||
<Val><![CDATA[Importez '{0}' à partir de "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6375,11 +6393,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Les déclarations de variable ultérieures doivent avoir le même type. La variable '{0}' doit être de type '{1}', mais elle a ici le type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Les déclarations de variables ultérieures doivent avoir le même type. La variable '{0}' a le type '{1}' au niveau de {2}, mais ici elle a le type '{3}'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -830,12 +830,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Aggiungi {0} alla dichiarazione di importazione esistente da {1}.]]></Val>
|
||||
<Val><![CDATA[Aggiungere '{0}' alla dichiarazione di importazione esistente da "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2898,6 +2898,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Sono previsti argomento tipo {0}-{1}. Per specificarli, usare un tag '@extends'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2925,6 +2934,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Sono previsti argomento tipo {0}. Per specificarli, usare un tag '@extends'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3680,12 +3698,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Importa {0} da {1}.]]></Val>
|
||||
<Val><![CDATA[Importare '{0}' da "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6366,11 +6384,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Le dichiarazioni di variabili successive devono essere dello stesso tipo. La variabile '{0}' deve essere di tipo '{1}', mentre è di tipo '{2}'.]]></Val>
|
||||
<Val><![CDATA[Le dichiarazioni di variabili successive devono essere dello stesso tipo. La variabile '{0}' è di tipo '{1}' alla posizione {2}, ma qui è di tipo '{3}'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -830,12 +830,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{1} から既存のインポート宣言に {0} を追加します。]]></Val>
|
||||
<Val><![CDATA["{1}" から既存のインポート宣言に '{0}' を追加します。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2898,6 +2898,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0}-{1} 型の引数が必要です。'@extends' タグで指定してください。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2925,6 +2934,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0} 型の引数が必要です。'@extends' タグで指定してください。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3680,12 +3698,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{1} から {0} をインポートします。]]></Val>
|
||||
<Val><![CDATA["{1}" から '{0}' をインポートします。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6366,11 +6384,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[後続の変数宣言は同じ型でなければなりません。変数 '{0}' の型は '{1}' である必要がありますが、'{2}' になっています。]]></Val>
|
||||
<Val><![CDATA[後続の変数宣言は同じ型でなければなりません。変数 '{0}' の型は {2} では '{1}' ですが、ここでは型が '{3}' になっています。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -830,12 +830,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{1}에서 기존 가져오기 선언에 {0}을(를) 추가합니다.]]></Val>
|
||||
<Val><![CDATA["{1}"에서 기존 가져오기 선언에 '{0}'을(를) 추가합니다.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2898,6 +2898,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['@extends' 태그로 제공하는 예상되는 {0}-{1} 형식 인수입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2925,6 +2934,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['@extends' 태그로 제공하는 예상되는 {0} 형식 인수입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3680,12 +3698,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{1}에서 {0}을(를) 가져옵니다.]]></Val>
|
||||
<Val><![CDATA["{1}"에서 '{0}'을(를) 가져옵니다.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6366,11 +6384,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[후속 변수 선언에 같은 형식이 있어야 합니다. '{0}' 변수가 '{1}' 형식이어야 하는데 여기에는 '{2}' 형식이 있습니다.]]></Val>
|
||||
<Val><![CDATA[후속 변수 선언에 같은 형식이 있어야 합니다. '{0}' 변수가 {2}에서 '{1}' 형식이어야 하는데 여기에는 '{3}' 형식이 있습니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -820,10 +820,13 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Dodaj element {0} do istniejącej deklaracji importu z {1}.]]></Val>
|
||||
<Val><![CDATA[Dodaj element „{0}” do istniejącej deklaracji importu z elementu „{1}”.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -2879,6 +2882,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Oczekiwano argumentów typu {0}-{1}; podaj je z tagiem „@extends”.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2906,6 +2918,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Oczekiwano argumentów typu {0}; podaj je z tagiem „@extends”.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3658,10 +3679,13 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Importuj {0} z {1}.]]></Val>
|
||||
<Val><![CDATA[Importuj element „{0}” z elementu „{1}”.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -6332,11 +6356,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Kolejne deklaracje zmiennej muszą być tego samego typu. Zmienna „{0}” musi być typu „{1}”, ale w tym miejscu jest typu „{2}”.]]></Val>
|
||||
<Val><![CDATA[Kolejne deklaracje zmiennej muszą być tego samego typu. Zmienna „{0}” musi być typu „{1}” w {2} , ale w tym miejscu jest typu „{3}”.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -820,10 +820,13 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Adicionar {0} à declaração de importação existente de {1}.]]></Val>
|
||||
<Val><![CDATA[Adicione "{0}" à declaração de importação existente de "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -2879,6 +2882,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Espera-se {0}-{1} argumentos de tipo; forneça esses recursos com uma marca "@extends".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2906,6 +2918,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Espera-se {0} argumentos de tipo; forneça esses recursos com uma marca "@extends".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3658,10 +3679,13 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Importar {0} de {1}.]]></Val>
|
||||
<Val><![CDATA[Importar "{0}" de "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -6332,11 +6356,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Declarações de variável subsequentes devem ter o mesmo tipo. A variável '{0}' deve ser do tipo '{1}', mas aqui tem o tipo '{2}'.]]></Val>
|
||||
<Val><![CDATA[Declarações de variável subsequentes devem ter o mesmo tipo. A variável "{0}" deve ser do tipo "{1}" em {2}, mas aqui tem o tipo "{3}".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -829,12 +829,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Добавьте {0} в существующее объявление импорта из {1}.]]></Val>
|
||||
<Val><![CDATA[Добавьте "{0}" в существующее объявление импорта из "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2897,6 +2897,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ожидается аргументов типа: {0}–{1}. Укажите их с тегом "@extends".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2924,6 +2933,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ожидается аргументов типа: {0}. Укажите их с тегом "@extends".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3679,12 +3697,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Импортируйте {0} из {1}.]]></Val>
|
||||
<Val><![CDATA[Импортируйте "{0}" из "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6365,11 +6383,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Последующие объявления переменных должны иметь тот же тип. Переменная "{0}" должна иметь тип "{1}", однако имеет тип "{2}".]]></Val>
|
||||
<Val><![CDATA[Последующие объявления переменных должны иметь тот же тип. Переменная "{0}" должна иметь тип "{1}" в {2}, но имеет тип "{3}".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
@@ -823,12 +823,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0} öğesini {1} konumundaki mevcut içeri aktarma bildirimine ekleyin.]]></Val>
|
||||
<Val><![CDATA['{0}' öğesini "{1}" konumundaki mevcut içeri aktarma bildirimine ekleyin.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2891,6 +2891,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0}-{1} türünde bağımsız değişkenler bekleniyordu; bunları bir '@extends' etiketiyle sağlayın.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2918,6 +2927,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0} türünde bağımsız değişkenler bekleniyordu; bunları bir '@extends' etiketiyle sağlayın.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3673,12 +3691,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0} öğesini {1} kaynağından içeri aktarın.]]></Val>
|
||||
<Val><![CDATA['{0}' öğesini "{1}" kaynağından içeri aktarın.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6359,11 +6377,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ardışık değişken bildirimleri aynı türe sahip olmalıdır. '{0}' değişkeni '{1}' türünde olmalıdır, ancak burada '{2}' türüne sahip.]]></Val>
|
||||
<Val><![CDATA[Ardışık değişken bildirimleri aynı türe sahip olmalıdır. '{0}' değişkeni {2} konumunda '{1}' türüne sahip olmasına rağmen burada '{3}' türüne sahip.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
|
||||
+24
-5
@@ -170,8 +170,8 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
getCompletionsAtPosition(fileName: string, position: number): CompletionInfo {
|
||||
const args: protocol.CompletionsRequestArgs = this.createFileLocationRequestArgs(fileName, position);
|
||||
getCompletionsAtPosition(fileName: string, position: number, options: GetCompletionsAtPositionOptions | undefined): CompletionInfo {
|
||||
const args: protocol.CompletionsRequestArgs = { ...this.createFileLocationRequestArgs(fileName, position), ...options };
|
||||
|
||||
const request = this.processRequest<protocol.CompletionsRequest>(CommandNames.Completions, args);
|
||||
const response = this.processResponse<protocol.CompletionsResponse>(request);
|
||||
@@ -192,8 +192,8 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
getCompletionEntryDetails(fileName: string, position: number, entryName: string): CompletionEntryDetails {
|
||||
const args: protocol.CompletionDetailsRequestArgs = { ...this.createFileLocationRequestArgs(fileName, position), entryNames: [entryName] };
|
||||
getCompletionEntryDetails(fileName: string, position: number, entryName: string, _options: FormatCodeOptions | FormatCodeSettings | undefined, source: string | undefined): CompletionEntryDetails {
|
||||
const args: protocol.CompletionDetailsRequestArgs = { ...this.createFileLocationRequestArgs(fileName, position), entryNames: [{ name: entryName, source }] };
|
||||
|
||||
const request = this.processRequest<protocol.CompletionDetailsRequest>(CommandNames.CompletionDetails, args);
|
||||
const response = this.processResponse<protocol.CompletionDetailsResponse>(request);
|
||||
@@ -270,6 +270,25 @@ namespace ts.server {
|
||||
}));
|
||||
}
|
||||
|
||||
getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan {
|
||||
const args: protocol.FileLocationRequestArgs = this.createFileLocationRequestArgs(fileName, position);
|
||||
|
||||
const request = this.processRequest<protocol.DefinitionRequest>(CommandNames.DefinitionAndBoundSpan, args);
|
||||
const response = this.processResponse<protocol.DefinitionInfoAndBoundSpanReponse>(request);
|
||||
|
||||
return {
|
||||
definitions: response.body.definitions.map(entry => ({
|
||||
containerKind: ScriptElementKind.unknown,
|
||||
containerName: "",
|
||||
fileName: entry.file,
|
||||
textSpan: this.decodeSpan(entry),
|
||||
kind: ScriptElementKind.unknown,
|
||||
name: ""
|
||||
})),
|
||||
textSpan: this.decodeSpan(response.body.textSpan, request.arguments.file)
|
||||
};
|
||||
}
|
||||
|
||||
getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] {
|
||||
const args: protocol.FileLocationRequestArgs = this.createFileLocationRequestArgs(fileName, position);
|
||||
|
||||
@@ -324,7 +343,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
getSyntacticDiagnostics(file: string): Diagnostic[] {
|
||||
const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file, includeLinePosition: true };
|
||||
const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file, includeLinePosition: true };
|
||||
|
||||
const request = this.processRequest<protocol.SyntacticDiagnosticsSyncRequest>(CommandNames.SyntacticDiagnosticsSync, args);
|
||||
const response = this.processResponse<protocol.SyntacticDiagnosticsSyncResponse>(request);
|
||||
|
||||
@@ -78,9 +78,7 @@ namespace ts.server {
|
||||
|
||||
export type ProjectServiceEvent = ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent;
|
||||
|
||||
export interface ProjectServiceEventHandler {
|
||||
(event: ProjectServiceEvent): void;
|
||||
}
|
||||
export type ProjectServiceEventHandler = (event: ProjectServiceEvent) => void;
|
||||
|
||||
export interface SafeList {
|
||||
[name: string]: { match: RegExp, exclude?: (string | number)[][], types?: string[] };
|
||||
@@ -354,9 +352,9 @@ namespace ts.server {
|
||||
*/
|
||||
readonly configuredProjects = createMap<ConfiguredProject>();
|
||||
/**
|
||||
* list of open files
|
||||
* Open files: with value being project root path, and key being Path of the file that is open
|
||||
*/
|
||||
readonly openFiles: ScriptInfo[] = [];
|
||||
readonly openFiles = createMap<NormalizedPath>();
|
||||
|
||||
private compilerOptionsForInferredProjects: CompilerOptions;
|
||||
private compilerOptionsForInferredProjectsPerProjectRoot = createMap<CompilerOptions>();
|
||||
@@ -584,7 +582,7 @@ namespace ts.server {
|
||||
const event: ProjectsUpdatedInBackgroundEvent = {
|
||||
eventName: ProjectsUpdatedInBackgroundEvent,
|
||||
data: {
|
||||
openFiles: this.openFiles.map(f => f.fileName)
|
||||
openFiles: arrayFrom(this.openFiles.keys(), path => this.getScriptInfoForPath(path as Path).fileName)
|
||||
}
|
||||
};
|
||||
this.eventHandler(event);
|
||||
@@ -893,7 +891,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
assignOrphanScriptInfoToInferredProject(info: ScriptInfo, projectRootPath?: string) {
|
||||
assignOrphanScriptInfoToInferredProject(info: ScriptInfo, projectRootPath: NormalizedPath | undefined) {
|
||||
Debug.assert(info.isOrphan());
|
||||
|
||||
const project = this.getOrCreateInferredProjectForProjectRootPathIfEnabled(info, projectRootPath) ||
|
||||
@@ -937,7 +935,7 @@ namespace ts.server {
|
||||
info.close();
|
||||
this.stopWatchingConfigFilesForClosedScriptInfo(info);
|
||||
|
||||
unorderedRemoveItem(this.openFiles, info);
|
||||
this.openFiles.delete(info.path);
|
||||
|
||||
const fileExists = this.host.fileExists(info.fileName);
|
||||
|
||||
@@ -976,11 +974,12 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
// collect orphaned files and assign them to inferred project just like we treat open of a file
|
||||
for (const f of this.openFiles) {
|
||||
this.openFiles.forEach((projectRootPath, path) => {
|
||||
const f = this.getScriptInfoForPath(path as Path);
|
||||
if (f.isOrphan()) {
|
||||
this.assignOrphanScriptInfoToInferredProject(f);
|
||||
this.assignOrphanScriptInfoToInferredProject(f, projectRootPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Cleanup script infos that arent part of any project (eg. those could be closed script infos not referenced by any project)
|
||||
// is postponed to next file open so that if file from same project is opened,
|
||||
@@ -1174,7 +1173,7 @@ namespace ts.server {
|
||||
* This is called by inferred project whenever script info is added as a root
|
||||
*/
|
||||
/* @internal */
|
||||
startWatchingConfigFilesForInferredProjectRoot(info: ScriptInfo) {
|
||||
startWatchingConfigFilesForInferredProjectRoot(info: ScriptInfo, projectRootPath: NormalizedPath | undefined) {
|
||||
Debug.assert(info.isScriptOpen());
|
||||
this.forEachConfigFileLocation(info, (configFileName, canonicalConfigFilePath) => {
|
||||
let configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
|
||||
@@ -1196,7 +1195,7 @@ namespace ts.server {
|
||||
!this.getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath)) {
|
||||
this.createConfigFileWatcherOfConfigFileExistence(configFileName, canonicalConfigFilePath, configFileExistenceInfo);
|
||||
}
|
||||
});
|
||||
}, projectRootPath);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1264,7 +1263,7 @@ namespace ts.server {
|
||||
* The server must start searching from the directory containing
|
||||
* the newly opened file.
|
||||
*/
|
||||
private getConfigFileNameForFile(info: ScriptInfo, projectRootPath?: NormalizedPath) {
|
||||
private getConfigFileNameForFile(info: ScriptInfo, projectRootPath: NormalizedPath | undefined) {
|
||||
Debug.assert(info.isScriptOpen());
|
||||
this.logger.info(`Search path: ${getDirectoryPath(info.fileName)}`);
|
||||
const configFileName = this.forEachConfigFileLocation(info,
|
||||
@@ -1303,9 +1302,9 @@ namespace ts.server {
|
||||
printProjects(this.inferredProjects, counter);
|
||||
|
||||
this.logger.info("Open files: ");
|
||||
for (const rootFile of this.openFiles) {
|
||||
this.logger.info(`\t${rootFile.fileName}`);
|
||||
}
|
||||
this.openFiles.forEach((projectRootPath, path) => {
|
||||
this.logger.info(`\tFileName: ${this.getScriptInfoForPath(path as Path).fileName} ProjectRootPath: ${projectRootPath}`);
|
||||
});
|
||||
|
||||
this.logger.endGroup();
|
||||
}
|
||||
@@ -1374,24 +1373,42 @@ namespace ts.server {
|
||||
this.projectToSizeMap.forEach(val => (availableSpace -= (val || 0)));
|
||||
|
||||
let totalNonTsFileSize = 0;
|
||||
|
||||
for (const f of fileNames) {
|
||||
const fileName = propertyReader.getFileName(f);
|
||||
if (hasTypeScriptFileExtension(fileName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
totalNonTsFileSize += this.host.getFileSize(fileName);
|
||||
|
||||
if (totalNonTsFileSize > maxProgramSizeForNonTsFiles) {
|
||||
this.logger.info(getExceedLimitMessage({ propertyReader, hasTypeScriptFileExtension, host: this.host }, totalNonTsFileSize));
|
||||
// Keep the size as zero since it's disabled
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (totalNonTsFileSize > availableSpace) {
|
||||
this.logger.info(getExceedLimitMessage({ propertyReader, hasTypeScriptFileExtension, host: this.host }, totalNonTsFileSize));
|
||||
return true;
|
||||
}
|
||||
|
||||
this.projectToSizeMap.set(name, totalNonTsFileSize);
|
||||
return false;
|
||||
|
||||
function getExceedLimitMessage(context: { propertyReader: FilePropertyReader<any>, hasTypeScriptFileExtension: (filename: string) => boolean, host: ServerHost }, totalNonTsFileSize: number) {
|
||||
const files = getTop5LargestFiles(context);
|
||||
|
||||
return `Non TS file size exceeded limit (${totalNonTsFileSize}). Largest files: ${files.map(file => `${file.name}:${file.size}`).join(", ")}`;
|
||||
}
|
||||
function getTop5LargestFiles({ propertyReader, hasTypeScriptFileExtension, host }: { propertyReader: FilePropertyReader<any>, hasTypeScriptFileExtension: (filename: string) => boolean, host: ServerHost }) {
|
||||
return fileNames.map(f => propertyReader.getFileName(f))
|
||||
.filter(name => hasTypeScriptFileExtension(name))
|
||||
.map(name => ({ name, size: host.getFileSize(name) }))
|
||||
.sort((a, b) => b.size - a.size)
|
||||
.slice(0, 5);
|
||||
}
|
||||
}
|
||||
|
||||
private createExternalProject(projectFileName: string, files: protocol.ExternalFile[], options: protocol.ExternalProjectCompilerOptions, typeAcquisition: TypeAcquisition) {
|
||||
@@ -1607,7 +1624,7 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
private getOrCreateInferredProjectForProjectRootPathIfEnabled(info: ScriptInfo, projectRootPath: string | undefined): InferredProject | undefined {
|
||||
private getOrCreateInferredProjectForProjectRootPathIfEnabled(info: ScriptInfo, projectRootPath: NormalizedPath | undefined): InferredProject | undefined {
|
||||
if (!this.useInferredProjectPerProjectRoot) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -1661,7 +1678,7 @@ namespace ts.server {
|
||||
return this.createInferredProject(/*currentDirectory*/ undefined, /*isSingleInferredProject*/ true);
|
||||
}
|
||||
|
||||
private createInferredProject(currentDirectory: string | undefined, isSingleInferredProject?: boolean, projectRootPath?: string): InferredProject {
|
||||
private createInferredProject(currentDirectory: string | undefined, isSingleInferredProject?: boolean, projectRootPath?: NormalizedPath): InferredProject {
|
||||
const compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects;
|
||||
const project = new InferredProject(this, this.documentRegistry, compilerOptions, projectRootPath, currentDirectory);
|
||||
if (isSingleInferredProject) {
|
||||
@@ -1798,23 +1815,19 @@ namespace ts.server {
|
||||
// as there is no need to load contents of the files from the disk
|
||||
|
||||
// Reload Projects
|
||||
this.reloadConfiguredProjectForFiles(this.openFiles, /*delayReload*/ false);
|
||||
this.reloadConfiguredProjectForFiles(this.openFiles, /*delayReload*/ false, returnTrue);
|
||||
this.refreshInferredProjects();
|
||||
}
|
||||
|
||||
private delayReloadConfiguredProjectForFiles(configFileExistenceInfo: ConfigFileExistenceInfo, ignoreIfNotRootOfInferredProject: boolean) {
|
||||
// Get open files to reload projects for
|
||||
const openFiles = mapDefinedIter(
|
||||
configFileExistenceInfo.openFilesImpactedByConfigFile.entries(),
|
||||
([path, isRootOfInferredProject]) => {
|
||||
if (!ignoreIfNotRootOfInferredProject || isRootOfInferredProject) {
|
||||
const info = this.getScriptInfoForPath(path as Path);
|
||||
Debug.assert(!!info);
|
||||
return info;
|
||||
}
|
||||
}
|
||||
this.reloadConfiguredProjectForFiles(
|
||||
configFileExistenceInfo.openFilesImpactedByConfigFile,
|
||||
/*delayReload*/ true,
|
||||
ignoreIfNotRootOfInferredProject ?
|
||||
isRootOfInferredProject => isRootOfInferredProject : // Reload open files if they are root of inferred project
|
||||
returnTrue // Reload all the open files impacted by config file
|
||||
);
|
||||
this.reloadConfiguredProjectForFiles(openFiles, /*delayReload*/ true);
|
||||
this.delayInferredProjectsRefresh();
|
||||
}
|
||||
|
||||
@@ -1823,16 +1836,24 @@ namespace ts.server {
|
||||
* If the config file is found and it refers to existing project, it reloads it either immediately
|
||||
* or schedules it for reload depending on delayReload option
|
||||
* If the there is no existing project it just opens the configured project for the config file
|
||||
* reloadForInfo provides a way to filter out files to reload configured project for
|
||||
*/
|
||||
private reloadConfiguredProjectForFiles(openFiles: ReadonlyArray<ScriptInfo>, delayReload: boolean) {
|
||||
private reloadConfiguredProjectForFiles<T>(openFiles: Map<T>, delayReload: boolean, shouldReloadProjectFor: (openFileValue: T) => boolean) {
|
||||
const updatedProjects = createMap<true>();
|
||||
// try to reload config file for all open files
|
||||
for (const info of openFiles) {
|
||||
openFiles.forEach((openFileValue, path) => {
|
||||
// Filter out the files that need to be ignored
|
||||
if (!shouldReloadProjectFor(openFileValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const info = this.getScriptInfoForPath(path as Path);
|
||||
Debug.assert(info.isScriptOpen());
|
||||
// This tries to search for a tsconfig.json for the given file. If we found it,
|
||||
// we first detect if there is already a configured project created for it: if so,
|
||||
// we re- read the tsconfig file content and update the project only if we havent already done so
|
||||
// otherwise we create a new one.
|
||||
const configFileName = this.getConfigFileNameForFile(info);
|
||||
const configFileName = this.getConfigFileNameForFile(info, this.openFiles.get(path));
|
||||
if (configFileName) {
|
||||
const project = this.findConfiguredProjectByProjectName(configFileName);
|
||||
if (!project) {
|
||||
@@ -1850,7 +1871,7 @@ namespace ts.server {
|
||||
updatedProjects.set(configFileName, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1895,16 +1916,17 @@ namespace ts.server {
|
||||
this.logger.info("refreshInferredProjects: updating project structure from ...");
|
||||
this.printProjects();
|
||||
|
||||
for (const info of this.openFiles) {
|
||||
this.openFiles.forEach((projectRootPath, path) => {
|
||||
const info = this.getScriptInfoForPath(path as Path);
|
||||
// collect all orphaned script infos from open files
|
||||
if (info.isOrphan()) {
|
||||
this.assignOrphanScriptInfoToInferredProject(info);
|
||||
this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
|
||||
}
|
||||
else {
|
||||
// Or remove the root of inferred project if is referenced in more than one projects
|
||||
this.removeRootOfInferredProjectIfNowPartOfOtherProject(info);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (const p of this.inferredProjects) {
|
||||
p.updateGraph();
|
||||
@@ -1958,7 +1980,7 @@ namespace ts.server {
|
||||
this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
|
||||
}
|
||||
Debug.assert(!info.isOrphan());
|
||||
this.openFiles.push(info);
|
||||
this.openFiles.set(info.path, projectRootPath);
|
||||
|
||||
if (sendConfigFileDiagEvent) {
|
||||
configFileErrors = project.getAllProjectErrors();
|
||||
|
||||
+4
-15
@@ -98,9 +98,7 @@ namespace ts.server {
|
||||
getExternalFiles?(proj: Project): string[];
|
||||
}
|
||||
|
||||
export interface PluginModuleFactory {
|
||||
(mod: { typescript: typeof ts }): PluginModule;
|
||||
}
|
||||
export type PluginModuleFactory = (mod: { typescript: typeof ts }) => PluginModule;
|
||||
|
||||
/**
|
||||
* The project root can be script info - if root is present,
|
||||
@@ -947,16 +945,6 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
reloadScript(filename: NormalizedPath, tempFileName?: NormalizedPath): boolean {
|
||||
const script = this.projectService.getScriptInfoForNormalizedPath(filename);
|
||||
if (script) {
|
||||
Debug.assert(script.isAttached(this));
|
||||
script.reloadFromFile(tempFileName);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
getChangesSinceVersion(lastKnownVersion?: number): ProjectFilesWithTSDiagnostics {
|
||||
this.updateGraph();
|
||||
@@ -1065,7 +1053,7 @@ namespace ts.server {
|
||||
projectService: ProjectService,
|
||||
documentRegistry: DocumentRegistry,
|
||||
compilerOptions: CompilerOptions,
|
||||
projectRootPath: string | undefined,
|
||||
projectRootPath: NormalizedPath | undefined,
|
||||
currentDirectory: string | undefined) {
|
||||
super(InferredProject.newName(),
|
||||
ProjectKind.Inferred,
|
||||
@@ -1081,7 +1069,8 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
addRoot(info: ScriptInfo) {
|
||||
this.projectService.startWatchingConfigFilesForInferredProjectRoot(info);
|
||||
Debug.assert(info.isScriptOpen());
|
||||
this.projectService.startWatchingConfigFilesForInferredProjectRoot(info, this.projectService.openFiles.get(info.path));
|
||||
if (!this._isJsInferredProject && info.isJavaScript()) {
|
||||
this.toggleJsInferredProject(/*isJsInferredProject*/ true);
|
||||
}
|
||||
|
||||
+34
-1
@@ -15,12 +15,17 @@ namespace ts.server.protocol {
|
||||
/* @internal */
|
||||
CompletionsFull = "completions-full",
|
||||
CompletionDetails = "completionEntryDetails",
|
||||
/* @internal */
|
||||
CompletionDetailsFull = "completionEntryDetailsFull",
|
||||
CompileOnSaveAffectedFileList = "compileOnSaveAffectedFileList",
|
||||
CompileOnSaveEmitFile = "compileOnSaveEmitFile",
|
||||
Configure = "configure",
|
||||
Definition = "definition",
|
||||
/* @internal */
|
||||
DefinitionFull = "definition-full",
|
||||
DefinitionAndBoundSpan = "definitionAndBoundSpan",
|
||||
/* @internal */
|
||||
DefinitionAndBoundSpanFull = "definitionAndBoundSpan-full",
|
||||
Implementation = "implementation",
|
||||
/* @internal */
|
||||
ImplementationFull = "implementation-full",
|
||||
@@ -708,6 +713,11 @@ namespace ts.server.protocol {
|
||||
file: string;
|
||||
}
|
||||
|
||||
export interface DefinitionInfoAndBoundSpan {
|
||||
definitions: ReadonlyArray<FileSpan>;
|
||||
textSpan: TextSpan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definition response message. Gives text range for definition.
|
||||
*/
|
||||
@@ -715,6 +725,10 @@ namespace ts.server.protocol {
|
||||
body?: FileSpan[];
|
||||
}
|
||||
|
||||
export interface DefinitionInfoAndBoundSpanReponse extends Response {
|
||||
body?: DefinitionInfoAndBoundSpan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definition response message. Gives text range for definition.
|
||||
*/
|
||||
@@ -1605,6 +1619,11 @@ namespace ts.server.protocol {
|
||||
* Optional prefix to apply to possible completions.
|
||||
*/
|
||||
prefix?: string;
|
||||
/**
|
||||
* If enabled, TypeScript will search through all external modules' exports and add them to the completions list.
|
||||
* This affects lone identifier completions but not completions on the right hand side of `obj.`.
|
||||
*/
|
||||
includeExternalModuleExports: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1625,7 +1644,12 @@ namespace ts.server.protocol {
|
||||
/**
|
||||
* Names of one or more entries for which to obtain details.
|
||||
*/
|
||||
entryNames: string[];
|
||||
entryNames: (string | CompletionEntryIdentifier)[];
|
||||
}
|
||||
|
||||
export interface CompletionEntryIdentifier {
|
||||
name: string;
|
||||
source: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1685,6 +1709,10 @@ namespace ts.server.protocol {
|
||||
* made to avoid errors. The CompletionEntryDetails will have these actions.
|
||||
*/
|
||||
hasAction?: true;
|
||||
/**
|
||||
* Identifier (not necessarily human-readable) identifying where this completion came from.
|
||||
*/
|
||||
source?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1722,6 +1750,11 @@ namespace ts.server.protocol {
|
||||
* The associated code actions for this entry
|
||||
*/
|
||||
codeActions?: CodeAction[];
|
||||
|
||||
/**
|
||||
* Human-readable description of the `source` from the CompletionEntry.
|
||||
*/
|
||||
source?: SymbolDisplayPart[];
|
||||
}
|
||||
|
||||
export interface CompletionsResponse extends Response {
|
||||
|
||||
+24
-22
@@ -67,7 +67,10 @@ namespace ts.server {
|
||||
this.lineMap = undefined;
|
||||
}
|
||||
|
||||
/** returns true if text changed */
|
||||
/**
|
||||
* Set the contents as newText
|
||||
* returns true if text changed
|
||||
*/
|
||||
public reload(newText: string) {
|
||||
Debug.assert(newText !== undefined);
|
||||
|
||||
@@ -87,31 +90,31 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
/** returns true if text changed */
|
||||
public reloadFromDisk() {
|
||||
let reloaded = false;
|
||||
if (!this.pendingReloadFromDisk && !this.ownFileText) {
|
||||
reloaded = this.reload(this.getFileText());
|
||||
this.ownFileText = true;
|
||||
}
|
||||
/**
|
||||
* Reads the contents from tempFile(if supplied) or own file and sets it as contents
|
||||
* returns true if text changed
|
||||
*/
|
||||
public reloadWithFileText(tempFileName?: string) {
|
||||
const reloaded = this.reload(this.getFileText(tempFileName));
|
||||
this.ownFileText = !tempFileName || tempFileName === this.fileName;
|
||||
return reloaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the contents from the file if there is no pending reload from disk or the contents of file are same as file text
|
||||
* returns true if text changed
|
||||
*/
|
||||
public reloadFromDisk() {
|
||||
if (!this.pendingReloadFromDisk && !this.ownFileText) {
|
||||
return this.reloadWithFileText();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public delayReloadFromFileIntoText() {
|
||||
this.pendingReloadFromDisk = true;
|
||||
}
|
||||
|
||||
/** returns true if text changed */
|
||||
public reloadFromFile(tempFileName: string) {
|
||||
let reloaded = false;
|
||||
// Reload if different file or we dont know if we are working with own file text
|
||||
if (tempFileName !== this.fileName || !this.ownFileText) {
|
||||
reloaded = this.reload(this.getFileText(tempFileName));
|
||||
this.ownFileText = !tempFileName || tempFileName === this.fileName;
|
||||
}
|
||||
return reloaded;
|
||||
}
|
||||
|
||||
public getSnapshot(): IScriptSnapshot {
|
||||
return this.useScriptVersionCacheIfValidOrOpen()
|
||||
? this.svc.getSnapshot()
|
||||
@@ -180,8 +183,7 @@ namespace ts.server {
|
||||
private getOrLoadText() {
|
||||
if (this.text === undefined || this.pendingReloadFromDisk) {
|
||||
Debug.assert(!this.svc || this.pendingReloadFromDisk, "ScriptVersionCache should not be set when reloading from disk");
|
||||
this.reload(this.getFileText());
|
||||
this.ownFileText = true;
|
||||
this.reloadWithFileText();
|
||||
}
|
||||
return this.text;
|
||||
}
|
||||
@@ -385,7 +387,7 @@ namespace ts.server {
|
||||
this.markContainingProjectsAsDirty();
|
||||
}
|
||||
else {
|
||||
if (this.textStorage.reloadFromFile(tempFileName)) {
|
||||
if (this.textStorage.reloadWithFileText(tempFileName)) {
|
||||
this.markContainingProjectsAsDirty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace ts.server {
|
||||
charCount(): number;
|
||||
lineCount(): number;
|
||||
isLeaf(): this is LineLeaf;
|
||||
walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker): void;
|
||||
walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker): void;
|
||||
}
|
||||
|
||||
export interface AbsolutePositionAndLineText {
|
||||
@@ -27,7 +27,7 @@ namespace ts.server {
|
||||
PostEnd
|
||||
}
|
||||
|
||||
interface ILineIndexWalker {
|
||||
interface LineIndexWalker {
|
||||
goSubtree: boolean;
|
||||
done: boolean;
|
||||
leaf(relativeStart: number, relativeLength: number, lineCollection: LineLeaf): void;
|
||||
@@ -37,7 +37,7 @@ namespace ts.server {
|
||||
parent: LineNode, nodeType: CharRangeSection): void;
|
||||
}
|
||||
|
||||
class EditWalker implements ILineIndexWalker {
|
||||
class EditWalker implements LineIndexWalker {
|
||||
goSubtree = true;
|
||||
get done() { return false; }
|
||||
|
||||
@@ -429,7 +429,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker) {
|
||||
walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker) {
|
||||
this.root.walk(rangeStart, rangeLength, walkFns);
|
||||
}
|
||||
|
||||
@@ -458,7 +458,7 @@ namespace ts.server {
|
||||
const walkFns = {
|
||||
goSubtree: true,
|
||||
done: false,
|
||||
leaf(this: ILineIndexWalker, relativeStart: number, relativeLength: number, ll: LineLeaf) {
|
||||
leaf(this: LineIndexWalker, relativeStart: number, relativeLength: number, ll: LineLeaf) {
|
||||
if (!f(ll, relativeStart, relativeLength)) {
|
||||
this.done = true;
|
||||
}
|
||||
@@ -580,7 +580,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private execWalk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker, childIndex: number, nodeType: CharRangeSection) {
|
||||
private execWalk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker, childIndex: number, nodeType: CharRangeSection) {
|
||||
if (walkFns.pre) {
|
||||
walkFns.pre(rangeStart, rangeLength, this.children[childIndex], this, nodeType);
|
||||
}
|
||||
@@ -596,14 +596,14 @@ namespace ts.server {
|
||||
return walkFns.done;
|
||||
}
|
||||
|
||||
private skipChild(relativeStart: number, relativeLength: number, childIndex: number, walkFns: ILineIndexWalker, nodeType: CharRangeSection) {
|
||||
private skipChild(relativeStart: number, relativeLength: number, childIndex: number, walkFns: LineIndexWalker, nodeType: CharRangeSection) {
|
||||
if (walkFns.pre && (!walkFns.done)) {
|
||||
walkFns.pre(relativeStart, relativeLength, this.children[childIndex], this, nodeType);
|
||||
walkFns.goSubtree = true;
|
||||
}
|
||||
}
|
||||
|
||||
walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker) {
|
||||
walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker) {
|
||||
// assume (rangeStart < this.totalChars) && (rangeLength <= this.totalChars)
|
||||
let childIndex = 0;
|
||||
let childCharCount = this.children[childIndex].charCount();
|
||||
@@ -814,7 +814,7 @@ namespace ts.server {
|
||||
return true;
|
||||
}
|
||||
|
||||
walk(rangeStart: number, rangeLength: number, walkFns: ILineIndexWalker) {
|
||||
walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker) {
|
||||
walkFns.leaf(rangeStart, rangeLength, this);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/// <reference path="session.ts" />
|
||||
|
||||
namespace ts.server {
|
||||
interface IOSessionOptions {
|
||||
interface IoSessionOptions {
|
||||
host: ServerHost;
|
||||
cancellationToken: ServerCancellationToken;
|
||||
canUseEvents: boolean;
|
||||
@@ -349,13 +349,13 @@ namespace ts.server {
|
||||
|
||||
const execArgv: string[] = [];
|
||||
for (const arg of process.execArgv) {
|
||||
const match = /^--(debug|inspect)(=(\d+))?$/.exec(arg);
|
||||
const match = /^--((?:debug|inspect)(?:-brk)?)(?:=(\d+))?$/.exec(arg);
|
||||
if (match) {
|
||||
// if port is specified - use port + 1
|
||||
// otherwise pick a default port depending on if 'debug' or 'inspect' and use its value + 1
|
||||
const currentPort = match[3] !== undefined
|
||||
? +match[3]
|
||||
: match[1] === "debug" ? 5858 : 9229;
|
||||
const currentPort = match[2] !== undefined
|
||||
? +match[2]
|
||||
: match[1].charAt(0) === "d" ? 5858 : 9229;
|
||||
execArgv.push(`--${match[1]}=${currentPort + 1}`);
|
||||
break;
|
||||
}
|
||||
@@ -529,7 +529,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
class IOSession extends Session {
|
||||
constructor(options: IOSessionOptions) {
|
||||
constructor(options: IoSessionOptions) {
|
||||
const { host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, canUseEvents } = options;
|
||||
const typingsInstaller = disableAutomaticTypingAcquisition
|
||||
? undefined
|
||||
@@ -816,7 +816,7 @@ namespace ts.server {
|
||||
if (useWatchGuard) {
|
||||
const currentDrive = extractWatchDirectoryCacheKey(sys.resolvePath(sys.getCurrentDirectory()), /*currentDriveKey*/ undefined);
|
||||
const statusCache = createMap<boolean>();
|
||||
sys.watchDirectory = function (path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher {
|
||||
sys.watchDirectory = (path, callback, recursive) => {
|
||||
const cacheKey = extractWatchDirectoryCacheKey(path, currentDrive);
|
||||
let status = cacheKey && statusCache.get(cacheKey);
|
||||
if (status === undefined) {
|
||||
@@ -933,7 +933,7 @@ namespace ts.server {
|
||||
const disableAutomaticTypingAcquisition = hasArgument("--disableAutomaticTypingAcquisition");
|
||||
const telemetryEnabled = hasArgument(Arguments.EnableTelemetry);
|
||||
|
||||
const options: IOSessionOptions = {
|
||||
const options: IoSessionOptions = {
|
||||
host: sys,
|
||||
cancellationToken,
|
||||
installerEventPort: eventPort,
|
||||
@@ -953,7 +953,7 @@ namespace ts.server {
|
||||
};
|
||||
|
||||
const ioSession = new IOSession(options);
|
||||
process.on("uncaughtException", function (err: Error) {
|
||||
process.on("uncaughtException", err => {
|
||||
ioSession.logError(err, "unknown");
|
||||
});
|
||||
// See https://github.com/Microsoft/TypeScript/issues/11348
|
||||
|
||||
+90
-68
@@ -167,7 +167,7 @@ namespace ts.server {
|
||||
private timerHandle: any;
|
||||
private immediateId: number | undefined;
|
||||
|
||||
constructor(private readonly operationHost: MultistepOperationHost) {}
|
||||
constructor(private readonly operationHost: MultistepOperationHost) { }
|
||||
|
||||
public startNew(action: (next: NextStep) => void) {
|
||||
this.complete();
|
||||
@@ -587,7 +587,7 @@ namespace ts.server {
|
||||
|
||||
private getDiagnosticsWorker(
|
||||
args: protocol.FileRequestArgs, isSemantic: boolean, selector: (project: Project, file: string) => ReadonlyArray<Diagnostic>, includeLinePosition: boolean
|
||||
): ReadonlyArray<protocol.DiagnosticWithLinePosition> | ReadonlyArray<protocol.Diagnostic> {
|
||||
): ReadonlyArray<protocol.DiagnosticWithLinePosition> | ReadonlyArray<protocol.Diagnostic> {
|
||||
const { project, file } = this.getFileAndProject(args);
|
||||
if (isSemantic && isDeclarationFileInJSOnlyNonConfiguredProject(project, file)) {
|
||||
return emptyArray;
|
||||
@@ -609,20 +609,51 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
if (simplifiedResult) {
|
||||
return definitions.map(def => {
|
||||
const defScriptInfo = project.getScriptInfo(def.fileName);
|
||||
return {
|
||||
file: def.fileName,
|
||||
start: defScriptInfo.positionToLineOffset(def.textSpan.start),
|
||||
end: defScriptInfo.positionToLineOffset(textSpanEnd(def.textSpan))
|
||||
};
|
||||
});
|
||||
return this.mapDefinitionInfo(definitions, project);
|
||||
}
|
||||
else {
|
||||
return definitions;
|
||||
}
|
||||
}
|
||||
|
||||
private getDefinitionAndBoundSpan(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.DefinitionInfoAndBoundSpan | DefinitionInfoAndBoundSpan {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const position = this.getPositionInFile(args, file);
|
||||
const scriptInfo = project.getScriptInfo(file);
|
||||
|
||||
const definitionAndBoundSpan = project.getLanguageService().getDefinitionAndBoundSpan(file, position);
|
||||
|
||||
if (!definitionAndBoundSpan || !definitionAndBoundSpan.definitions) {
|
||||
return {
|
||||
definitions: emptyArray,
|
||||
textSpan: undefined
|
||||
};
|
||||
}
|
||||
|
||||
if (simplifiedResult) {
|
||||
return {
|
||||
definitions: this.mapDefinitionInfo(definitionAndBoundSpan.definitions, project),
|
||||
textSpan: this.toLocationTextSpan(definitionAndBoundSpan.textSpan, scriptInfo)
|
||||
};
|
||||
}
|
||||
|
||||
return definitionAndBoundSpan;
|
||||
}
|
||||
|
||||
private mapDefinitionInfo(definitions: ReadonlyArray<DefinitionInfo>, project: Project): ReadonlyArray<protocol.FileSpan> {
|
||||
return definitions.map(def => this.toFileSpan(def.fileName, def.textSpan, project));
|
||||
}
|
||||
|
||||
private toFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan {
|
||||
const scriptInfo = project.getScriptInfo(fileName);
|
||||
|
||||
return {
|
||||
file: fileName,
|
||||
start: scriptInfo.positionToLineOffset(textSpan.start),
|
||||
end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan))
|
||||
};
|
||||
}
|
||||
|
||||
private getTypeDefinition(args: protocol.FileLocationRequestArgs): ReadonlyArray<protocol.FileSpan> {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const position = this.getPositionInFile(args, file);
|
||||
@@ -632,14 +663,7 @@ namespace ts.server {
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
return definitions.map(def => {
|
||||
const defScriptInfo = project.getScriptInfo(def.fileName);
|
||||
return {
|
||||
file: def.fileName,
|
||||
start: defScriptInfo.positionToLineOffset(def.textSpan.start),
|
||||
end: defScriptInfo.positionToLineOffset(textSpanEnd(def.textSpan))
|
||||
};
|
||||
});
|
||||
return this.mapDefinitionInfo(definitions, project);
|
||||
}
|
||||
|
||||
private getImplementation(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.FileSpan> | ReadonlyArray<ImplementationLocation> {
|
||||
@@ -650,14 +674,7 @@ namespace ts.server {
|
||||
return emptyArray;
|
||||
}
|
||||
if (simplifiedResult) {
|
||||
return implementations.map(({ fileName, textSpan }) => {
|
||||
const scriptInfo = project.getScriptInfo(fileName);
|
||||
return {
|
||||
file: fileName,
|
||||
start: scriptInfo.positionToLineOffset(textSpan.start),
|
||||
end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan))
|
||||
};
|
||||
});
|
||||
return implementations.map(({ fileName, textSpan }) => this.toFileSpan(fileName, textSpan, project));
|
||||
}
|
||||
else {
|
||||
return implementations;
|
||||
@@ -666,6 +683,7 @@ namespace ts.server {
|
||||
|
||||
private getOccurrences(args: protocol.FileLocationRequestArgs): ReadonlyArray<protocol.OccurrencesResponseItem> {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
|
||||
const position = this.getPositionInFile(args, file);
|
||||
|
||||
const occurrences = project.getLanguageService().getOccurrencesAtPosition(file, position);
|
||||
@@ -677,11 +695,9 @@ namespace ts.server {
|
||||
return occurrences.map(occurrence => {
|
||||
const { fileName, isWriteAccess, textSpan, isInString } = occurrence;
|
||||
const scriptInfo = project.getScriptInfo(fileName);
|
||||
const start = scriptInfo.positionToLineOffset(textSpan.start);
|
||||
const end = scriptInfo.positionToLineOffset(textSpanEnd(textSpan));
|
||||
const result: protocol.OccurrencesResponseItem = {
|
||||
start,
|
||||
end,
|
||||
start: scriptInfo.positionToLineOffset(textSpan.start),
|
||||
end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)),
|
||||
file: fileName,
|
||||
isWriteAccess,
|
||||
};
|
||||
@@ -1184,14 +1200,14 @@ namespace ts.server {
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
|
||||
const position = this.getPosition(args, scriptInfo);
|
||||
|
||||
const completions = project.getLanguageService().getCompletionsAtPosition(file, position);
|
||||
const completions = project.getLanguageService().getCompletionsAtPosition(file, position, args);
|
||||
if (simplifiedResult) {
|
||||
return mapDefined<CompletionEntry, protocol.CompletionEntry>(completions && completions.entries, entry => {
|
||||
if (completions.isMemberCompletion || (entry.name.toLowerCase().indexOf(prefix.toLowerCase()) === 0)) {
|
||||
const { name, kind, kindModifiers, sortText, replacementSpan, hasAction } = entry;
|
||||
const convertedSpan = replacementSpan ? this.decorateSpan(replacementSpan, scriptInfo) : undefined;
|
||||
if (completions.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) {
|
||||
const { name, kind, kindModifiers, sortText, replacementSpan, hasAction, source } = entry;
|
||||
const convertedSpan = replacementSpan ? this.toLocationTextSpan(replacementSpan, scriptInfo) : undefined;
|
||||
// Use `hasAction || undefined` to avoid serializing `false`.
|
||||
return { name, kind, kindModifiers, sortText, replacementSpan: convertedSpan, hasAction: hasAction || undefined };
|
||||
return { name, kind, kindModifiers, sortText, replacementSpan: convertedSpan, hasAction: hasAction || undefined, source };
|
||||
}
|
||||
}).sort((a, b) => compareStringsCaseSensitiveUI(a.name, b.name));
|
||||
}
|
||||
@@ -1200,22 +1216,19 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private getCompletionEntryDetails(args: protocol.CompletionDetailsRequestArgs): ReadonlyArray<protocol.CompletionEntryDetails> {
|
||||
private getCompletionEntryDetails(args: protocol.CompletionDetailsRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.CompletionEntryDetails> | ReadonlyArray<CompletionEntryDetails> {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
|
||||
const position = this.getPosition(args, scriptInfo);
|
||||
const formattingOptions = project.projectService.getFormatCodeOptions(file);
|
||||
|
||||
return mapDefined(args.entryNames, entryName => {
|
||||
const details = project.getLanguageService().getCompletionEntryDetails(file, position, entryName, formattingOptions);
|
||||
if (details) {
|
||||
const mappedCodeActions = map(details.codeActions, action => this.mapCodeAction(action, scriptInfo));
|
||||
return { ...details, codeActions: mappedCodeActions };
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
}
|
||||
const result = mapDefined(args.entryNames, entryName => {
|
||||
const { name, source } = typeof entryName === "string" ? { name: entryName, source: undefined } : entryName;
|
||||
return project.getLanguageService().getCompletionEntryDetails(file, position, name, formattingOptions, source);
|
||||
});
|
||||
return simplifiedResult
|
||||
? result.map(details => ({ ...details, codeActions: map(details.codeActions, action => this.mapCodeAction(action, scriptInfo)) }))
|
||||
: result;
|
||||
}
|
||||
|
||||
private getCompileOnSaveAffectedFileList(args: protocol.FileRequestArgs): ReadonlyArray<protocol.CompileOnSaveAffectedFileListSingleProject> {
|
||||
@@ -1311,11 +1324,13 @@ namespace ts.server {
|
||||
private reload(args: protocol.ReloadRequestArgs, reqSeq: number) {
|
||||
const file = toNormalizedPath(args.file);
|
||||
const tempFileName = args.tmpfile && toNormalizedPath(args.tmpfile);
|
||||
const project = this.projectService.getDefaultProjectForFile(file, /*ensureProject*/ true);
|
||||
this.changeSeq++;
|
||||
// make sure no changes happen before this one is finished
|
||||
if (project.reloadScript(file, tempFileName)) {
|
||||
this.doOutput(/*info*/ undefined, CommandNames.Reload, reqSeq, /*success*/ true);
|
||||
const info = this.projectService.getScriptInfoForNormalizedPath(file);
|
||||
if (info) {
|
||||
this.changeSeq++;
|
||||
// make sure no changes happen before this one is finished
|
||||
if (info.reloadFromFile(tempFileName)) {
|
||||
this.doOutput(/*info*/ undefined, CommandNames.Reload, reqSeq, /*success*/ true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1334,13 +1349,13 @@ namespace ts.server {
|
||||
this.projectService.closeClientFile(file);
|
||||
}
|
||||
|
||||
private decorateNavigationBarItems(items: NavigationBarItem[], scriptInfo: ScriptInfo): protocol.NavigationBarItem[] {
|
||||
private mapLocationNavigationBarItems(items: NavigationBarItem[], scriptInfo: ScriptInfo): protocol.NavigationBarItem[] {
|
||||
return map(items, item => ({
|
||||
text: item.text,
|
||||
kind: item.kind,
|
||||
kindModifiers: item.kindModifiers,
|
||||
spans: item.spans.map(span => this.decorateSpan(span, scriptInfo)),
|
||||
childItems: this.decorateNavigationBarItems(item.childItems, scriptInfo),
|
||||
spans: item.spans.map(span => this.toLocationTextSpan(span, scriptInfo)),
|
||||
childItems: this.mapLocationNavigationBarItems(item.childItems, scriptInfo),
|
||||
indent: item.indent
|
||||
}));
|
||||
}
|
||||
@@ -1351,21 +1366,21 @@ namespace ts.server {
|
||||
return !items
|
||||
? undefined
|
||||
: simplifiedResult
|
||||
? this.decorateNavigationBarItems(items, this.projectService.getScriptInfoForNormalizedPath(file))
|
||||
? this.mapLocationNavigationBarItems(items, this.projectService.getScriptInfoForNormalizedPath(file))
|
||||
: items;
|
||||
}
|
||||
|
||||
private decorateNavigationTree(tree: NavigationTree, scriptInfo: ScriptInfo): protocol.NavigationTree {
|
||||
private toLocationNavigationTree(tree: NavigationTree, scriptInfo: ScriptInfo): protocol.NavigationTree {
|
||||
return {
|
||||
text: tree.text,
|
||||
kind: tree.kind,
|
||||
kindModifiers: tree.kindModifiers,
|
||||
spans: tree.spans.map(span => this.decorateSpan(span, scriptInfo)),
|
||||
childItems: map(tree.childItems, item => this.decorateNavigationTree(item, scriptInfo))
|
||||
spans: tree.spans.map(span => this.toLocationTextSpan(span, scriptInfo)),
|
||||
childItems: map(tree.childItems, item => this.toLocationNavigationTree(item, scriptInfo))
|
||||
};
|
||||
}
|
||||
|
||||
private decorateSpan(span: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan {
|
||||
private toLocationTextSpan(span: TextSpan, scriptInfo: ScriptInfo): protocol.TextSpan {
|
||||
return {
|
||||
start: scriptInfo.positionToLineOffset(span.start),
|
||||
end: scriptInfo.positionToLineOffset(textSpanEnd(span))
|
||||
@@ -1378,7 +1393,7 @@ namespace ts.server {
|
||||
return !tree
|
||||
? undefined
|
||||
: simplifiedResult
|
||||
? this.decorateNavigationTree(tree, this.projectService.getScriptInfoForNormalizedPath(file))
|
||||
? this.toLocationNavigationTree(tree, this.projectService.getScriptInfoForNormalizedPath(file))
|
||||
: tree;
|
||||
}
|
||||
|
||||
@@ -1397,14 +1412,12 @@ namespace ts.server {
|
||||
|
||||
return navItems.map((navItem) => {
|
||||
const scriptInfo = project.getScriptInfo(navItem.fileName);
|
||||
const start = scriptInfo.positionToLineOffset(navItem.textSpan.start);
|
||||
const end = scriptInfo.positionToLineOffset(textSpanEnd(navItem.textSpan));
|
||||
const bakedItem: protocol.NavtoItem = {
|
||||
name: navItem.name,
|
||||
kind: navItem.kind,
|
||||
file: navItem.fileName,
|
||||
start,
|
||||
end,
|
||||
start: scriptInfo.positionToLineOffset(navItem.textSpan.start),
|
||||
end: scriptInfo.positionToLineOffset(textSpanEnd(navItem.textSpan))
|
||||
};
|
||||
if (navItem.kindModifiers && (navItem.kindModifiers !== "")) {
|
||||
bakedItem.kindModifiers = navItem.kindModifiers;
|
||||
@@ -1591,7 +1604,7 @@ namespace ts.server {
|
||||
fileName: change.fileName,
|
||||
textChanges: change.textChanges.map(textChange => this.convertTextChangeToCodeEdit(textChange, scriptInfo))
|
||||
}));
|
||||
return { description, changes, commands };
|
||||
return { description, changes, commands };
|
||||
}
|
||||
|
||||
private mapTextChangesToCodeEdits(project: Project, textChanges: FileTextChanges): protocol.FileCodeEdits {
|
||||
@@ -1619,7 +1632,7 @@ namespace ts.server {
|
||||
return !spans
|
||||
? undefined
|
||||
: simplifiedResult
|
||||
? spans.map(span => this.decorateSpan(span, scriptInfo))
|
||||
? spans.map(span => this.toLocationTextSpan(span, scriptInfo))
|
||||
: spans;
|
||||
}
|
||||
|
||||
@@ -1735,6 +1748,12 @@ namespace ts.server {
|
||||
[CommandNames.DefinitionFull]: (request: protocol.DefinitionRequest) => {
|
||||
return this.requiredResponse(this.getDefinition(request.arguments, /*simplifiedResult*/ false));
|
||||
},
|
||||
[CommandNames.DefinitionAndBoundSpan]: (request: protocol.DefinitionRequest) => {
|
||||
return this.requiredResponse(this.getDefinitionAndBoundSpan(request.arguments, /*simplifiedResult*/ true));
|
||||
},
|
||||
[CommandNames.DefinitionAndBoundSpanFull]: (request: protocol.DefinitionRequest) => {
|
||||
return this.requiredResponse(this.getDefinitionAndBoundSpan(request.arguments, /*simplifiedResult*/ false));
|
||||
},
|
||||
[CommandNames.TypeDefinition]: (request: protocol.FileLocationRequest) => {
|
||||
return this.requiredResponse(this.getTypeDefinition(request.arguments));
|
||||
},
|
||||
@@ -1812,14 +1831,17 @@ namespace ts.server {
|
||||
[CommandNames.FormatRangeFull]: (request: protocol.FormatRequest) => {
|
||||
return this.requiredResponse(this.getFormattingEditsForRangeFull(request.arguments));
|
||||
},
|
||||
[CommandNames.Completions]: (request: protocol.CompletionDetailsRequest) => {
|
||||
[CommandNames.Completions]: (request: protocol.CompletionsRequest) => {
|
||||
return this.requiredResponse(this.getCompletions(request.arguments, /*simplifiedResult*/ true));
|
||||
},
|
||||
[CommandNames.CompletionsFull]: (request: protocol.CompletionDetailsRequest) => {
|
||||
[CommandNames.CompletionsFull]: (request: protocol.CompletionsRequest) => {
|
||||
return this.requiredResponse(this.getCompletions(request.arguments, /*simplifiedResult*/ false));
|
||||
},
|
||||
[CommandNames.CompletionDetails]: (request: protocol.CompletionDetailsRequest) => {
|
||||
return this.requiredResponse(this.getCompletionEntryDetails(request.arguments));
|
||||
return this.requiredResponse(this.getCompletionEntryDetails(request.arguments, /*simplifiedResult*/ true));
|
||||
},
|
||||
[CommandNames.CompletionDetailsFull]: (request: protocol.CompletionDetailsRequest) => {
|
||||
return this.requiredResponse(this.getCompletionEntryDetails(request.arguments, /*simplifiedResult*/ false));
|
||||
},
|
||||
[CommandNames.CompileOnSaveAffectedFileList]: (request: protocol.CompileOnSaveAffectedFileListRequest) => {
|
||||
return this.requiredResponse(this.getCompileOnSaveAffectedFileList(request.arguments));
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace ts.server {
|
||||
projectRootPath: Path;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line interface-name (for backwards-compatibility)
|
||||
export interface ITypingsInstaller {
|
||||
isKnownTypesPackageName(name: string): boolean;
|
||||
installPackage(options: InstallPackageOptionsWithProjectRootPath): Promise<ApplyCodeActionCommandResult>;
|
||||
|
||||
@@ -248,7 +248,7 @@ namespace ts.server.typingsInstaller {
|
||||
this.log.writeLine(`Npm config file: '${npmConfigPath}' is missing, creating new one...`);
|
||||
}
|
||||
this.ensureDirectoryExists(directory, this.installTypingHost);
|
||||
this.installTypingHost.writeFile(npmConfigPath, "{}");
|
||||
this.installTypingHost.writeFile(npmConfigPath, '{ "description": "", "repository": "", "license": "" }');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace ts.BreakpointResolver {
|
||||
}
|
||||
|
||||
// Cannot set breakpoint in ambient declarations
|
||||
if (isInAmbientContext(tokenAtLocation)) {
|
||||
if (tokenAtLocation.flags & NodeFlags.Ambient) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -297,7 +297,7 @@ namespace ts.BreakpointResolver {
|
||||
}
|
||||
}
|
||||
|
||||
if (isPartOfExpression(node)) {
|
||||
if (isExpressionNode(node)) {
|
||||
switch (node.parent.kind) {
|
||||
case SyntaxKind.DoStatement:
|
||||
// Set span as if on while keyword
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace ts.codefix {
|
||||
|
||||
const typesPackageName = getTypesPackageName(packageName);
|
||||
return {
|
||||
description: `Install '${typesPackageName}'`,
|
||||
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Install_0), [typesPackageName]),
|
||||
changes: [],
|
||||
commands: [{ type: "install package", packageName: typesPackageName }],
|
||||
};
|
||||
|
||||
@@ -20,8 +20,8 @@ namespace ts.codefix {
|
||||
// i.e. super(this.a), since in that case we won't suggest a fix
|
||||
if (superCall.expression && superCall.expression.kind === SyntaxKind.CallExpression) {
|
||||
const expressionArguments = (<CallExpression>superCall.expression).arguments;
|
||||
for (let i = 0; i < expressionArguments.length; i++) {
|
||||
if ((<PropertyAccessExpression>expressionArguments[i]).expression === token) {
|
||||
for (const arg of expressionArguments) {
|
||||
if ((<PropertyAccessExpression>arg).expression === token) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,8 +104,7 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
const signatureDeclarations: MethodDeclaration[] = [];
|
||||
for (let i = 0; i < signatures.length; i++) {
|
||||
const signature = signatures[i];
|
||||
for (const signature of signatures) {
|
||||
const methodDeclaration = signatureToMethodDeclaration(signature, enclosingDeclaration);
|
||||
if (methodDeclaration) {
|
||||
signatureDeclarations.push(methodDeclaration);
|
||||
@@ -194,8 +193,7 @@ namespace ts.codefix {
|
||||
let maxArgsSignature = signatures[0];
|
||||
let minArgumentCount = signatures[0].minArgumentCount;
|
||||
let someSigHasRestParameter = false;
|
||||
for (let i = 0; i < signatures.length; i++) {
|
||||
const sig = signatures[i];
|
||||
for (const sig of signatures) {
|
||||
minArgumentCount = Math.min(sig.minArgumentCount, minArgumentCount);
|
||||
if (sig.hasRestParameter) {
|
||||
someSigHasRestParameter = true;
|
||||
|
||||
@@ -249,7 +249,11 @@ namespace ts.codefix {
|
||||
const lastImportDeclaration = findLast(sourceFile.statements, isAnyImportSyntax);
|
||||
|
||||
const moduleSpecifierWithoutQuotes = stripQuotes(moduleSpecifier);
|
||||
const importDecl = createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createImportClauseOfKind(kind, symbolName), createStringLiteralWithQuoteStyle(sourceFile, moduleSpecifierWithoutQuotes));
|
||||
const importDecl = createImportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createImportClauseOfKind(kind, symbolName),
|
||||
createStringLiteralWithQuoteStyle(sourceFile, moduleSpecifierWithoutQuotes));
|
||||
const changes = ChangeTracker.with(context, changeTracker => {
|
||||
if (lastImportDeclaration) {
|
||||
changeTracker.insertNodeAfter(sourceFile, lastImportDeclaration, importDecl, { suffix: newLineCharacter });
|
||||
@@ -279,13 +283,14 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
function createImportClauseOfKind(kind: ImportKind, symbolName: string) {
|
||||
const id = createIdentifier(symbolName);
|
||||
switch (kind) {
|
||||
case ImportKind.Default:
|
||||
return createImportClause(createIdentifier(symbolName), /*namedBindings*/ undefined);
|
||||
return createImportClause(id, /*namedBindings*/ undefined);
|
||||
case ImportKind.Namespace:
|
||||
return createImportClause(/*name*/ undefined, createNamespaceImport(createIdentifier(symbolName)));
|
||||
return createImportClause(/*name*/ undefined, createNamespaceImport(id));
|
||||
case ImportKind.Named:
|
||||
return createImportClause(/*name*/ undefined, createNamedImports([createImportSpecifier(/*propertyName*/ undefined, createIdentifier(symbolName))]));
|
||||
return createImportClause(/*name*/ undefined, createNamedImports([createImportSpecifier(/*propertyName*/ undefined, id)]));
|
||||
default:
|
||||
Debug.assertNever(kind);
|
||||
}
|
||||
@@ -529,7 +534,7 @@ namespace ts.codefix {
|
||||
declarations: ReadonlyArray<AnyImportSyntax>): ImportCodeAction {
|
||||
const fromExistingImport = firstDefined(declarations, declaration => {
|
||||
if (declaration.kind === SyntaxKind.ImportDeclaration && declaration.importClause) {
|
||||
const changes = tryUpdateExistingImport(ctx, ctx.kind, declaration.importClause);
|
||||
const changes = tryUpdateExistingImport(ctx, declaration.importClause);
|
||||
if (changes) {
|
||||
const moduleSpecifierWithoutQuotes = stripQuotes(declaration.moduleSpecifier.getText());
|
||||
return createCodeAction(
|
||||
@@ -559,8 +564,8 @@ namespace ts.codefix {
|
||||
return expression && isStringLiteral(expression) ? expression.text : undefined;
|
||||
}
|
||||
|
||||
function tryUpdateExistingImport(context: SymbolContext, kind: ImportKind, importClause: ImportClause): FileTextChanges[] | undefined {
|
||||
const { symbolName, sourceFile } = context;
|
||||
function tryUpdateExistingImport(context: SymbolContext & { kind: ImportKind }, importClause: ImportClause): FileTextChanges[] | undefined {
|
||||
const { symbolName, sourceFile, kind } = context;
|
||||
const { name, namedBindings } = importClause;
|
||||
switch (kind) {
|
||||
case ImportKind.Default:
|
||||
|
||||
@@ -368,7 +368,7 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
function inferTypeFromContextualType(node: Expression, checker: TypeChecker, usageContext: UsageContext): void {
|
||||
if (isPartOfExpression(node)) {
|
||||
if (isExpressionNode(node)) {
|
||||
addCandidateType(usageContext, checker.getContextualType(node));
|
||||
}
|
||||
}
|
||||
|
||||
+171
-74
@@ -12,7 +12,7 @@ namespace ts.Completions {
|
||||
* Map from symbol id -> SymbolOriginInfo.
|
||||
* Only populated for symbols that come from other modules.
|
||||
*/
|
||||
type SymbolOriginInfoMap = SymbolOriginInfo[];
|
||||
type SymbolOriginInfoMap = (SymbolOriginInfo | undefined)[];
|
||||
|
||||
const enum KeywordCompletionFilters {
|
||||
None,
|
||||
@@ -28,16 +28,18 @@ namespace ts.Completions {
|
||||
sourceFile: SourceFile,
|
||||
position: number,
|
||||
allSourceFiles: ReadonlyArray<SourceFile>,
|
||||
options: GetCompletionsAtPositionOptions,
|
||||
): CompletionInfo | undefined {
|
||||
if (isInReferenceComment(sourceFile, position)) {
|
||||
return PathCompletions.getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host);
|
||||
const entries = PathCompletions.getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host);
|
||||
return entries && pathCompletionsInfo(entries);
|
||||
}
|
||||
|
||||
if (isInString(sourceFile, position)) {
|
||||
return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log);
|
||||
}
|
||||
|
||||
const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles);
|
||||
const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, options);
|
||||
if (!completionData) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -100,7 +102,7 @@ namespace ts.Completions {
|
||||
function getJavaScriptCompletionEntries(
|
||||
sourceFile: SourceFile,
|
||||
position: number,
|
||||
uniqueNames: Map<true>,
|
||||
uniqueNames: Map<{}>,
|
||||
target: ScriptTarget,
|
||||
entries: Push<CompletionEntry>): void {
|
||||
getNameTable(sourceFile).forEach((pos, name) => {
|
||||
@@ -127,7 +129,15 @@ namespace ts.Completions {
|
||||
});
|
||||
}
|
||||
|
||||
function createCompletionEntry(symbol: Symbol, location: Node, performCharacterChecks: boolean, typeChecker: TypeChecker, target: ScriptTarget, allowStringLiteral: boolean): CompletionEntry {
|
||||
function createCompletionEntry(
|
||||
symbol: Symbol,
|
||||
location: Node,
|
||||
performCharacterChecks: boolean,
|
||||
typeChecker: TypeChecker,
|
||||
target: ScriptTarget,
|
||||
allowStringLiteral: boolean,
|
||||
origin: SymbolOriginInfo,
|
||||
): CompletionEntry | undefined {
|
||||
// Try to get a valid display name for this symbol, if we could not find one, then ignore it.
|
||||
// We would like to only show things that can be added after a dot, so for instance numeric properties can
|
||||
// not be accessed with a dot (a.1 <- invalid)
|
||||
@@ -149,9 +159,15 @@ namespace ts.Completions {
|
||||
kind: SymbolDisplay.getSymbolKind(typeChecker, symbol, location),
|
||||
kindModifiers: SymbolDisplay.getSymbolModifiers(symbol),
|
||||
sortText: "0",
|
||||
source: getSourceFromOrigin(origin),
|
||||
hasAction: origin === undefined ? undefined : true,
|
||||
};
|
||||
}
|
||||
|
||||
function getSourceFromOrigin(origin: SymbolOriginInfo | undefined): string | undefined {
|
||||
return origin && stripQuotes(origin.moduleSymbol.name);
|
||||
}
|
||||
|
||||
function getCompletionEntriesFromSymbols(
|
||||
symbols: ReadonlyArray<Symbol>,
|
||||
entries: Push<CompletionEntry>,
|
||||
@@ -164,25 +180,35 @@ namespace ts.Completions {
|
||||
symbolToOriginInfoMap?: SymbolOriginInfoMap,
|
||||
): Map<true> {
|
||||
const start = timestamp();
|
||||
const uniqueNames = createMap<true>();
|
||||
// Tracks unique names.
|
||||
// We don't set this for global variables or completions from external module exports, because we can have multiple of those.
|
||||
// Based on the order we add things we will always see locals first, then globals, then module exports.
|
||||
// So adding a completion for a local will prevent us from adding completions for external module exports sharing the same name.
|
||||
const uniques = createMap<true>();
|
||||
if (symbols) {
|
||||
for (const symbol of symbols) {
|
||||
const entry = createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target, allowStringLiteral);
|
||||
if (entry) {
|
||||
const id = entry.name;
|
||||
if (!uniqueNames.has(id)) {
|
||||
if (symbolToOriginInfoMap && symbolToOriginInfoMap[getUniqueSymbolId(symbol, typeChecker)]) {
|
||||
entry.hasAction = true;
|
||||
}
|
||||
entries.push(entry);
|
||||
uniqueNames.set(id, true);
|
||||
}
|
||||
const origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[getSymbolId(symbol)] : undefined;
|
||||
const entry = createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target, allowStringLiteral, origin);
|
||||
if (!entry) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const { name } = entry;
|
||||
if (uniques.has(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Latter case tests whether this is a global variable.
|
||||
if (!origin && !(symbol.parent === undefined && !some(symbol.declarations, d => d.getSourceFile() === location.getSourceFile()))) {
|
||||
uniques.set(name, true);
|
||||
}
|
||||
|
||||
entries.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (timestamp() - start));
|
||||
return uniqueNames;
|
||||
return uniques;
|
||||
}
|
||||
|
||||
function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number, typeChecker: TypeChecker, compilerOptions: CompilerOptions, host: LanguageServiceHost, log: Log): CompletionInfo | undefined {
|
||||
@@ -217,12 +243,17 @@ namespace ts.Completions {
|
||||
// a['/*completion position*/']
|
||||
return getStringLiteralCompletionEntriesFromElementAccess(node.parent, typeChecker, compilerOptions.target, log);
|
||||
}
|
||||
else if (node.parent.kind === SyntaxKind.ImportDeclaration || isExpressionOfExternalModuleImportEqualsDeclaration(node) || isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false)) {
|
||||
else if (node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration
|
||||
|| isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) || isImportCall(node.parent)
|
||||
|| isExpressionOfExternalModuleImportEqualsDeclaration(node)) {
|
||||
// Get all known external module names or complete a path to a module
|
||||
// i.e. import * as ns from "/*completion position*/";
|
||||
// var y = import("/*completion position*/");
|
||||
// import x = require("/*completion position*/");
|
||||
// var y = require("/*completion position*/");
|
||||
return PathCompletions.getStringLiteralCompletionEntriesFromModuleNames(<StringLiteral>node, compilerOptions, host, typeChecker);
|
||||
// export * from "/*completion position*/";
|
||||
const entries = PathCompletions.getStringLiteralCompletionsFromModuleNames(<StringLiteral>node, compilerOptions, host, typeChecker);
|
||||
return pathCompletionsInfo(entries);
|
||||
}
|
||||
else if (isEqualityExpression(node.parent)) {
|
||||
// Get completions from the type of the other operand
|
||||
@@ -251,6 +282,18 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
|
||||
function pathCompletionsInfo(entries: CompletionEntry[]): CompletionInfo {
|
||||
return {
|
||||
// We don't want the editor to offer any other completions, such as snippets, inside a comment.
|
||||
isGlobalCompletion: false,
|
||||
isMemberCompletion: false,
|
||||
// The user may type in a path that doesn't yet exist, creating a "new identifier"
|
||||
// with respect to the collection of identifiers the server is aware of.
|
||||
isNewIdentifierLocation: true,
|
||||
entries,
|
||||
};
|
||||
}
|
||||
|
||||
function getStringLiteralCompletionEntriesFromPropertyAssignment(element: ObjectLiteralElement, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined {
|
||||
const type = typeChecker.getContextualType((<ObjectLiteralExpression>element.parent));
|
||||
const entries: CompletionEntry[] = [];
|
||||
@@ -329,59 +372,104 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
|
||||
function getSymbolCompletionFromEntryId(
|
||||
typeChecker: TypeChecker,
|
||||
log: (message: string) => void,
|
||||
compilerOptions: CompilerOptions,
|
||||
sourceFile: SourceFile,
|
||||
position: number,
|
||||
{ name, source }: CompletionEntryIdentifier,
|
||||
allSourceFiles: ReadonlyArray<SourceFile>,
|
||||
): { type: "symbol", symbol: Symbol, location: Node, symbolToOriginInfoMap: SymbolOriginInfoMap } | { type: "request", request: Request } | { type: "none" } {
|
||||
const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, { includeExternalModuleExports: true });
|
||||
if (!completionData) {
|
||||
return { type: "none" };
|
||||
}
|
||||
|
||||
const { symbols, location, allowStringLiteral, symbolToOriginInfoMap, request } = completionData;
|
||||
if (request) {
|
||||
return { type: "request", request };
|
||||
}
|
||||
|
||||
// Find the symbol with the matching entry name.
|
||||
// We don't need to perform character checks here because we're only comparing the
|
||||
// name against 'entryName' (which is known to be good), not building a new
|
||||
// completion entry.
|
||||
const symbol = find(symbols, s =>
|
||||
getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral) === name
|
||||
&& getSourceFromOrigin(symbolToOriginInfoMap[getSymbolId(s)]) === source);
|
||||
return symbol ? { type: "symbol", symbol, location, symbolToOriginInfoMap } : { type: "none" };
|
||||
}
|
||||
|
||||
export interface CompletionEntryIdentifier {
|
||||
name: string;
|
||||
source?: string;
|
||||
}
|
||||
|
||||
export function getCompletionEntryDetails(
|
||||
typeChecker: TypeChecker,
|
||||
log: (message: string) => void,
|
||||
compilerOptions: CompilerOptions,
|
||||
sourceFile: SourceFile,
|
||||
position: number,
|
||||
name: string,
|
||||
entryId: CompletionEntryIdentifier,
|
||||
allSourceFiles: ReadonlyArray<SourceFile>,
|
||||
host: LanguageServiceHost,
|
||||
rulesProvider: formatting.RulesProvider,
|
||||
): CompletionEntryDetails {
|
||||
|
||||
const { name, source } = entryId;
|
||||
// Compute all the completion symbols again.
|
||||
const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles);
|
||||
if (completionData) {
|
||||
const { symbols, location, allowStringLiteral, symbolToOriginInfoMap } = completionData;
|
||||
|
||||
// Find the symbol with the matching entry name.
|
||||
// We don't need to perform character checks here because we're only comparing the
|
||||
// name against 'entryName' (which is known to be good), not building a new
|
||||
// completion entry.
|
||||
const symbol = find(symbols, s => getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral) === name);
|
||||
|
||||
if (symbol) {
|
||||
const symbolCompletion = getSymbolCompletionFromEntryId(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles);
|
||||
switch (symbolCompletion.type) {
|
||||
case "request": {
|
||||
const { request } = symbolCompletion;
|
||||
switch (request.kind) {
|
||||
case "JsDocTagName":
|
||||
return JsDoc.getJSDocTagNameCompletionDetails(name);
|
||||
case "JsDocTag":
|
||||
return JsDoc.getJSDocTagCompletionDetails(name);
|
||||
case "JsDocParameterName":
|
||||
return JsDoc.getJSDocParameterNameCompletionDetails(name);
|
||||
default:
|
||||
return Debug.assertNever(request);
|
||||
}
|
||||
}
|
||||
case "symbol": {
|
||||
const { symbol, location, symbolToOriginInfoMap } = symbolCompletion;
|
||||
const codeActions = getCompletionEntryCodeActions(symbolToOriginInfoMap, symbol, typeChecker, host, compilerOptions, sourceFile, rulesProvider);
|
||||
const kindModifiers = SymbolDisplay.getSymbolModifiers(symbol);
|
||||
const { displayParts, documentation, symbolKind, tags } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, location, location, SemanticMeaning.All);
|
||||
return { name, kindModifiers, kind: symbolKind, displayParts, documentation, tags, codeActions };
|
||||
return { name, kindModifiers, kind: symbolKind, displayParts, documentation, tags, codeActions, source: source === undefined ? undefined : [textPart(source)] };
|
||||
}
|
||||
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)) {
|
||||
return {
|
||||
name,
|
||||
kind: ScriptElementKind.keyword,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
displayParts: [displayPart(name, SymbolDisplayPartKind.keyword)],
|
||||
documentation: undefined,
|
||||
tags: undefined,
|
||||
codeActions: undefined,
|
||||
source: undefined,
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// Didn't find a symbol with this name. See if we can find a keyword instead.
|
||||
const keywordCompletion = forEach(
|
||||
getKeywordCompletions(KeywordCompletionFilters.None),
|
||||
c => c.name === name
|
||||
);
|
||||
if (keywordCompletion) {
|
||||
return {
|
||||
name,
|
||||
kind: ScriptElementKind.keyword,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
displayParts: [displayPart(name, SymbolDisplayPartKind.keyword)],
|
||||
documentation: undefined,
|
||||
tags: undefined,
|
||||
codeActions: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getCompletionEntryCodeActions(symbolToOriginInfoMap: SymbolOriginInfoMap, symbol: Symbol, checker: TypeChecker, host: LanguageServiceHost, compilerOptions: CompilerOptions, sourceFile: SourceFile, rulesProvider: formatting.RulesProvider): CodeAction[] | undefined {
|
||||
const symbolOriginInfo = symbolToOriginInfoMap[getUniqueSymbolId(symbol, checker)];
|
||||
function getCompletionEntryCodeActions(
|
||||
symbolToOriginInfoMap: SymbolOriginInfoMap,
|
||||
symbol: Symbol,
|
||||
checker: TypeChecker,
|
||||
host: LanguageServiceHost,
|
||||
compilerOptions: CompilerOptions,
|
||||
sourceFile: SourceFile,
|
||||
rulesProvider: formatting.RulesProvider,
|
||||
): CodeAction[] | undefined {
|
||||
const symbolOriginInfo = symbolToOriginInfoMap[getSymbolId(symbol)];
|
||||
if (!symbolOriginInfo) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -407,29 +495,20 @@ namespace ts.Completions {
|
||||
compilerOptions: CompilerOptions,
|
||||
sourceFile: SourceFile,
|
||||
position: number,
|
||||
entryName: string,
|
||||
entryId: CompletionEntryIdentifier,
|
||||
allSourceFiles: ReadonlyArray<SourceFile>,
|
||||
): Symbol | undefined {
|
||||
// Compute all the completion symbols again.
|
||||
const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles);
|
||||
if (!completionData) {
|
||||
return undefined;
|
||||
}
|
||||
const { symbols, allowStringLiteral } = completionData;
|
||||
// Find the symbol with the matching entry name.
|
||||
// We don't need to perform character checks here because we're only comparing the
|
||||
// name against 'entryName' (which is known to be good), not building a new
|
||||
// completion entry.
|
||||
return find(symbols, s => getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral) === entryName);
|
||||
const completion = getSymbolCompletionFromEntryId(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles);
|
||||
return completion.type === "symbol" ? completion.symbol : undefined;
|
||||
}
|
||||
|
||||
interface CompletionData {
|
||||
symbols: Symbol[];
|
||||
symbols: ReadonlyArray<Symbol>;
|
||||
isGlobalCompletion: boolean;
|
||||
isMemberCompletion: boolean;
|
||||
allowStringLiteral: boolean;
|
||||
isNewIdentifierLocation: boolean;
|
||||
location: Node;
|
||||
location: Node | undefined;
|
||||
isRightOfDot: boolean;
|
||||
request?: Request;
|
||||
keywordFilters: KeywordCompletionFilters;
|
||||
@@ -443,6 +522,7 @@ namespace ts.Completions {
|
||||
sourceFile: SourceFile,
|
||||
position: number,
|
||||
allSourceFiles: ReadonlyArray<SourceFile>,
|
||||
options: GetCompletionsAtPositionOptions,
|
||||
): CompletionData | undefined {
|
||||
const isJavaScriptFile = isSourceFileJavaScript(sourceFile);
|
||||
|
||||
@@ -516,7 +596,7 @@ namespace ts.Completions {
|
||||
|
||||
if (request) {
|
||||
return {
|
||||
symbols: undefined,
|
||||
symbols: emptyArray,
|
||||
isGlobalCompletion: false,
|
||||
isMemberCompletion: false,
|
||||
allowStringLiteral: false,
|
||||
@@ -840,7 +920,9 @@ namespace ts.Completions {
|
||||
const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias;
|
||||
|
||||
symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings);
|
||||
getSymbolsFromOtherSourceFileExports(symbols, previousToken && isIdentifier(previousToken) ? previousToken.text : "");
|
||||
if (options.includeExternalModuleExports) {
|
||||
getSymbolsFromOtherSourceFileExports(symbols, previousToken && isIdentifier(previousToken) ? previousToken.text : "");
|
||||
}
|
||||
filterGlobalCompletion(symbols);
|
||||
|
||||
return true;
|
||||
@@ -923,7 +1005,6 @@ namespace ts.Completions {
|
||||
|
||||
function getSymbolsFromOtherSourceFileExports(symbols: Symbol[], tokenText: string): void {
|
||||
const tokenTextLowerCase = tokenText.toLowerCase();
|
||||
const symbolIdMap = arrayToNumericMap(symbols, s => getUniqueSymbolId(s, typeChecker));
|
||||
|
||||
codefix.forEachExternalModule(typeChecker, allSourceFiles, moduleSymbol => {
|
||||
if (moduleSymbol === sourceFile.symbol) {
|
||||
@@ -941,10 +1022,14 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
|
||||
const id = getUniqueSymbolId(symbol, typeChecker);
|
||||
if (!symbolIdMap[id] && stringContainsCharactersInOrder(name.toLowerCase(), tokenTextLowerCase)) {
|
||||
if (symbol.declarations && symbol.declarations.some(d => isExportSpecifier(d) && !!d.parent.parent.moduleSpecifier)) {
|
||||
// Don't add a completion for a re-export, only for the original.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stringContainsCharactersInOrder(name.toLowerCase(), tokenTextLowerCase)) {
|
||||
symbols.push(symbol);
|
||||
symbolToOriginInfoMap[id] = { moduleSymbol, isDefaultExport };
|
||||
symbolToOriginInfoMap[getSymbolId(symbol)] = { moduleSymbol, isDefaultExport };
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1776,6 +1861,18 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
|
||||
// If the symbol is for a member of an object type and is the internal name of an ES
|
||||
// symbol, it is not a valid entry. Internal names for ES symbols start with "__@"
|
||||
if (symbol.flags & SymbolFlags.ClassMember) {
|
||||
const escapedName = symbol.escapedName as string;
|
||||
if (escapedName.length >= 3 &&
|
||||
escapedName.charCodeAt(0) === CharacterCodes._ &&
|
||||
escapedName.charCodeAt(1) === CharacterCodes._ &&
|
||||
escapedName.charCodeAt(2) === CharacterCodes.at) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return getCompletionEntryDisplayName(name, target, performCharacterChecks, allowStringLiteral);
|
||||
}
|
||||
|
||||
|
||||
@@ -714,6 +714,11 @@ namespace ts.formatting {
|
||||
|
||||
processNode(child, childContextNode, childStartLine, undecoratedChildStartLine, childIndentation.indentation, childIndentation.delta);
|
||||
|
||||
if (child.kind === SyntaxKind.JsxText) {
|
||||
const range: TextRange = { pos: child.getStart(), end: child.getEnd() };
|
||||
indentMultilineCommentOrJsxText(range, childIndentation.indentation, /*firstLineIsIndented*/ true, /*indentFinalLine*/ false);
|
||||
}
|
||||
|
||||
childContextNode = node;
|
||||
|
||||
if (isFirstListItem && parent.kind === SyntaxKind.ArrayLiteralExpression && inheritedIndentation === Constants.Unknown) {
|
||||
@@ -833,7 +838,7 @@ namespace ts.formatting {
|
||||
switch (triviaItem.kind) {
|
||||
case SyntaxKind.MultiLineCommentTrivia:
|
||||
if (triviaInRange) {
|
||||
indentMultilineComment(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia);
|
||||
indentMultilineCommentOrJsxText(triviaItem, commentIndentation, /*firstLineIsIndented*/ !indentNextTokenOrTrivia);
|
||||
}
|
||||
indentNextTokenOrTrivia = false;
|
||||
break;
|
||||
@@ -985,7 +990,7 @@ namespace ts.formatting {
|
||||
return indentationString !== sourceFile.text.substr(startLinePosition, indentationString.length);
|
||||
}
|
||||
|
||||
function indentMultilineComment(commentRange: TextRange, indentation: number, firstLineIsIndented: boolean) {
|
||||
function indentMultilineCommentOrJsxText(commentRange: TextRange, indentation: number, firstLineIsIndented: boolean, indentFinalLine = true) {
|
||||
// split comment in lines
|
||||
let startLine = sourceFile.getLineAndCharacterOfPosition(commentRange.pos).line;
|
||||
const endLine = sourceFile.getLineAndCharacterOfPosition(commentRange.end).line;
|
||||
@@ -1006,7 +1011,9 @@ namespace ts.formatting {
|
||||
startPos = getStartPositionOfLine(line + 1, sourceFile);
|
||||
}
|
||||
|
||||
parts.push({ pos: startPos, end: commentRange.end });
|
||||
if (indentFinalLine) {
|
||||
parts.push({ pos: startPos, end: commentRange.end });
|
||||
}
|
||||
}
|
||||
|
||||
const startLinePos = getStartPositionOfLine(startLine, sourceFile);
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
namespace ts.formatting {
|
||||
|
||||
export class RuleOperationContext {
|
||||
private readonly customContextChecks: { (context: FormattingContext): boolean; }[];
|
||||
private readonly customContextChecks: ((context: FormattingContext) => boolean)[];
|
||||
|
||||
constructor(...funcs: { (context: FormattingContext): boolean; }[]) {
|
||||
constructor(...funcs: ((context: FormattingContext) => boolean)[]) {
|
||||
this.customContextChecks = funcs;
|
||||
}
|
||||
|
||||
|
||||
@@ -849,7 +849,7 @@ namespace ts.formatting {
|
||||
}
|
||||
|
||||
static NodeIsInDecoratorContext(node: Node): boolean {
|
||||
while (isPartOfExpression(node)) {
|
||||
while (isExpressionNode(node)) {
|
||||
node = node.parent;
|
||||
}
|
||||
return node.kind === SyntaxKind.Decorator;
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace ts.GoToDefinition {
|
||||
// }
|
||||
// bar<Test>(({pr/*goto*/op1})=>{});
|
||||
if (isPropertyName(node) && isBindingElement(node.parent) && isObjectBindingPattern(node.parent.parent) &&
|
||||
(node === (node.parent.propertyName || node.parent.name))) {
|
||||
(node === (node.parent.propertyName || node.parent.name))) {
|
||||
const type = typeChecker.getTypeAtLocation(node.parent.parent);
|
||||
if (type) {
|
||||
const propSymbols = getPropertySymbolsFromType(type, node);
|
||||
@@ -149,6 +149,28 @@ namespace ts.GoToDefinition {
|
||||
return getDefinitionFromSymbol(typeChecker, type.symbol, node);
|
||||
}
|
||||
|
||||
export function getDefinitionAndBoundSpan(program: Program, sourceFile: SourceFile, position: number): DefinitionInfoAndBoundSpan {
|
||||
const definitions = getDefinitionAtPosition(program, sourceFile, position);
|
||||
|
||||
if (!definitions || definitions.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Check if position is on triple slash reference.
|
||||
const comment = findReferenceInPosition(sourceFile.referencedFiles, position) || findReferenceInPosition(sourceFile.typeReferenceDirectives, position);
|
||||
if (comment) {
|
||||
return {
|
||||
definitions,
|
||||
textSpan: createTextSpanFromBounds(comment.pos, comment.end)
|
||||
};
|
||||
}
|
||||
|
||||
const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
|
||||
const textSpan = createTextSpan(node.getStart(), node.getWidth());
|
||||
|
||||
return { definitions, textSpan };
|
||||
}
|
||||
|
||||
// Go to the original declaration for cases:
|
||||
//
|
||||
// (1) when the aliased symbol was declared in the location(parent).
|
||||
|
||||
+55
-4
@@ -65,19 +65,44 @@ namespace ts.JsDoc {
|
||||
return documentationComment;
|
||||
}
|
||||
|
||||
export function getJsDocTagsFromDeclarations(declarations?: Declaration[]) {
|
||||
export function getJsDocTagsFromDeclarations(declarations?: Declaration[]): JSDocTagInfo[] {
|
||||
// Only collect doc comments from duplicate declarations once.
|
||||
const tags: JSDocTagInfo[] = [];
|
||||
forEachUnique(declarations, declaration => {
|
||||
for (const tag of getJSDocTags(declaration)) {
|
||||
if (tag.kind === SyntaxKind.JSDocTag) {
|
||||
tags.push({ name: tag.tagName.text, text: tag.comment });
|
||||
}
|
||||
tags.push({ name: tag.tagName.text, text: getCommentText(tag) });
|
||||
}
|
||||
});
|
||||
return tags;
|
||||
}
|
||||
|
||||
function getCommentText(tag: JSDocTag): string {
|
||||
const { comment } = tag;
|
||||
switch (tag.kind) {
|
||||
case SyntaxKind.JSDocAugmentsTag:
|
||||
return withNode((tag as JSDocAugmentsTag).class);
|
||||
case SyntaxKind.JSDocTemplateTag:
|
||||
return withList((tag as JSDocTemplateTag).typeParameters);
|
||||
case SyntaxKind.JSDocTypeTag:
|
||||
return withNode((tag as JSDocTypeTag).typeExpression);
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
case SyntaxKind.JSDocPropertyTag:
|
||||
case SyntaxKind.JSDocParameterTag:
|
||||
const { name } = tag as JSDocTypedefTag | JSDocPropertyTag | JSDocParameterTag;
|
||||
return name ? withNode(name) : comment;
|
||||
default:
|
||||
return comment;
|
||||
}
|
||||
|
||||
function withNode(node: Node) {
|
||||
return `${node.getText()} ${comment}`;
|
||||
}
|
||||
|
||||
function withList(list: NodeArray<Node>): string {
|
||||
return `${list.map(x => x.getText())} ${comment}`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through 'array' by index and performs the callback on each element of array until the callback
|
||||
* returns a truthy value, then returns that value.
|
||||
@@ -108,6 +133,8 @@ namespace ts.JsDoc {
|
||||
}));
|
||||
}
|
||||
|
||||
export const getJSDocTagNameCompletionDetails = getJSDocTagCompletionDetails;
|
||||
|
||||
export function getJSDocTagCompletions(): CompletionEntry[] {
|
||||
return jsDocTagCompletionEntries || (jsDocTagCompletionEntries = ts.map(jsDocTagNames, tagName => {
|
||||
return {
|
||||
@@ -119,6 +146,18 @@ namespace ts.JsDoc {
|
||||
}));
|
||||
}
|
||||
|
||||
export function getJSDocTagCompletionDetails(name: string): CompletionEntryDetails {
|
||||
return {
|
||||
name,
|
||||
kind: ScriptElementKind.unknown, // TODO: should have its own kind?
|
||||
kindModifiers: "",
|
||||
displayParts: [textPart(name)],
|
||||
documentation: emptyArray,
|
||||
tags: emptyArray,
|
||||
codeActions: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
export function getJSDocParameterNameCompletions(tag: JSDocParameterTag): CompletionEntry[] {
|
||||
if (!isIdentifier(tag.name)) {
|
||||
return emptyArray;
|
||||
@@ -141,6 +180,18 @@ namespace ts.JsDoc {
|
||||
});
|
||||
}
|
||||
|
||||
export function getJSDocParameterNameCompletionDetails(name: string): CompletionEntryDetails {
|
||||
return {
|
||||
name,
|
||||
kind: ScriptElementKind.parameterElement,
|
||||
kindModifiers: "",
|
||||
displayParts: [textPart(name)],
|
||||
documentation: emptyArray,
|
||||
tags: emptyArray,
|
||||
codeActions: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if position points to a valid position to add JSDoc comments, and if so,
|
||||
* returns the appropriate template. Otherwise returns an empty string.
|
||||
|
||||
@@ -1,34 +1,27 @@
|
||||
/* @internal */
|
||||
namespace ts.Completions.PathCompletions {
|
||||
export function getStringLiteralCompletionEntriesFromModuleNames(node: StringLiteral, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionInfo {
|
||||
export function getStringLiteralCompletionsFromModuleNames(node: StringLiteral, compilerOptions: CompilerOptions, host: LanguageServiceHost, typeChecker: TypeChecker): CompletionEntry[] {
|
||||
const literalValue = normalizeSlashes(node.text);
|
||||
|
||||
const scriptPath = node.getSourceFile().path;
|
||||
const scriptDirectory = getDirectoryPath(scriptPath);
|
||||
|
||||
const span = getDirectoryFragmentTextSpan((<StringLiteral>node).text, node.getStart() + 1);
|
||||
let entries: CompletionEntry[];
|
||||
if (isPathRelativeToScript(literalValue) || isRootedDiskPath(literalValue)) {
|
||||
const extensions = getSupportedExtensions(compilerOptions);
|
||||
if (compilerOptions.rootDirs) {
|
||||
entries = getCompletionEntriesForDirectoryFragmentWithRootDirs(
|
||||
return getCompletionEntriesForDirectoryFragmentWithRootDirs(
|
||||
compilerOptions.rootDirs, literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, span, compilerOptions, host, scriptPath);
|
||||
}
|
||||
else {
|
||||
entries = getCompletionEntriesForDirectoryFragment(
|
||||
return getCompletionEntriesForDirectoryFragment(
|
||||
literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, span, host, scriptPath);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Check for node modules
|
||||
entries = getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, span, compilerOptions, host, typeChecker);
|
||||
return getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, span, compilerOptions, host, typeChecker);
|
||||
}
|
||||
return {
|
||||
isGlobalCompletion: false,
|
||||
isMemberCompletion: false,
|
||||
isNewIdentifierLocation: true,
|
||||
entries
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,15 +30,15 @@ namespace ts.Completions.PathCompletions {
|
||||
*/
|
||||
function getBaseDirectoriesFromRootDirs(rootDirs: string[], basePath: string, scriptPath: string, ignoreCase: boolean): string[] {
|
||||
// Make all paths absolute/normalized if they are not already
|
||||
rootDirs = map(rootDirs, rootDirectory => normalizePath(isRootedDiskPath(rootDirectory) ? rootDirectory : combinePaths(basePath, rootDirectory)));
|
||||
rootDirs = rootDirs.map(rootDirectory => normalizePath(isRootedDiskPath(rootDirectory) ? rootDirectory : combinePaths(basePath, rootDirectory)));
|
||||
|
||||
// Determine the path to the directory containing the script relative to the root directory it is contained within
|
||||
const relativeDirectory = forEach(rootDirs, rootDirectory =>
|
||||
const relativeDirectory = firstDefined(rootDirs, rootDirectory =>
|
||||
containsPath(rootDirectory, scriptPath, basePath, ignoreCase) ? scriptPath.substr(rootDirectory.length) : undefined);
|
||||
|
||||
// Now find a path for each potential directory that is to be merged with the one containing the script
|
||||
return deduplicate(
|
||||
map(rootDirs, rootDirectory => combinePaths(rootDirectory, relativeDirectory)),
|
||||
rootDirs.map(rootDirectory => combinePaths(rootDirectory, relativeDirectory)),
|
||||
equateStringsCaseSensitive,
|
||||
compareStringsCaseSensitive);
|
||||
}
|
||||
@@ -147,8 +140,8 @@ namespace ts.Completions.PathCompletions {
|
||||
|
||||
let result: CompletionEntry[];
|
||||
|
||||
const fileExtensions = getSupportedExtensions(compilerOptions);
|
||||
if (baseUrl) {
|
||||
const fileExtensions = getSupportedExtensions(compilerOptions);
|
||||
const projectDir = compilerOptions.project || host.getCurrentDirectory();
|
||||
const absolute = isRootedDiskPath(baseUrl) ? baseUrl : combinePaths(projectDir, baseUrl);
|
||||
result = getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/ false, span, host);
|
||||
@@ -179,6 +172,15 @@ namespace ts.Completions.PathCompletions {
|
||||
result = [];
|
||||
}
|
||||
|
||||
if (compilerOptions.moduleResolution === ts.ModuleResolutionKind.NodeJs) {
|
||||
forEachAncestorDirectory(scriptPath, ancestor => {
|
||||
const nodeModules = combinePaths(ancestor, "node_modules");
|
||||
if (host.directoryExists(nodeModules)) {
|
||||
getCompletionEntriesForDirectoryFragment(fragment, nodeModules, fileExtensions, /*includeExtensions*/ false, span, host, /*exclude*/ undefined, result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span, result);
|
||||
|
||||
for (const moduleName of enumeratePotentialNonRelativeModules(fragment, scriptPath, compilerOptions, typeChecker, host)) {
|
||||
@@ -277,61 +279,35 @@ namespace ts.Completions.PathCompletions {
|
||||
return deduplicate(nonRelativeModuleNames, equateStringsCaseSensitive, compareStringsCaseSensitive);
|
||||
}
|
||||
|
||||
export function getTripleSlashReferenceCompletion(sourceFile: SourceFile, position: number, compilerOptions: CompilerOptions, host: LanguageServiceHost): CompletionInfo {
|
||||
export function getTripleSlashReferenceCompletion(sourceFile: SourceFile, position: number, compilerOptions: CompilerOptions, host: LanguageServiceHost): CompletionEntry[] | undefined {
|
||||
const token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
|
||||
if (!token) {
|
||||
return undefined;
|
||||
}
|
||||
const commentRanges: CommentRange[] = getLeadingCommentRanges(sourceFile.text, token.pos);
|
||||
|
||||
if (!commentRanges || !commentRanges.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const range = forEach(commentRanges, commentRange => position >= commentRange.pos && position <= commentRange.end && commentRange);
|
||||
|
||||
const commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos);
|
||||
const range = commentRanges && find(commentRanges, commentRange => position >= commentRange.pos && position <= commentRange.end);
|
||||
if (!range) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const completionInfo: CompletionInfo = {
|
||||
/**
|
||||
* We don't want the editor to offer any other completions, such as snippets, inside a comment.
|
||||
*/
|
||||
isGlobalCompletion: false,
|
||||
isMemberCompletion: false,
|
||||
/**
|
||||
* The user may type in a path that doesn't yet exist, creating a "new identifier"
|
||||
* with respect to the collection of identifiers the server is aware of.
|
||||
*/
|
||||
isNewIdentifierLocation: true,
|
||||
|
||||
entries: []
|
||||
};
|
||||
|
||||
const text = sourceFile.text.substr(range.pos, position - range.pos);
|
||||
|
||||
const text = sourceFile.text.slice(range.pos, position);
|
||||
const match = tripleSlashDirectiveFragmentRegex.exec(text);
|
||||
|
||||
if (match) {
|
||||
const prefix = match[1];
|
||||
const kind = match[2];
|
||||
const toComplete = match[3];
|
||||
|
||||
const scriptPath = getDirectoryPath(sourceFile.path);
|
||||
if (kind === "path") {
|
||||
// Give completions for a relative path
|
||||
const span: TextSpan = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length);
|
||||
completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/ true, span, host, sourceFile.path);
|
||||
}
|
||||
else {
|
||||
// Give completions based on the typings available
|
||||
const span: TextSpan = { start: range.pos + prefix.length, length: match[0].length - prefix.length };
|
||||
completionInfo.entries = getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span);
|
||||
}
|
||||
if (!match) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return completionInfo;
|
||||
const [, prefix, kind, toComplete] = match;
|
||||
const scriptPath = getDirectoryPath(sourceFile.path);
|
||||
switch (kind) {
|
||||
case "path": {
|
||||
// Give completions for a relative path
|
||||
const span = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length);
|
||||
return getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/ true, span, host, sourceFile.path);
|
||||
}
|
||||
case "types": {
|
||||
// Give completions based on the typings available
|
||||
const span = createTextSpan(range.pos + prefix.length, match[0].length - prefix.length);
|
||||
return getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span);
|
||||
}
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function getCompletionEntriesFromTypings(host: LanguageServiceHost, options: CompilerOptions, scriptPath: string, span: TextSpan, result: CompletionEntry[] = []): CompletionEntry[] {
|
||||
@@ -379,26 +355,15 @@ namespace ts.Completions.PathCompletions {
|
||||
}
|
||||
}
|
||||
|
||||
function findPackageJsons(currentDir: string, host: LanguageServiceHost): string[] {
|
||||
function findPackageJsons(directory: string, host: LanguageServiceHost): string[] {
|
||||
const paths: string[] = [];
|
||||
let currentConfigPath: string;
|
||||
while (true) {
|
||||
currentConfigPath = findConfigFile(currentDir, (f) => tryFileExists(host, f), "package.json");
|
||||
if (currentConfigPath) {
|
||||
paths.push(currentConfigPath);
|
||||
|
||||
currentDir = getDirectoryPath(currentConfigPath);
|
||||
const parent = getDirectoryPath(currentDir);
|
||||
if (currentDir === parent) {
|
||||
break;
|
||||
}
|
||||
currentDir = parent;
|
||||
forEachAncestorDirectory(directory, ancestor => {
|
||||
const currentConfigPath = findConfigFile(ancestor, (f) => tryFileExists(host, f), "package.json");
|
||||
if (!currentConfigPath) {
|
||||
return true; // break out
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
paths.push(currentConfigPath);
|
||||
});
|
||||
return paths;
|
||||
}
|
||||
|
||||
|
||||
@@ -244,12 +244,52 @@ namespace ts.refactor.extractSymbol {
|
||||
return { targetRange: { range: statements, facts: rangeFacts, declarations } };
|
||||
}
|
||||
|
||||
if (isReturnStatement(start) && !start.expression) {
|
||||
// Makes no sense to extract an expression-less return statement.
|
||||
return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractRange)] };
|
||||
}
|
||||
|
||||
// We have a single node (start)
|
||||
const errors = checkRootNode(start) || checkNode(start);
|
||||
const node = refineNode(start);
|
||||
|
||||
const errors = checkRootNode(node) || checkNode(node);
|
||||
if (errors) {
|
||||
return { errors };
|
||||
}
|
||||
return { targetRange: { range: getStatementOrExpressionRange(start), facts: rangeFacts, declarations } };
|
||||
return { targetRange: { range: getStatementOrExpressionRange(node), facts: rangeFacts, declarations } };
|
||||
|
||||
/**
|
||||
* Attempt to refine the extraction node (generally, by shrinking it) to produce better results.
|
||||
* @param node The unrefined extraction node.
|
||||
*/
|
||||
function refineNode(node: Node) {
|
||||
if (isReturnStatement(node)) {
|
||||
if (node.expression) {
|
||||
return node.expression;
|
||||
}
|
||||
}
|
||||
else if (isVariableStatement(node)) {
|
||||
let numInitializers = 0;
|
||||
let lastInitializer: Expression | undefined = undefined;
|
||||
for (const declaration of node.declarationList.declarations) {
|
||||
if (declaration.initializer) {
|
||||
numInitializers++;
|
||||
lastInitializer = declaration.initializer;
|
||||
}
|
||||
}
|
||||
if (numInitializers === 1) {
|
||||
return lastInitializer;
|
||||
}
|
||||
// No special handling if there are multiple initializers.
|
||||
}
|
||||
else if (isVariableDeclaration(node)) {
|
||||
if (node.initializer) {
|
||||
return node.initializer;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function checkRootNode(node: Node): Diagnostic[] | undefined {
|
||||
if (isIdentifier(isExpressionStatement(node) ? node.expression : node)) {
|
||||
@@ -291,11 +331,11 @@ namespace ts.refactor.extractSymbol {
|
||||
Continue = 1 << 1,
|
||||
Return = 1 << 2
|
||||
}
|
||||
if (!isStatement(nodeToCheck) && !(isPartOfExpression(nodeToCheck) && isExtractableExpression(nodeToCheck))) {
|
||||
if (!isStatement(nodeToCheck) && !(isExpressionNode(nodeToCheck) && isExtractableExpression(nodeToCheck))) {
|
||||
return [createDiagnosticForNode(nodeToCheck, Messages.StatementOrExpressionExpected)];
|
||||
}
|
||||
|
||||
if (isInAmbientContext(nodeToCheck)) {
|
||||
if (nodeToCheck.flags & NodeFlags.Ambient) {
|
||||
return [createDiagnosticForNode(nodeToCheck, Messages.CannotExtractAmbientBlock)];
|
||||
}
|
||||
|
||||
@@ -451,7 +491,7 @@ namespace ts.refactor.extractSymbol {
|
||||
if (isStatement(node)) {
|
||||
return [node];
|
||||
}
|
||||
else if (isPartOfExpression(node)) {
|
||||
else if (isExpressionNode(node)) {
|
||||
// If our selection is the expression in an ExpressionStatement, expand
|
||||
// the selection to include the enclosing Statement (this stops us
|
||||
// from trying to care about the return value of the extracted function
|
||||
@@ -690,7 +730,7 @@ namespace ts.refactor.extractSymbol {
|
||||
let type = checker.getTypeOfSymbolAtLocation(usage.symbol, usage.node);
|
||||
// Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {"
|
||||
type = checker.getBaseTypeOfLiteralType(type);
|
||||
typeNode = checker.typeToTypeNode(type, node, NodeBuilderFlags.NoTruncation);
|
||||
typeNode = checker.typeToTypeNode(type, scope, NodeBuilderFlags.NoTruncation);
|
||||
}
|
||||
|
||||
const paramDecl = createParameter(
|
||||
|
||||
@@ -12,8 +12,7 @@ namespace ts.refactor.installTypesForPackage {
|
||||
registerRefactor(installTypesForPackage);
|
||||
|
||||
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
|
||||
const options = context.program.getCompilerOptions();
|
||||
if (options.noImplicitAny || options.strict) {
|
||||
if (getStrictOptionValue(context.program.getCompilerOptions(), "noImplicitAny")) {
|
||||
// Then it will be available via `fixCannotFindModule`.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
/// <reference path="convertFunctionToEs6Class.ts" />
|
||||
/// <reference path="extractSymbol.ts" />
|
||||
/// <reference path="installTypesForPackage.ts" />
|
||||
/// <reference path="useDefaultImport.ts" />
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/* @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);
|
||||
|
||||
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
|
||||
const { file, startPosition, program } = context;
|
||||
|
||||
if (!program.getCompilerOptions().allowSyntheticDefaultImports) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const importInfo = getConvertibleImportAtPosition(file, startPosition);
|
||||
if (!importInfo) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const module = ts.getResolvedModule(file, importInfo.moduleSpecifier.text);
|
||||
const resolvedFile = program.getSourceFile(module.resolvedFileName);
|
||||
if (!(resolvedFile.externalModuleIndicator && isExportAssignment(resolvedFile.externalModuleIndicator) && resolvedFile.externalModuleIndicator.isExportEquals)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
name: useDefaultImport.name,
|
||||
description: useDefaultImport.description,
|
||||
actions: [
|
||||
{
|
||||
description: useDefaultImport.description,
|
||||
name: actionName,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function getEditsForAction(context: RefactorContext, _actionName: string): RefactorEditInfo | undefined {
|
||||
const { file, startPosition } = context;
|
||||
Debug.assertEqual(actionName, _actionName);
|
||||
const importInfo = getConvertibleImportAtPosition(file, startPosition);
|
||||
if (!importInfo) {
|
||||
return undefined;
|
||||
}
|
||||
const { importStatement, name, moduleSpecifier } = importInfo;
|
||||
const newImportClause = createImportClause(name, /*namedBindings*/ undefined);
|
||||
const newImportStatement = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newImportClause, moduleSpecifier);
|
||||
return {
|
||||
edits: textChanges.ChangeTracker.with(context, t => t.replaceNode(file, importStatement, newImportStatement)),
|
||||
renameFilename: undefined,
|
||||
renameLocation: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
function getConvertibleImportAtPosition(
|
||||
file: SourceFile,
|
||||
startPosition: number,
|
||||
): { importStatement: AnyImportSyntax, name: Identifier, moduleSpecifier: StringLiteral } | undefined {
|
||||
let node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
|
||||
while (true) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
const eq = node as ImportEqualsDeclaration;
|
||||
const { moduleReference } = eq;
|
||||
return moduleReference.kind === SyntaxKind.ExternalModuleReference && isStringLiteral(moduleReference.expression)
|
||||
? { importStatement: eq, name: eq.name, moduleSpecifier: moduleReference.expression }
|
||||
: undefined;
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
const d = node as ImportDeclaration;
|
||||
const { importClause } = d;
|
||||
return !importClause.name && importClause.namedBindings.kind === SyntaxKind.NamespaceImport && isStringLiteral(d.moduleSpecifier)
|
||||
? { importStatement: d, name: importClause.namedBindings.name, moduleSpecifier: d.moduleSpecifier }
|
||||
: undefined;
|
||||
// For known child node kinds of convertible imports, try again with parent node.
|
||||
case SyntaxKind.NamespaceImport:
|
||||
case SyntaxKind.ExternalModuleReference:
|
||||
case SyntaxKind.ImportKeyword:
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.AsteriskToken:
|
||||
break;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user