mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into wip-master-statelessOverload
# Conflicts: # src/compiler/factory.ts
This commit is contained in:
@@ -8,11 +8,14 @@ Alexander Rusakov <a_s_rusakov@mail.ru>
|
||||
Alex Eagle <alexeagle@google.com>
|
||||
Anatoly Ressin <anatoly.ressin@icloud.com>
|
||||
Anders Hejlsberg <andersh@microsoft.com> unknown <andersh@AndersX1.NOE.Nokia.com> unknown <andersh@andersh-yoga.redmond.corp.microsoft.com>
|
||||
about-code <about-code@users.noreply.github.com> # Andreas Martin
|
||||
Andrej Baran <andrej.baran@gmail.com>
|
||||
Andrew Ochsner <andrew.ochsner@wipro.com>
|
||||
Andrew Z Allen <me@andrewzallen.com>
|
||||
Andy Hanson <anhans@microsoft.com> Andy <anhans@microsoft.com>
|
||||
Anil Anar <anilanar@hotmail.com>
|
||||
Anton Tolmachev <myste@mail.ru>
|
||||
Anubha Mathur <anubmat@microsoft.com> anubmat <anubmat@microsoft.com>
|
||||
Arnavion <arnavion@gmail.com> # Arnav Singh
|
||||
Arthur Ozga <aozgaa@umich.edu> Arthur Ozga <t-arthoz@microsoft.com> Arthur Ozga <aozgaa-ms@outlook.com> Arthur Ozga <aozgaa@users.noreply.github.com> Arthur Ozga <arozga@microsoft.com>
|
||||
Asad Saeeduddin <masaeedu@gmail.com>
|
||||
@@ -37,6 +40,7 @@ Dan Corder <dev@dancorder.com>
|
||||
Dan Quirk <danquirk@microsoft.com> Dan Quirk <danquirk@users.noreply.github.com> nknown <danquirk@DANQUIRK1.redmond.corp.microsoft.com>
|
||||
Daniel Rosenwasser <drosen@microsoft.com> Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com> Daniel Rosenwasser <DanielRosenwasser@gmail.com> Daniel Rosenwasser <Daniel.Rosenwasser@microsoft.com> Daniel Rosenwasser <DanielRosenwasser@microsoft.com>
|
||||
David Li <jiawei.davidli@gmail.com>
|
||||
David Sheldrick <david@futurice.com>
|
||||
David Souther <davidsouther@gmail.com>
|
||||
Denis Nedelyaev <denvned@gmail.com>
|
||||
Dick van den Brink <d_vandenbrink@outlook.com> unknown <d_vandenbrink@outlook.com> unknown <d_vandenbrink@live.com>
|
||||
@@ -52,6 +56,7 @@ Evan Sebastian <evanlhoini@gmail.com>
|
||||
Eyas <eyas.sharaiha@gmail.com> # Eyas Sharaiha
|
||||
Fabian Cook <faybecook@gmail.com>
|
||||
falsandtru <falsandtru@users.noreply.github.com> # @falsandtru
|
||||
flowmemo <flowmemo@outlook.com> # @flowmemo
|
||||
Frank Wallis <fwallis@outlook.com>
|
||||
František Žiacik <fziacik@gratex.com> František Žiacik <ziacik@gmail.com>
|
||||
Gabe Moothart <gmoothart@gmail.com>
|
||||
@@ -62,6 +67,7 @@ Graeme Wicksted <graeme.wicksted@gmail.com>
|
||||
Guillaume Salles <guillaume.salles@me.com>
|
||||
Guy Bedford <guybedford@gmail.com> guybedford <guybedford@gmail.com>
|
||||
Harald Niesche <harald@niesche.de>
|
||||
Homa Wong <homawong@gmail.com>
|
||||
Iain Monro <iain.monro@softwire.com>
|
||||
Ingvar Stepanyan <me@rreverser.com>
|
||||
impinball <impinball@gmail.com> # Isiah Meadows
|
||||
@@ -81,6 +87,7 @@ Jonathan Park <jpark@daptiv.com>
|
||||
Jonathan Turner <jont@microsoft.com> Jonathan Turner <probata@hotmail.com>
|
||||
Jonathan Toland <toland@dnalot.com>
|
||||
Jesse Schalken <me@jesseschalken.com>
|
||||
Joel Day <joelday@gmail.com>
|
||||
Josh Abernathy <joshaber@gmail.com> joshaber <joshaber@gmail.com>
|
||||
Josh Kalderimis <josh.kalderimis@gmail.com>
|
||||
Josh Soref <jsoref@users.noreply.github.com>
|
||||
@@ -95,10 +102,12 @@ Kanchalai Tanglertsampan <yuisu@microsoft.com> Yui T <yuisu@microsoft.com>
|
||||
Kanchalai Tanglertsampan <yuisu@microsoft.com> Yui <yuit@users.noreply.github.com>
|
||||
Kanchalai Tanglertsampan <yuisu@microsoft.com> Yui <yuisu@microsoft.com>
|
||||
Kanchalai Tanglertsampan <yuisu@microsoft.com> yui T <yuisu@microsoft.com>
|
||||
Kārlis Gaņģis <Knagis@users.noreply.github.com>
|
||||
Keith Mashinter <kmashint@yahoo.com> kmashint <kmashint@yahoo.com>
|
||||
Ken Howard <ken@simplicatedweb.com>
|
||||
Kevin Lang <klang2012@gmail.com>
|
||||
kimamula <kenji.imamula@gmail.com> # Kenji Imamula
|
||||
Klaus Meinhardt <klaus.meinhardt1@gmail.com>
|
||||
Kyle Kelley <rgbkrk@gmail.com>
|
||||
Lorant Pinter <lorant.pinter@prezi.com>
|
||||
Lucien Greathouse <me@lpghatguy.com>
|
||||
@@ -107,6 +116,7 @@ Martin Vseticka <vseticka.martin@gmail.com> Martin Všeticka <vseticka.martin@gm
|
||||
gcnew <gcnew@abv.bg> # Marin Marinov
|
||||
vvakame <vvakame+dev@gmail.com> # Masahiro Wakame
|
||||
Matt McCutchen <rmccutch@mit.edu>
|
||||
MANISH-GIRI <manish.giri.me@gmail.com> # Manish Giri
|
||||
Max Deepfield <maxdeepfield@absolutefreakout.com>
|
||||
Micah Zoltu <micah@zoltu.net>
|
||||
Michael <maykelchiche@gmail.com>
|
||||
@@ -213,4 +223,6 @@ Tim Perry <tim.perry@softwire.com>
|
||||
Vidar Tonaas Fauske <vidartf@gmail.com>
|
||||
Viktor Zozulyak <zozulyakviktor@gmail.com>
|
||||
rix <rix@rixs-MacBook-Pro.local> # Richard Sentino
|
||||
rohitverma007 <rohitverma@live.ca> # Rohit Verma
|
||||
rohitverma007 <rohitverma@live.ca> # Rohit Verma
|
||||
rdosanjh <me@rajdeep.io> # Raj Dosanjh
|
||||
gdh1995 <gdh1995@qq.com> # Dahan Gong
|
||||
+12
@@ -12,13 +12,16 @@ TypeScript is authored by:
|
||||
* Aliaksandr Radzivanovich
|
||||
* Anatoly Ressin
|
||||
* Anders Hejlsberg
|
||||
* Andreas Martin
|
||||
* Andrej Baran
|
||||
* Andrew Ochsner
|
||||
* Andrew Z Allen
|
||||
* András Parditka
|
||||
* Andy Hanson
|
||||
* Anil Anar
|
||||
* Anton Khlynovskiy
|
||||
* Anton Tolmachev
|
||||
* Anubha Mathur
|
||||
* Arnav Singh
|
||||
* Arthur Ozga
|
||||
* Asad Saeeduddin
|
||||
@@ -42,12 +45,14 @@ TypeScript is authored by:
|
||||
* Cotton Hou
|
||||
* Cyrus Najmabadi
|
||||
* Dafrok Zhang
|
||||
* Dahan Gong
|
||||
* Dan Corder
|
||||
* Dan Quirk
|
||||
* Daniel Hollocher
|
||||
* Daniel Rosenwasser
|
||||
* David Kmenta
|
||||
* David Li
|
||||
* David Sheldrick
|
||||
* David Souther
|
||||
* Denis Nedelyaev
|
||||
* Dick van den Brink
|
||||
@@ -66,6 +71,7 @@ TypeScript is authored by:
|
||||
* Eyas Sharaiha
|
||||
* Fabian Cook
|
||||
* @falsandtru
|
||||
* @flowmemo
|
||||
* Frank Wallis
|
||||
* Franklin Tse
|
||||
* František Žiacik
|
||||
@@ -79,6 +85,7 @@ TypeScript is authored by:
|
||||
* Guy Bedford
|
||||
* Harald Niesche
|
||||
* Herrington Darkholme
|
||||
* Homa Wong
|
||||
* Iain Monro
|
||||
* Ingvar Stepanyan
|
||||
* Isiah Meadows
|
||||
@@ -93,6 +100,7 @@ TypeScript is authored by:
|
||||
* Jeffrey Morlan
|
||||
* Jesse Schalken
|
||||
* Jiri Tobisek
|
||||
* Joel Day
|
||||
* Joey Wilson
|
||||
* Johannes Rieken
|
||||
* John Vilk
|
||||
@@ -114,10 +122,13 @@ TypeScript is authored by:
|
||||
* Ken Howard
|
||||
* Kenji Imamula
|
||||
* Kevin Lang
|
||||
* Klaus Meinhardt
|
||||
* Kyle Kelley
|
||||
* Kārlis Gaņģis
|
||||
* Lorant Pinter
|
||||
* Lucien Greathouse
|
||||
* Lukas Elmer
|
||||
* Manish Giri
|
||||
* Marin Marinov
|
||||
* Marius Schulz
|
||||
* Martin Vseticka
|
||||
@@ -155,6 +166,7 @@ TypeScript is authored by:
|
||||
* @progre
|
||||
* Punya Biswal
|
||||
* Rado Kirov
|
||||
* Raj Dosanjh
|
||||
* Richard Knoll
|
||||
* Richard Sentino
|
||||
* Robert Coie
|
||||
|
||||
+32
-169
@@ -6,6 +6,8 @@ var path = require("path");
|
||||
var child_process = require("child_process");
|
||||
var fold = require("travis-fold");
|
||||
var runTestsInParallel = require("./scripts/mocha-parallel").runTestsInParallel;
|
||||
var ts = require("./lib/typescript");
|
||||
|
||||
|
||||
// Variables
|
||||
var compilerDirectory = "src/compiler/";
|
||||
@@ -34,6 +36,24 @@ if (process.env.path !== undefined) {
|
||||
process.env.PATH = nodeModulesPathPrefix + process.env.PATH;
|
||||
}
|
||||
|
||||
function filesFromConfig(configPath) {
|
||||
var configText = fs.readFileSync(configPath).toString();
|
||||
var config = ts.parseConfigFileTextToJson(configPath, configText, /*stripComments*/ true);
|
||||
if (config.error) {
|
||||
throw new Error(diagnosticsToString([config.error]));
|
||||
}
|
||||
const configFileContent = ts.parseJsonConfigFileContent(config.config, ts.sys, path.dirname(configPath));
|
||||
if (configFileContent.errors && configFileContent.errors.length) {
|
||||
throw new Error(diagnosticsToString(configFileContent.errors));
|
||||
}
|
||||
|
||||
return configFileContent.fileNames;
|
||||
|
||||
function diagnosticsToString(s) {
|
||||
return s.map(function(e) { return ts.flattenDiagnosticMessageText(e.messageText, ts.sys.newLine); }).join(ts.sys.newLine);
|
||||
}
|
||||
}
|
||||
|
||||
function toNs(diff) {
|
||||
return diff[0] * 1e9 + diff[1];
|
||||
}
|
||||
@@ -56,173 +76,12 @@ function measure(marker) {
|
||||
console.log("travis_time:end:" + marker.id + ":start=" + toNs(marker.stamp) + ",finish=" + toNs(total) + ",duration=" + toNs(diff) + "\r");
|
||||
}
|
||||
|
||||
var compilerSources = [
|
||||
"core.ts",
|
||||
"performance.ts",
|
||||
"sys.ts",
|
||||
"types.ts",
|
||||
"scanner.ts",
|
||||
"parser.ts",
|
||||
"utilities.ts",
|
||||
"binder.ts",
|
||||
"checker.ts",
|
||||
"factory.ts",
|
||||
"visitor.ts",
|
||||
"transformers/destructuring.ts",
|
||||
"transformers/ts.ts",
|
||||
"transformers/jsx.ts",
|
||||
"transformers/esnext.ts",
|
||||
"transformers/es2017.ts",
|
||||
"transformers/es2016.ts",
|
||||
"transformers/es2015.ts",
|
||||
"transformers/generators.ts",
|
||||
"transformers/es5.ts",
|
||||
"transformers/module/es2015.ts",
|
||||
"transformers/module/system.ts",
|
||||
"transformers/module/module.ts",
|
||||
"transformer.ts",
|
||||
"sourcemap.ts",
|
||||
"comments.ts",
|
||||
"declarationEmitter.ts",
|
||||
"emitter.ts",
|
||||
"program.ts",
|
||||
"commandLineParser.ts",
|
||||
"tsc.ts",
|
||||
"diagnosticInformationMap.generated.ts"
|
||||
].map(function (f) {
|
||||
return path.join(compilerDirectory, f);
|
||||
});
|
||||
|
||||
var servicesSources = [
|
||||
"core.ts",
|
||||
"performance.ts",
|
||||
"sys.ts",
|
||||
"types.ts",
|
||||
"scanner.ts",
|
||||
"parser.ts",
|
||||
"utilities.ts",
|
||||
"binder.ts",
|
||||
"checker.ts",
|
||||
"factory.ts",
|
||||
"visitor.ts",
|
||||
"transformers/destructuring.ts",
|
||||
"transformers/ts.ts",
|
||||
"transformers/jsx.ts",
|
||||
"transformers/esnext.ts",
|
||||
"transformers/es2017.ts",
|
||||
"transformers/es2016.ts",
|
||||
"transformers/es2015.ts",
|
||||
"transformers/generators.ts",
|
||||
"transformers/es5.ts",
|
||||
"transformers/module/es2015.ts",
|
||||
"transformers/module/system.ts",
|
||||
"transformers/module/module.ts",
|
||||
"transformer.ts",
|
||||
"sourcemap.ts",
|
||||
"comments.ts",
|
||||
"declarationEmitter.ts",
|
||||
"emitter.ts",
|
||||
"program.ts",
|
||||
"commandLineParser.ts",
|
||||
"diagnosticInformationMap.generated.ts"
|
||||
].map(function (f) {
|
||||
return path.join(compilerDirectory, f);
|
||||
}).concat([
|
||||
"types.ts",
|
||||
"utilities.ts",
|
||||
"breakpoints.ts",
|
||||
"classifier.ts",
|
||||
"completions.ts",
|
||||
"documentHighlights.ts",
|
||||
"documentRegistry.ts",
|
||||
"findAllReferences.ts",
|
||||
"goToDefinition.ts",
|
||||
"goToImplementation.ts",
|
||||
"jsDoc.ts",
|
||||
"jsTyping.ts",
|
||||
"navigateTo.ts",
|
||||
"navigationBar.ts",
|
||||
"outliningElementsCollector.ts",
|
||||
"patternMatcher.ts",
|
||||
"preProcess.ts",
|
||||
"rename.ts",
|
||||
"services.ts",
|
||||
"shims.ts",
|
||||
"signatureHelp.ts",
|
||||
"symbolDisplay.ts",
|
||||
"transpile.ts",
|
||||
// Formatting
|
||||
"formatting/formatting.ts",
|
||||
"formatting/formattingContext.ts",
|
||||
"formatting/formattingRequestKind.ts",
|
||||
"formatting/formattingScanner.ts",
|
||||
"formatting/references.ts",
|
||||
"formatting/rule.ts",
|
||||
"formatting/ruleAction.ts",
|
||||
"formatting/ruleDescriptor.ts",
|
||||
"formatting/ruleFlag.ts",
|
||||
"formatting/ruleOperation.ts",
|
||||
"formatting/ruleOperationContext.ts",
|
||||
"formatting/rules.ts",
|
||||
"formatting/rulesMap.ts",
|
||||
"formatting/rulesProvider.ts",
|
||||
"formatting/smartIndenter.ts",
|
||||
"formatting/tokenRange.ts",
|
||||
// CodeFixes
|
||||
"codeFixProvider.ts",
|
||||
"codefixes/fixes.ts",
|
||||
"codefixes/fixExtendsInterfaceBecomesImplements.ts",
|
||||
"codefixes/fixClassIncorrectlyImplementsInterface.ts",
|
||||
"codefixes/fixClassDoesntImplementInheritedAbstractMember.ts",
|
||||
"codefixes/fixClassSuperMustPrecedeThisAccess.ts",
|
||||
"codefixes/fixConstructorForDerivedNeedSuperCall.ts",
|
||||
"codefixes/helpers.ts",
|
||||
"codefixes/importFixes.ts",
|
||||
"codefixes/unusedIdentifierFixes.ts"
|
||||
].map(function (f) {
|
||||
return path.join(servicesDirectory, f);
|
||||
}));
|
||||
|
||||
var baseServerCoreSources = [
|
||||
"builder.ts",
|
||||
"editorServices.ts",
|
||||
"lsHost.ts",
|
||||
"project.ts",
|
||||
"protocol.ts",
|
||||
"scriptInfo.ts",
|
||||
"scriptVersionCache.ts",
|
||||
"session.ts",
|
||||
"shared.ts",
|
||||
"types.ts",
|
||||
"typingsCache.ts",
|
||||
"utilities.ts",
|
||||
].map(function (f) {
|
||||
return path.join(serverDirectory, f);
|
||||
});
|
||||
|
||||
var serverCoreSources = [
|
||||
"server.ts"
|
||||
].map(function (f) {
|
||||
return path.join(serverDirectory, f);
|
||||
}).concat(baseServerCoreSources);
|
||||
|
||||
var cancellationTokenSources = [
|
||||
"cancellationToken.ts"
|
||||
].map(function (f) {
|
||||
return path.join(cancellationTokenDirectory, f);
|
||||
});
|
||||
|
||||
var typingsInstallerSources = [
|
||||
"../types.ts",
|
||||
"../shared.ts",
|
||||
"typingsInstaller.ts",
|
||||
"nodeTypingsInstaller.ts"
|
||||
].map(function (f) {
|
||||
return path.join(typingsInstallerDirectory, f);
|
||||
});
|
||||
|
||||
var serverSources = serverCoreSources.concat(servicesSources);
|
||||
var languageServiceLibrarySources = baseServerCoreSources.concat(servicesSources);
|
||||
var compilerSources = filesFromConfig("./src/compiler/tsconfig.json");
|
||||
var servicesSources = filesFromConfig("./src/services/tsconfig.json");
|
||||
var cancellationTokenSources = filesFromConfig(path.join(serverDirectory, "cancellationToken/tsconfig.json"));
|
||||
var typingsInstallerSources = filesFromConfig(path.join(serverDirectory, "typingsInstaller/tsconfig.json"));
|
||||
var serverSources = filesFromConfig(path.join(serverDirectory, "tsconfig.json"))
|
||||
var languageServiceLibrarySources = filesFromConfig(path.join(serverDirectory, "tsconfig.library.json"));
|
||||
|
||||
var harnessCoreSources = [
|
||||
"harness.ts",
|
||||
@@ -269,6 +128,7 @@ var harnessSources = harnessCoreSources.concat([
|
||||
"projectErrors.ts",
|
||||
"matchFiles.ts",
|
||||
"initializeTSConfig.ts",
|
||||
"printer.ts",
|
||||
].map(function (f) {
|
||||
return path.join(unittestsDirectory, f);
|
||||
})).concat([
|
||||
@@ -1229,13 +1089,16 @@ var lintTargets = compilerSources
|
||||
.concat(harnessSources)
|
||||
// Other harness sources
|
||||
.concat(["instrumenter.ts"].map(function (f) { return path.join(harnessDirectory, f) }))
|
||||
.concat(serverCoreSources)
|
||||
.concat(serverSources)
|
||||
.concat(tslintRulesFiles)
|
||||
.concat(servicesSources)
|
||||
.concat(typingsInstallerSources)
|
||||
.concat(cancellationTokenSources)
|
||||
.concat(["Gulpfile.ts"])
|
||||
.concat([nodeServerInFile, perftscPath, "tests/perfsys.ts", webhostPath]);
|
||||
.concat([nodeServerInFile, perftscPath, "tests/perfsys.ts", webhostPath])
|
||||
.map(function (p) { return path.resolve(p) });
|
||||
// keep only unique items
|
||||
lintTargets = Array.from(new Set(lintTargets));
|
||||
|
||||
function sendNextFile(files, child, callback, failures) {
|
||||
var file = files.pop();
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"name": "typescript",
|
||||
"author": "Microsoft Corp.",
|
||||
"homepage": "http://typescriptlang.org/",
|
||||
"version": "2.2.0",
|
||||
"version": "2.3.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "TypeScript is a language for application scale JavaScript development",
|
||||
"keywords": [
|
||||
|
||||
@@ -167,7 +167,7 @@ function generateProtocolFile(protocolTs: string, typeScriptServicesDts: string)
|
||||
const sanityCheckProgram = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ false);
|
||||
const diagnostics = [...sanityCheckProgram.getSyntacticDiagnostics(), ...sanityCheckProgram.getSemanticDiagnostics(), ...sanityCheckProgram.getGlobalDiagnostics()];
|
||||
if (diagnostics.length) {
|
||||
const flattenedDiagnostics = diagnostics.map(d => ts.flattenDiagnosticMessageText(d.messageText, "\n")).join("\n");
|
||||
const flattenedDiagnostics = diagnostics.map(d => `${ts.flattenDiagnosticMessageText(d.messageText, "\n")} at ${d.file.fileName} line ${d.start}`).join("\n");
|
||||
throw new Error(`Unexpected errors during sanity check: ${flattenedDiagnostics}`);
|
||||
}
|
||||
return protocolDts;
|
||||
|
||||
+34
-1
@@ -1045,7 +1045,35 @@ namespace ts {
|
||||
if (node.finallyBlock) {
|
||||
// in finally flow is combined from pre-try/flow from try/flow from catch
|
||||
// pre-flow is necessary to make sure that finally is reachable even if finally flows in both try and finally blocks are unreachable
|
||||
addAntecedent(preFinallyLabel, preTryFlow);
|
||||
|
||||
// also for finally blocks we inject two extra edges into the flow graph.
|
||||
// first -> edge that connects pre-try flow with the label at the beginning of the finally block, it has lock associated with it
|
||||
// second -> edge that represents post-finally flow.
|
||||
// these edges are used in following scenario:
|
||||
// let a; (1)
|
||||
// try { a = someOperation(); (2)}
|
||||
// finally { (3) console.log(a) } (4)
|
||||
// (5) a
|
||||
|
||||
// flow graph for this case looks roughly like this (arrows show ):
|
||||
// (1-pre-try-flow) <--.. <-- (2-post-try-flow)
|
||||
// ^ ^
|
||||
// |*****(3-pre-finally-label) -----|
|
||||
// ^
|
||||
// |-- ... <-- (4-post-finally-label) <--- (5)
|
||||
// In case when we walk the flow starting from inside the finally block we want to take edge '*****' into account
|
||||
// since it ensures that finally is always reachable. However when we start outside the finally block and go through label (5)
|
||||
// then edge '*****' should be discarded because label 4 is only reachable if post-finally label-4 is reachable
|
||||
// Simply speaking code inside finally block is treated as reachable as pre-try-flow
|
||||
// since we conservatively assume that any line in try block can throw or return in which case we'll enter finally.
|
||||
// However code after finally is reachable only if control flow was not abrupted in try/catch or finally blocks - it should be composed from
|
||||
// final flows of these blocks without taking pre-try flow into account.
|
||||
//
|
||||
// extra edges that we inject allows to control this behavior
|
||||
// if when walking the flow we step on post-finally edge - we can mark matching pre-finally edge as locked so it will be skipped.
|
||||
const preFinallyFlow: PreFinallyFlow = { flags: FlowFlags.PreFinally, antecedent: preTryFlow, lock: {} };
|
||||
addAntecedent(preFinallyLabel, preFinallyFlow);
|
||||
|
||||
currentFlow = finishFlowLabel(preFinallyLabel);
|
||||
bind(node.finallyBlock);
|
||||
// if flow after finally is unreachable - keep it
|
||||
@@ -1061,6 +1089,11 @@ namespace ts {
|
||||
: unreachableFlow;
|
||||
}
|
||||
}
|
||||
if (!(currentFlow.flags & FlowFlags.Unreachable)) {
|
||||
const afterFinallyFlow: AfterFinallyFlow = { flags: FlowFlags.AfterFinally, antecedent: currentFlow };
|
||||
preFinallyFlow.lock = afterFinallyFlow;
|
||||
currentFlow = afterFinallyFlow;
|
||||
}
|
||||
}
|
||||
else {
|
||||
currentFlow = finishFlowLabel(preFinallyLabel);
|
||||
|
||||
+371
-170
File diff suppressed because it is too large
Load Diff
@@ -459,6 +459,16 @@ namespace ts {
|
||||
name: "alwaysStrict",
|
||||
type: "boolean",
|
||||
description: Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file
|
||||
},
|
||||
{
|
||||
// A list of plugins to load in the language service
|
||||
name: "plugins",
|
||||
type: "list",
|
||||
isTSConfigOnly: true,
|
||||
element: {
|
||||
name: "plugin",
|
||||
type: "object"
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
@@ -840,7 +850,7 @@ namespace ts {
|
||||
* @param basePath A root directory to resolve relative path entries in the config
|
||||
* file to. e.g. outDir
|
||||
*/
|
||||
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}, configFileName?: string, resolutionStack: Path[] = [], extraFileExtensions: FileExtensionInfo[] = []): ParsedCommandLine {
|
||||
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}, configFileName?: string, resolutionStack: Path[] = [], extraFileExtensions: JsFileExtensionInfo[] = []): ParsedCommandLine {
|
||||
const errors: Diagnostic[] = [];
|
||||
basePath = normalizeSlashes(basePath);
|
||||
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames);
|
||||
@@ -1186,7 +1196,7 @@ namespace ts {
|
||||
* @param host The host used to resolve files and directories.
|
||||
* @param errors An array for diagnostic reporting.
|
||||
*/
|
||||
function matchFileNames(fileNames: string[], include: string[], exclude: string[], basePath: string, options: CompilerOptions, host: ParseConfigHost, errors: Diagnostic[], extraFileExtensions: FileExtensionInfo[]): ExpandResult {
|
||||
function matchFileNames(fileNames: string[], include: string[], exclude: string[], basePath: string, options: CompilerOptions, host: ParseConfigHost, errors: Diagnostic[], extraFileExtensions: JsFileExtensionInfo[]): ExpandResult {
|
||||
basePath = normalizePath(basePath);
|
||||
|
||||
// The exclude spec list is converted into a regular expression, which allows us to quickly
|
||||
@@ -1361,7 +1371,7 @@ namespace ts {
|
||||
*/
|
||||
function hasFileWithHigherPriorityExtension(file: string, literalFiles: Map<string>, wildcardFiles: Map<string>, extensions: string[], keyMapper: (value: string) => string) {
|
||||
const extensionPriority = getExtensionPriority(file, extensions);
|
||||
const adjustedExtensionPriority = adjustExtensionPriority(extensionPriority);
|
||||
const adjustedExtensionPriority = adjustExtensionPriority(extensionPriority, extensions);
|
||||
for (let i = ExtensionPriority.Highest; i < adjustedExtensionPriority; i++) {
|
||||
const higherPriorityExtension = extensions[i];
|
||||
const higherPriorityPath = keyMapper(changeExtension(file, higherPriorityExtension));
|
||||
@@ -1383,7 +1393,7 @@ namespace ts {
|
||||
*/
|
||||
function removeWildcardFilesWithLowerPriorityExtension(file: string, wildcardFiles: Map<string>, extensions: string[], keyMapper: (value: string) => string) {
|
||||
const extensionPriority = getExtensionPriority(file, extensions);
|
||||
const nextExtensionPriority = getNextLowestExtensionPriority(extensionPriority);
|
||||
const nextExtensionPriority = getNextLowestExtensionPriority(extensionPriority, extensions);
|
||||
for (let i = nextExtensionPriority; i < extensions.length; i++) {
|
||||
const lowerPriorityExtension = extensions[i];
|
||||
const lowerPriorityPath = keyMapper(changeExtension(file, lowerPriorityExtension));
|
||||
|
||||
+36
-22
@@ -5,17 +5,17 @@ namespace ts {
|
||||
export interface CommentWriter {
|
||||
reset(): void;
|
||||
setSourceFile(sourceFile: SourceFile): void;
|
||||
emitNodeWithComments(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
|
||||
setWriter(writer: EmitTextWriter): void;
|
||||
emitNodeWithComments(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
emitBodyWithDetachedComments(node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void): void;
|
||||
emitTrailingCommentsOfPosition(pos: number): void;
|
||||
emitLeadingCommentsOfPosition(pos: number): void;
|
||||
}
|
||||
|
||||
export function createCommentWriter(host: EmitHost, writer: EmitTextWriter, sourceMap: SourceMapWriter): CommentWriter {
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
const extendedDiagnostics = compilerOptions.extendedDiagnostics;
|
||||
const newLine = host.getNewLine();
|
||||
const { emitPos } = sourceMap;
|
||||
|
||||
export function createCommentWriter(printerOptions: PrinterOptions, emitPos: ((pos: number) => void) | undefined): CommentWriter {
|
||||
const extendedDiagnostics = printerOptions.extendedDiagnostics;
|
||||
const newLine = getNewLineCharacter(printerOptions);
|
||||
let writer: EmitTextWriter;
|
||||
let containerPos = -1;
|
||||
let containerEnd = -1;
|
||||
let declarationListContainerEnd = -1;
|
||||
@@ -24,19 +24,21 @@ namespace ts {
|
||||
let currentLineMap: number[];
|
||||
let detachedCommentsInfo: { nodePos: number, detachedCommentEndPos: number}[];
|
||||
let hasWrittenComment = false;
|
||||
let disabled: boolean = compilerOptions.removeComments;
|
||||
let disabled: boolean = printerOptions.removeComments;
|
||||
|
||||
return {
|
||||
reset,
|
||||
setWriter,
|
||||
setSourceFile,
|
||||
emitNodeWithComments,
|
||||
emitBodyWithDetachedComments,
|
||||
emitTrailingCommentsOfPosition,
|
||||
emitLeadingCommentsOfPosition,
|
||||
};
|
||||
|
||||
function emitNodeWithComments(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
|
||||
function emitNodeWithComments(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (disabled) {
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -47,11 +49,11 @@ namespace ts {
|
||||
// Both pos and end are synthesized, so just emit the node without comments.
|
||||
if (emitFlags & EmitFlags.NoNestedComments) {
|
||||
disabled = true;
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -94,11 +96,11 @@ namespace ts {
|
||||
|
||||
if (emitFlags & EmitFlags.NoNestedComments) {
|
||||
disabled = true;
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
@@ -198,9 +200,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
|
||||
emitPos(commentPos);
|
||||
if (emitPos) emitPos(commentPos);
|
||||
writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
|
||||
emitPos(commentEnd);
|
||||
if (emitPos) emitPos(commentEnd);
|
||||
|
||||
if (hasTrailingNewLine) {
|
||||
writer.writeLine();
|
||||
@@ -210,6 +212,14 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitLeadingCommentsOfPosition(pos: number) {
|
||||
if (disabled || pos === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
emitLeadingComments(pos, /*isEmittedNode*/ true);
|
||||
}
|
||||
|
||||
function emitTrailingComments(pos: number) {
|
||||
forEachTrailingCommentToEmit(pos, emitTrailingComment);
|
||||
}
|
||||
@@ -220,9 +230,9 @@ namespace ts {
|
||||
writer.write(" ");
|
||||
}
|
||||
|
||||
emitPos(commentPos);
|
||||
if (emitPos) emitPos(commentPos);
|
||||
writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
|
||||
emitPos(commentEnd);
|
||||
if (emitPos) emitPos(commentEnd);
|
||||
|
||||
if (hasTrailingNewLine) {
|
||||
writer.writeLine();
|
||||
@@ -248,9 +258,9 @@ namespace ts {
|
||||
function emitTrailingCommentOfPosition(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) {
|
||||
// trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
|
||||
|
||||
emitPos(commentPos);
|
||||
if (emitPos) emitPos(commentPos);
|
||||
writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
|
||||
emitPos(commentEnd);
|
||||
if (emitPos) emitPos(commentEnd);
|
||||
|
||||
if (hasTrailingNewLine) {
|
||||
writer.writeLine();
|
||||
@@ -286,6 +296,10 @@ namespace ts {
|
||||
detachedCommentsInfo = undefined;
|
||||
}
|
||||
|
||||
function setWriter(output: EmitTextWriter): void {
|
||||
writer = output;
|
||||
}
|
||||
|
||||
function setSourceFile(sourceFile: SourceFile) {
|
||||
currentSourceFile = sourceFile;
|
||||
currentText = currentSourceFile.text;
|
||||
@@ -323,9 +337,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
function writeComment(text: string, lineMap: number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) {
|
||||
emitPos(commentPos);
|
||||
if (emitPos) emitPos(commentPos);
|
||||
writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine);
|
||||
emitPos(commentEnd);
|
||||
if (emitPos) emitPos(commentEnd);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+22
-16
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace ts {
|
||||
/** The version of the TypeScript compiler release */
|
||||
export const version = "2.2.0";
|
||||
export const version = "2.3.0";
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -895,6 +895,14 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function convertToArray<T, U>(iterator: Iterator<T>, f: (value: T) => U) {
|
||||
const result: U[] = [];
|
||||
for (let { value, done } = iterator.next(); !done; { value, done } = iterator.next()) {
|
||||
result.push(f(value));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls `callback` for each entry in the map, returning the first truthy result.
|
||||
* Use `map.forEach` instead for normal iteration.
|
||||
@@ -1447,7 +1455,7 @@ namespace ts {
|
||||
return /^\.\.?($|[\\/])/.test(moduleName);
|
||||
}
|
||||
|
||||
export function getEmitScriptTarget(compilerOptions: CompilerOptions) {
|
||||
export function getEmitScriptTarget(compilerOptions: CompilerOptions | PrinterOptions) {
|
||||
return compilerOptions.target || ScriptTarget.ES3;
|
||||
}
|
||||
|
||||
@@ -2012,14 +2020,14 @@ namespace ts {
|
||||
export const supportedJavascriptExtensions = [".js", ".jsx"];
|
||||
const allSupportedExtensions = supportedTypeScriptExtensions.concat(supportedJavascriptExtensions);
|
||||
|
||||
export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: FileExtensionInfo[]): string[] {
|
||||
export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: JsFileExtensionInfo[]): string[] {
|
||||
const needAllExtensions = options && options.allowJs;
|
||||
if (!extraFileExtensions || extraFileExtensions.length === 0) {
|
||||
if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) {
|
||||
return needAllExtensions ? allSupportedExtensions : supportedTypeScriptExtensions;
|
||||
}
|
||||
const extensions = (needAllExtensions ? allSupportedExtensions : supportedTypeScriptExtensions).slice(0);
|
||||
const extensions = allSupportedExtensions.slice(0);
|
||||
for (const extInfo of extraFileExtensions) {
|
||||
if (needAllExtensions || extInfo.scriptKind === ScriptKind.TS) {
|
||||
if (extensions.indexOf(extInfo.extension) === -1) {
|
||||
extensions.push(extInfo.extension);
|
||||
}
|
||||
}
|
||||
@@ -2034,7 +2042,7 @@ namespace ts {
|
||||
return forEach(supportedTypeScriptExtensions, extension => fileExtensionIs(fileName, extension));
|
||||
}
|
||||
|
||||
export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, extraFileExtensions?: FileExtensionInfo[]) {
|
||||
export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, extraFileExtensions?: JsFileExtensionInfo[]) {
|
||||
if (!fileName) { return false; }
|
||||
|
||||
for (const extension of getSupportedExtensions(compilerOptions, extraFileExtensions)) {
|
||||
@@ -2053,7 +2061,6 @@ namespace ts {
|
||||
export const enum ExtensionPriority {
|
||||
TypeScriptFiles = 0,
|
||||
DeclarationAndJavaScriptFiles = 2,
|
||||
Limit = 5,
|
||||
|
||||
Highest = TypeScriptFiles,
|
||||
Lowest = DeclarationAndJavaScriptFiles,
|
||||
@@ -2062,7 +2069,7 @@ namespace ts {
|
||||
export function getExtensionPriority(path: string, supportedExtensions: string[]): ExtensionPriority {
|
||||
for (let i = supportedExtensions.length - 1; i >= 0; i--) {
|
||||
if (fileExtensionIs(path, supportedExtensions[i])) {
|
||||
return adjustExtensionPriority(<ExtensionPriority>i);
|
||||
return adjustExtensionPriority(<ExtensionPriority>i, supportedExtensions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2074,27 +2081,26 @@ namespace ts {
|
||||
/**
|
||||
* Adjusts an extension priority to be the highest priority within the same range.
|
||||
*/
|
||||
export function adjustExtensionPriority(extensionPriority: ExtensionPriority): ExtensionPriority {
|
||||
export function adjustExtensionPriority(extensionPriority: ExtensionPriority, supportedExtensions: string[]): ExtensionPriority {
|
||||
if (extensionPriority < ExtensionPriority.DeclarationAndJavaScriptFiles) {
|
||||
return ExtensionPriority.TypeScriptFiles;
|
||||
}
|
||||
else if (extensionPriority < ExtensionPriority.Limit) {
|
||||
else if (extensionPriority < supportedExtensions.length) {
|
||||
return ExtensionPriority.DeclarationAndJavaScriptFiles;
|
||||
}
|
||||
else {
|
||||
return ExtensionPriority.Limit;
|
||||
}
|
||||
}
|
||||
return supportedExtensions.length;
|
||||
} }
|
||||
|
||||
/**
|
||||
* Gets the next lowest extension priority for a given priority.
|
||||
*/
|
||||
export function getNextLowestExtensionPriority(extensionPriority: ExtensionPriority): ExtensionPriority {
|
||||
export function getNextLowestExtensionPriority(extensionPriority: ExtensionPriority, supportedExtensions: string[]): ExtensionPriority {
|
||||
if (extensionPriority < ExtensionPriority.DeclarationAndJavaScriptFiles) {
|
||||
return ExtensionPriority.DeclarationAndJavaScriptFiles;
|
||||
}
|
||||
else {
|
||||
return ExtensionPriority.Limit;
|
||||
return supportedExtensions.length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,13 +35,15 @@ namespace ts {
|
||||
forEachEmittedFile(host, getDeclarationDiagnosticsFromFile, targetSourceFile);
|
||||
return declarationDiagnostics.getDiagnostics(targetSourceFile ? targetSourceFile.fileName : undefined);
|
||||
|
||||
function getDeclarationDiagnosticsFromFile({ declarationFilePath }: EmitFileNames, sources: SourceFile[], isBundledEmit: boolean) {
|
||||
emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sources, isBundledEmit, /*emitOnlyDtsFiles*/ false);
|
||||
function getDeclarationDiagnosticsFromFile({ declarationFilePath }: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) {
|
||||
emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sourceFileOrBundle, /*emitOnlyDtsFiles*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
function emitDeclarations(host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, declarationFilePath: string,
|
||||
sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean): DeclarationEmit {
|
||||
sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean): DeclarationEmit {
|
||||
const sourceFiles = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle];
|
||||
const isBundledEmit = sourceFileOrBundle.kind === SyntaxKind.Bundle;
|
||||
const newLine = host.getNewLine();
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
|
||||
@@ -322,13 +324,20 @@ namespace ts {
|
||||
function writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, type: TypeNode, getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic) {
|
||||
writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
|
||||
write(": ");
|
||||
if (type) {
|
||||
|
||||
// use the checker's type, not the declared type,
|
||||
// for non-optional initialized parameters that aren't a parameter property
|
||||
const shouldUseResolverType = declaration.kind === SyntaxKind.Parameter &&
|
||||
resolver.isRequiredInitializedParameter(declaration as ParameterDeclaration);
|
||||
if (type && !shouldUseResolverType) {
|
||||
// Write the type
|
||||
emitType(type);
|
||||
}
|
||||
else {
|
||||
errorNameNode = declaration.name;
|
||||
resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer);
|
||||
const format = TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue |
|
||||
(shouldUseResolverType ? TypeFormatFlags.AddUndefined : 0);
|
||||
resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, format, writer);
|
||||
errorNameNode = undefined;
|
||||
}
|
||||
}
|
||||
@@ -1803,8 +1812,9 @@ namespace ts {
|
||||
}
|
||||
return addedBundledEmitReference;
|
||||
|
||||
function getDeclFileName(emitFileNames: EmitFileNames, _sourceFiles: SourceFile[], isBundledEmit: boolean) {
|
||||
function getDeclFileName(emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) {
|
||||
// Dont add reference path to this file if it is a bundled emit and caller asked not emit bundled file path
|
||||
const isBundledEmit = sourceFileOrBundle.kind === SyntaxKind.Bundle;
|
||||
if (isBundledEmit && !addBundledFileReference) {
|
||||
return;
|
||||
}
|
||||
@@ -1817,10 +1827,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function writeDeclarationFile(declarationFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean, host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, emitOnlyDtsFiles: boolean) {
|
||||
const emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFiles, isBundledEmit, emitOnlyDtsFiles);
|
||||
export function writeDeclarationFile(declarationFilePath: string, sourceFileOrBundle: SourceFile | Bundle, host: EmitHost, resolver: EmitResolver, emitterDiagnostics: DiagnosticCollection, emitOnlyDtsFiles: boolean) {
|
||||
const emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFileOrBundle, emitOnlyDtsFiles);
|
||||
const emitSkipped = emitDeclarationResult.reportedDeclarationError || host.isEmitBlocked(declarationFilePath) || host.getCompilerOptions().noEmit;
|
||||
if (!emitSkipped) {
|
||||
const sourceFiles = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle];
|
||||
const declarationOutput = emitDeclarationResult.referencesOutput
|
||||
+ getDeclarationOutput(emitDeclarationResult.synchronousDeclarationOutput, emitDeclarationResult.moduleElementDeclarationEmitInfo);
|
||||
writeFile(host, emitterDiagnostics, declarationFilePath, declarationOutput, host.getCompilerOptions().emitBOM, sourceFiles);
|
||||
|
||||
@@ -671,6 +671,10 @@
|
||||
"category": "Error",
|
||||
"code": 1215
|
||||
},
|
||||
"Identifier expected. '__esModule' is reserved as an exported marker when transforming ECMAScript modules.": {
|
||||
"category": "Error",
|
||||
"code": 1216
|
||||
},
|
||||
"Export assignment is not supported when '--module' flag is 'system'.": {
|
||||
"category": "Error",
|
||||
"code": 1218
|
||||
@@ -1787,6 +1791,10 @@
|
||||
"category": "Error",
|
||||
"code": 2545
|
||||
},
|
||||
"Property '{0}' has conflicting declarations and is inaccessible in type '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 2546
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
@@ -2047,6 +2055,10 @@
|
||||
"category": "Error",
|
||||
"code": 2704
|
||||
},
|
||||
"An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.": {
|
||||
"category": "Error",
|
||||
"code": 2705
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
@@ -2801,7 +2813,7 @@
|
||||
"category": "Message",
|
||||
"code": 6099
|
||||
},
|
||||
"'package.json' does not have a 'types' or 'main' field.": {
|
||||
"'package.json' does not have a '{0}' field.": {
|
||||
"category": "Message",
|
||||
"code": 6100
|
||||
},
|
||||
@@ -2949,10 +2961,6 @@
|
||||
"category": "Message",
|
||||
"code": 6136
|
||||
},
|
||||
"No types specified in 'package.json', so returning 'main' value of '{0}'": {
|
||||
"category": "Message",
|
||||
"code": 6137
|
||||
},
|
||||
"Property '{0}' is declared but never used.": {
|
||||
"category": "Error",
|
||||
"code": 6138
|
||||
|
||||
+553
-459
File diff suppressed because it is too large
Load Diff
+1291
-1084
File diff suppressed because it is too large
Load Diff
@@ -67,40 +67,31 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Reads from "main" or "types"/"typings" depending on `extensions`. */
|
||||
function tryReadPackageJsonMainOrTypes(extensions: Extensions, packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string {
|
||||
function tryReadPackageJsonFields(readTypes: boolean, packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string | undefined {
|
||||
const jsonContent = readJson(packageJsonPath, state.host);
|
||||
return readTypes ? tryReadFromField("typings") || tryReadFromField("types") : tryReadFromField("main");
|
||||
|
||||
switch (extensions) {
|
||||
case Extensions.DtsOnly:
|
||||
case Extensions.TypeScript:
|
||||
return tryReadFromField("typings") || tryReadFromField("types");
|
||||
|
||||
case Extensions.JavaScript:
|
||||
if (typeof jsonContent.main === "string") {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.No_types_specified_in_package_json_so_returning_main_value_of_0, jsonContent.main);
|
||||
}
|
||||
return normalizePath(combinePaths(baseDirectory, jsonContent.main));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function tryReadFromField(fieldName: string) {
|
||||
if (hasProperty(jsonContent, fieldName)) {
|
||||
const typesFile = (<any>jsonContent)[fieldName];
|
||||
if (typeof typesFile === "string") {
|
||||
const typesFilePath = normalizePath(combinePaths(baseDirectory, typesFile));
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, typesFile, typesFilePath);
|
||||
}
|
||||
return typesFilePath;
|
||||
}
|
||||
else {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_string_got_1, fieldName, typeof typesFile);
|
||||
}
|
||||
function tryReadFromField(fieldName: "typings" | "types" | "main"): string | undefined {
|
||||
if (!hasProperty(jsonContent, fieldName)) {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.package_json_does_not_have_a_0_field, fieldName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const fileName = jsonContent[fieldName];
|
||||
if (typeof fileName !== "string") {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_string_got_1, fieldName, typeof fileName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const path = normalizePath(combinePaths(baseDirectory, fileName));
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, fileName, path);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,13 +675,18 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations {
|
||||
return nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, /* jsOnly*/ false);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function nodeModuleNameResolverWorker(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, jsOnly = false): ResolvedModuleWithFailedLookupLocations {
|
||||
const containingDirectory = getDirectoryPath(containingFile);
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
|
||||
const failedLookupLocations: string[] = [];
|
||||
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
|
||||
|
||||
const result = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
|
||||
const result = jsOnly ? tryResolve(Extensions.JavaScript) : (tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript));
|
||||
if (result && result.value) {
|
||||
const { resolved, isExternalLibraryImport } = result.value;
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations);
|
||||
@@ -698,7 +694,8 @@ namespace ts {
|
||||
return { resolvedModule: undefined, failedLookupLocations };
|
||||
|
||||
function tryResolve(extensions: Extensions): SearchResult<{ resolved: Resolved, isExternalLibraryImport: boolean }> {
|
||||
const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, nodeLoadModuleByRelativeName, failedLookupLocations, state);
|
||||
const loader: ResolutionKindSpecificLoader = (extensions, candidate, failedLookupLocations, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/true);
|
||||
const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state);
|
||||
if (resolved) {
|
||||
return toSearchResult({ resolved, isExternalLibraryImport: false });
|
||||
}
|
||||
@@ -713,7 +710,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
|
||||
const resolved = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state);
|
||||
const resolved = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/true);
|
||||
return resolved && toSearchResult({ resolved, isExternalLibraryImport: false });
|
||||
}
|
||||
}
|
||||
@@ -731,7 +728,7 @@ namespace ts {
|
||||
return real;
|
||||
}
|
||||
|
||||
function nodeLoadModuleByRelativeName(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
|
||||
function nodeLoadModuleByRelativeName(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson: boolean): Resolved | undefined {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1, candidate, Extensions[extensions]);
|
||||
}
|
||||
@@ -759,7 +756,7 @@ namespace ts {
|
||||
onlyRecordFailures = true;
|
||||
}
|
||||
}
|
||||
return loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state);
|
||||
return loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -835,50 +832,57 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
|
||||
const packageJsonPath = pathToPackageJson(candidate);
|
||||
function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson = true): Resolved | undefined {
|
||||
const directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host);
|
||||
|
||||
if (directoryExists && state.host.fileExists(packageJsonPath)) {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Found_package_json_at_0, packageJsonPath);
|
||||
}
|
||||
const mainOrTypesFile = tryReadPackageJsonMainOrTypes(extensions, packageJsonPath, candidate, state);
|
||||
if (mainOrTypesFile) {
|
||||
const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(mainOrTypesFile), state.host);
|
||||
// A package.json "typings" may specify an exact filename, or may choose to omit an extension.
|
||||
const fromExactFile = tryFile(mainOrTypesFile, failedLookupLocations, onlyRecordFailures, state);
|
||||
if (fromExactFile) {
|
||||
const resolved = fromExactFile && resolvedIfExtensionMatches(extensions, fromExactFile);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromExactFile);
|
||||
}
|
||||
}
|
||||
const resolved = tryAddingExtensions(mainOrTypesFile, Extensions.TypeScript, failedLookupLocations, onlyRecordFailures, state);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
if (considerPackageJson) {
|
||||
const packageJsonPath = pathToPackageJson(candidate);
|
||||
if (directoryExists && state.host.fileExists(packageJsonPath)) {
|
||||
const fromPackageJson = loadModuleFromPackageJson(packageJsonPath, extensions, candidate, failedLookupLocations, state);
|
||||
if (fromPackageJson) {
|
||||
return fromPackageJson;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.package_json_does_not_have_a_types_or_main_field);
|
||||
if (directoryExists && state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.File_0_does_not_exist, packageJsonPath);
|
||||
}
|
||||
// record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
|
||||
failedLookupLocations.push(packageJsonPath);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (directoryExists && state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.File_0_does_not_exist, packageJsonPath);
|
||||
}
|
||||
// record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
|
||||
failedLookupLocations.push(packageJsonPath);
|
||||
}
|
||||
|
||||
return loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state);
|
||||
}
|
||||
|
||||
function loadModuleFromPackageJson(packageJsonPath: string, extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, state: ModuleResolutionState): Resolved | undefined {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Found_package_json_at_0, packageJsonPath);
|
||||
}
|
||||
|
||||
const file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, packageJsonPath, candidate, state);
|
||||
if (!file) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(file), state.host);
|
||||
const fromFile = tryFile(file, failedLookupLocations, onlyRecordFailures, state);
|
||||
if (fromFile) {
|
||||
const resolved = fromFile && resolvedIfExtensionMatches(extensions, fromFile);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromFile);
|
||||
}
|
||||
}
|
||||
|
||||
// Even if extensions is DtsOnly, we can still look up a .ts file as a result of package.json "types"
|
||||
const nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions;
|
||||
// Don't do package.json lookup recursively, because Node.js' package lookup doesn't.
|
||||
return nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ false);
|
||||
}
|
||||
|
||||
/** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */
|
||||
function resolvedIfExtensionMatches(extensions: Extensions, path: string): Resolved | undefined {
|
||||
const extension = tryGetExtensionFromPath(path);
|
||||
@@ -1040,7 +1044,6 @@ namespace ts {
|
||||
return value !== undefined ? { value } : undefined;
|
||||
}
|
||||
|
||||
|
||||
/** Calls `callback` on `directory` and every ancestor directory it has, returning the first defined result. */
|
||||
function forEachAncestorDirectory<T>(directory: string, callback: (directory: string) => SearchResult<T>): SearchResult<T> {
|
||||
while (true) {
|
||||
|
||||
@@ -1152,13 +1152,10 @@ namespace ts {
|
||||
&& (options.isolatedModules || isExternalModuleFile)
|
||||
&& !file.isDeclarationFile) {
|
||||
// synthesize 'import "tslib"' declaration
|
||||
const externalHelpersModuleReference = <StringLiteral>createSynthesizedNode(SyntaxKind.StringLiteral);
|
||||
externalHelpersModuleReference.text = externalHelpersModuleNameText;
|
||||
const importDecl = createSynthesizedNode(SyntaxKind.ImportDeclaration);
|
||||
|
||||
importDecl.parent = file;
|
||||
const externalHelpersModuleReference = createLiteral(externalHelpersModuleNameText);
|
||||
const importDecl = createImportDeclaration(undefined, undefined, undefined);
|
||||
externalHelpersModuleReference.parent = importDecl;
|
||||
|
||||
importDecl.parent = file;
|
||||
imports = [externalHelpersModuleReference];
|
||||
}
|
||||
|
||||
|
||||
+13
-15
@@ -8,10 +8,9 @@ namespace ts {
|
||||
*
|
||||
* @param filePath The path to the generated output file.
|
||||
* @param sourceMapFilePath The path to the output source map file.
|
||||
* @param sourceFiles The input source files for the program.
|
||||
* @param isBundledEmit A value indicating whether the generated output file is a bundle.
|
||||
* @param sourceFileOrBundle The input source file or bundle for the program.
|
||||
*/
|
||||
initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean): void;
|
||||
initialize(filePath: string, sourceMapFilePath: string, sourceFileOrBundle: SourceFile | Bundle): void;
|
||||
|
||||
/**
|
||||
* Reset the SourceMapWriter to an empty state.
|
||||
@@ -38,11 +37,11 @@ namespace ts {
|
||||
/**
|
||||
* Emits a node with possible leading and trailing source maps.
|
||||
*
|
||||
* @param emitContext The current emit context
|
||||
* @param hint The current emit context
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback The callback used to emit the node.
|
||||
*/
|
||||
emitNodeWithSourceMap(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
|
||||
emitNodeWithSourceMap(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
|
||||
/**
|
||||
* Emits a token of a node node with possible leading and trailing source maps.
|
||||
@@ -115,10 +114,9 @@ namespace ts {
|
||||
*
|
||||
* @param filePath The path to the generated output file.
|
||||
* @param sourceMapFilePath The path to the output source map file.
|
||||
* @param sourceFiles The input source files for the program.
|
||||
* @param isBundledEmit A value indicating whether the generated output file is a bundle.
|
||||
* @param sourceFileOrBundle The input source file or bundle for the program.
|
||||
*/
|
||||
function initialize(filePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) {
|
||||
function initialize(filePath: string, sourceMapFilePath: string, sourceFileOrBundle: SourceFile | Bundle) {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
@@ -161,11 +159,10 @@ namespace ts {
|
||||
|
||||
if (compilerOptions.mapRoot) {
|
||||
sourceMapDir = normalizeSlashes(compilerOptions.mapRoot);
|
||||
if (!isBundledEmit) { // emitting single module file
|
||||
Debug.assert(sourceFiles.length === 1);
|
||||
if (sourceFileOrBundle.kind === SyntaxKind.SourceFile) { // emitting single module file
|
||||
// For modules or multiple emit files the mapRoot will have directory structure like the sources
|
||||
// So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
|
||||
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFiles[0], host, sourceMapDir));
|
||||
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFileOrBundle, host, sourceMapDir));
|
||||
}
|
||||
|
||||
if (!isRootedDiskPath(sourceMapDir) && !isUrl(sourceMapDir)) {
|
||||
@@ -311,12 +308,13 @@ namespace ts {
|
||||
/**
|
||||
* Emits a node with possible leading and trailing source maps.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback The callback used to emit the node.
|
||||
*/
|
||||
function emitNodeWithSourceMap(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
|
||||
function emitNodeWithSourceMap(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (disabled) {
|
||||
return emitCallback(emitContext, node);
|
||||
return emitCallback(hint, node);
|
||||
}
|
||||
|
||||
if (node) {
|
||||
@@ -332,11 +330,11 @@ namespace ts {
|
||||
|
||||
if (emitFlags & EmitFlags.NoNestedSourceMaps) {
|
||||
disabled = true;
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
|
||||
if (node.kind !== SyntaxKind.NotEmittedStatement
|
||||
|
||||
+8
-1
@@ -485,7 +485,10 @@ namespace ts {
|
||||
// Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
|
||||
// (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
|
||||
let options: any;
|
||||
if (!directoryExists(directoryName)) {
|
||||
if (!directoryExists(directoryName) || (isUNCPath(directoryName) && process.platform === "win32")) {
|
||||
// do nothing if either
|
||||
// - target folder does not exist
|
||||
// - this is UNC path on Windows (https://github.com/Microsoft/TypeScript/issues/13874)
|
||||
return noOpFileWatcher;
|
||||
}
|
||||
|
||||
@@ -509,6 +512,10 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
function isUNCPath(s: string): boolean {
|
||||
return s.length > 2 && s.charCodeAt(0) === CharacterCodes.slash && s.charCodeAt(1) === CharacterCodes.slash;
|
||||
}
|
||||
},
|
||||
resolvePath: function(path: string): string {
|
||||
return _path.resolve(path);
|
||||
|
||||
+15
-15
@@ -105,14 +105,16 @@ namespace ts {
|
||||
hoistFunctionDeclaration,
|
||||
requestEmitHelper,
|
||||
readEmitHelpers,
|
||||
onSubstituteNode: (_emitContext, node) => node,
|
||||
onSubstituteNode: (_, node) => node,
|
||||
enableSubstitution,
|
||||
isSubstitutionEnabled,
|
||||
onEmitNode: (node, emitContext, emitCallback) => emitCallback(node, emitContext),
|
||||
onEmitNode: (hint, node, callback) => callback(hint, node),
|
||||
enableEmitNotification,
|
||||
isEmitNotificationEnabled
|
||||
};
|
||||
|
||||
performance.mark("beforeTransform");
|
||||
|
||||
// Chain together and initialize each transformer.
|
||||
const transformation = chain(...transformers)(context);
|
||||
|
||||
@@ -122,6 +124,9 @@ namespace ts {
|
||||
// Disable modification of the lexical environment.
|
||||
lexicalEnvironmentDisabled = true;
|
||||
|
||||
performance.mark("afterTransform");
|
||||
performance.measure("transformTime", "beforeTransform", "afterTransform");
|
||||
|
||||
return {
|
||||
transformed,
|
||||
emitNodeWithSubstitution,
|
||||
@@ -159,21 +164,16 @@ namespace ts {
|
||||
/**
|
||||
* Emits a node with possible substitution.
|
||||
*
|
||||
* @param emitContext The current emit context.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback The callback used to emit the node or its substitute.
|
||||
*/
|
||||
function emitNodeWithSubstitution(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
|
||||
function emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (node) {
|
||||
if (isSubstitutionEnabled(node)) {
|
||||
const substitute = context.onSubstituteNode(emitContext, node);
|
||||
if (substitute && substitute !== node) {
|
||||
emitCallback(emitContext, substitute);
|
||||
return;
|
||||
}
|
||||
node = context.onSubstituteNode(hint, node) || node;
|
||||
}
|
||||
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,17 +196,17 @@ namespace ts {
|
||||
/**
|
||||
* Emits a node with possible emit notification.
|
||||
*
|
||||
* @param emitContext The current emit context.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback The callback used to emit the node.
|
||||
*/
|
||||
function emitNodeWithNotification(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
|
||||
function emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (node) {
|
||||
if (isEmitNotificationEnabled(node)) {
|
||||
context.onEmitNode(emitContext, node, emitCallback);
|
||||
context.onEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
else {
|
||||
emitCallback(emitContext, node);
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,10 @@ namespace ts {
|
||||
Debug.assertNode(target, createAssignmentCallback ? isIdentifier : isExpression);
|
||||
const expression = createAssignmentCallback
|
||||
? createAssignmentCallback(<Identifier>target, value, location)
|
||||
: createAssignment(visitNode(<Expression>target, visitor, isExpression), value, location);
|
||||
: setTextRange(
|
||||
createAssignment(visitNode(<Expression>target, visitor, isExpression), value),
|
||||
location
|
||||
);
|
||||
expression.original = original;
|
||||
emitExpression(expression);
|
||||
}
|
||||
@@ -174,9 +177,10 @@ namespace ts {
|
||||
const variable = createVariableDeclaration(
|
||||
name,
|
||||
/*type*/ undefined,
|
||||
pendingExpressions ? inlineExpressions(append(pendingExpressions, value)) : value,
|
||||
location);
|
||||
pendingExpressions ? inlineExpressions(append(pendingExpressions, value)) : value
|
||||
);
|
||||
variable.original = original;
|
||||
setTextRange(variable, location);
|
||||
if (isIdentifier(name)) {
|
||||
setEmitFlags(variable, EmitFlags.NoNestedSourceMaps);
|
||||
}
|
||||
@@ -416,7 +420,7 @@ namespace ts {
|
||||
const temp = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
if (flattenContext.hoistTempVariables) {
|
||||
flattenContext.context.hoistVariableDeclaration(temp);
|
||||
flattenContext.emitExpression(createAssignment(temp, value, location));
|
||||
flattenContext.emitExpression(setTextRange(createAssignment(temp, value), location));
|
||||
}
|
||||
else {
|
||||
flattenContext.emitBindingOrAssignment(temp, value, location, /*original*/ undefined);
|
||||
@@ -492,6 +496,15 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
return createCall(getHelperName("__rest"), undefined, [value, createArrayLiteral(propertyNames, location)]);
|
||||
return createCall(
|
||||
getHelperName("__rest"),
|
||||
undefined,
|
||||
[
|
||||
value,
|
||||
setTextRange(
|
||||
createArrayLiteral(propertyNames),
|
||||
location
|
||||
)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
+211
-172
@@ -514,7 +514,7 @@ namespace ts {
|
||||
exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None);
|
||||
return updateSourceFileNode(
|
||||
node,
|
||||
createNodeArray(statements, node.statements)
|
||||
setTextRange(createNodeArray(statements), node.statements)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -671,9 +671,10 @@ namespace ts {
|
||||
setOriginalNode(variable, node);
|
||||
|
||||
const statements: Statement[] = [];
|
||||
const statement = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([variable]), /*location*/ node);
|
||||
const statement = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([variable]));
|
||||
|
||||
setOriginalNode(statement, node);
|
||||
setTextRange(statement, node);
|
||||
startOnNewLine(statement);
|
||||
statements.push(statement);
|
||||
|
||||
@@ -818,7 +819,7 @@ namespace ts {
|
||||
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
|
||||
const block = createBlock(createNodeArray(statements, /*location*/ node.members), /*location*/ undefined, /*multiLine*/ true);
|
||||
const block = createBlock(setTextRange(createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true);
|
||||
setEmitFlags(block, EmitFlags.NoComments);
|
||||
return block;
|
||||
}
|
||||
@@ -833,8 +834,10 @@ namespace ts {
|
||||
function addExtendsHelperIfNeeded(statements: Statement[], node: ClassExpression | ClassDeclaration, extendsClauseElement: ExpressionWithTypeArguments): void {
|
||||
if (extendsClauseElement) {
|
||||
statements.push(
|
||||
createStatement(
|
||||
createExtendsHelper(context, getLocalName(node)),
|
||||
setTextRange(
|
||||
createStatement(
|
||||
createExtendsHelper(context, getLocalName(node))
|
||||
),
|
||||
/*location*/ extendsClauseElement
|
||||
)
|
||||
);
|
||||
@@ -854,19 +857,18 @@ namespace ts {
|
||||
const ancestorFacts = enterSubtree(HierarchyFacts.ConstructorExcludes, HierarchyFacts.ConstructorIncludes);
|
||||
const constructor = getFirstConstructorWithBody(node);
|
||||
const hasSynthesizedSuper = hasSynthesizedDefaultSuperCall(constructor, extendsClauseElement !== undefined);
|
||||
const constructorFunction =
|
||||
createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
getDeclarationName(node),
|
||||
/*typeParameters*/ undefined,
|
||||
transformConstructorParameters(constructor, hasSynthesizedSuper),
|
||||
/*type*/ undefined,
|
||||
transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper),
|
||||
/*location*/ constructor || node
|
||||
);
|
||||
const constructorFunction = createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
getDeclarationName(node),
|
||||
/*typeParameters*/ undefined,
|
||||
transformConstructorParameters(constructor, hasSynthesizedSuper),
|
||||
/*type*/ undefined,
|
||||
transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper)
|
||||
);
|
||||
|
||||
setTextRange(constructorFunction, constructor || node);
|
||||
if (extendsClauseElement) {
|
||||
setEmitFlags(constructorFunction, EmitFlags.CapturesThis);
|
||||
}
|
||||
@@ -962,14 +964,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
const block = createBlock(
|
||||
createNodeArray(
|
||||
statements,
|
||||
setTextRange(
|
||||
createNodeArray(
|
||||
statements
|
||||
),
|
||||
/*location*/ constructor ? constructor.body.statements : node.members
|
||||
),
|
||||
/*location*/ constructor ? constructor.body : node,
|
||||
/*multiLine*/ true
|
||||
);
|
||||
|
||||
setTextRange(block, constructor ? constructor.body : node);
|
||||
if (!constructor) {
|
||||
setEmitFlags(block, EmitFlags.NoComments);
|
||||
}
|
||||
@@ -1139,14 +1143,16 @@ namespace ts {
|
||||
// Binding patterns are converted into a generated name and are
|
||||
// evaluated inside the function body.
|
||||
return setOriginalNode(
|
||||
createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
getGeneratedNameForNode(node),
|
||||
/*questionToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
/*initializer*/ undefined,
|
||||
setTextRange(
|
||||
createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
getGeneratedNameForNode(node),
|
||||
/*questionToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
/*initializer*/ undefined
|
||||
),
|
||||
/*location*/ node
|
||||
),
|
||||
/*original*/ node
|
||||
@@ -1155,14 +1161,16 @@ namespace ts {
|
||||
else if (node.initializer) {
|
||||
// Initializers are elided
|
||||
return setOriginalNode(
|
||||
createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
node.name,
|
||||
/*questionToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
/*initializer*/ undefined,
|
||||
setTextRange(
|
||||
createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
node.name,
|
||||
/*questionToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
/*initializer*/ undefined
|
||||
),
|
||||
/*location*/ node
|
||||
),
|
||||
/*original*/ node
|
||||
@@ -1274,21 +1282,25 @@ namespace ts {
|
||||
const statement = createIf(
|
||||
createTypeCheck(getSynthesizedClone(name), "undefined"),
|
||||
setEmitFlags(
|
||||
createBlock([
|
||||
createStatement(
|
||||
createAssignment(
|
||||
setEmitFlags(getMutableClone(name), EmitFlags.NoSourceMap),
|
||||
setEmitFlags(initializer, EmitFlags.NoSourceMap | getEmitFlags(initializer)),
|
||||
/*location*/ parameter
|
||||
setTextRange(
|
||||
createBlock([
|
||||
createStatement(
|
||||
setTextRange(
|
||||
createAssignment(
|
||||
setEmitFlags(getMutableClone(name), EmitFlags.NoSourceMap),
|
||||
setEmitFlags(initializer, EmitFlags.NoSourceMap | getEmitFlags(initializer))
|
||||
),
|
||||
parameter
|
||||
)
|
||||
)
|
||||
)
|
||||
], /*location*/ parameter),
|
||||
]),
|
||||
parameter
|
||||
),
|
||||
EmitFlags.SingleLine | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTokenSourceMaps
|
||||
),
|
||||
/*elseStatement*/ undefined,
|
||||
/*location*/ parameter
|
||||
)
|
||||
);
|
||||
statement.startsOnNewLine = true;
|
||||
setTextRange(statement, parameter);
|
||||
setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.CustomPrologue);
|
||||
statements.push(statement);
|
||||
}
|
||||
@@ -1332,15 +1344,17 @@ namespace ts {
|
||||
// var param = [];
|
||||
statements.push(
|
||||
setEmitFlags(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
declarationName,
|
||||
/*type*/ undefined,
|
||||
createArrayLiteral([])
|
||||
)
|
||||
]),
|
||||
setTextRange(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
declarationName,
|
||||
/*type*/ undefined,
|
||||
createArrayLiteral([])
|
||||
)
|
||||
])
|
||||
),
|
||||
/*location*/ parameter
|
||||
),
|
||||
EmitFlags.CustomPrologue
|
||||
@@ -1351,26 +1365,33 @@ namespace ts {
|
||||
// param[_i - restIndex] = arguments[_i];
|
||||
// }
|
||||
const forStatement = createFor(
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(temp, /*type*/ undefined, createLiteral(restIndex))
|
||||
], /*location*/ parameter),
|
||||
createLessThan(
|
||||
temp,
|
||||
createPropertyAccess(createIdentifier("arguments"), "length"),
|
||||
/*location*/ parameter
|
||||
setTextRange(
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(temp, /*type*/ undefined, createLiteral(restIndex))
|
||||
]),
|
||||
parameter
|
||||
),
|
||||
createPostfixIncrement(temp, /*location*/ parameter),
|
||||
setTextRange(
|
||||
createLessThan(
|
||||
temp,
|
||||
createPropertyAccess(createIdentifier("arguments"), "length")
|
||||
),
|
||||
parameter
|
||||
),
|
||||
setTextRange(createPostfixIncrement(temp), parameter),
|
||||
createBlock([
|
||||
startOnNewLine(
|
||||
createStatement(
|
||||
createAssignment(
|
||||
createElementAccess(
|
||||
expressionName,
|
||||
restIndex === 0
|
||||
? temp
|
||||
: createSubtract(temp, createLiteral(restIndex))
|
||||
),
|
||||
createElementAccess(createIdentifier("arguments"), temp)
|
||||
setTextRange(
|
||||
createStatement(
|
||||
createAssignment(
|
||||
createElementAccess(
|
||||
expressionName,
|
||||
restIndex === 0
|
||||
? temp
|
||||
: createSubtract(temp, createLiteral(restIndex))
|
||||
),
|
||||
createElementAccess(createIdentifier("arguments"), temp)
|
||||
)
|
||||
),
|
||||
/*location*/ parameter
|
||||
)
|
||||
@@ -1405,11 +1426,10 @@ namespace ts {
|
||||
/*type*/ undefined,
|
||||
initializer
|
||||
)
|
||||
]),
|
||||
originalStatement
|
||||
])
|
||||
);
|
||||
|
||||
setEmitFlags(captureThisStatement, EmitFlags.NoComments | EmitFlags.CustomPrologue);
|
||||
setTextRange(captureThisStatement, originalStatement);
|
||||
setSourceMapRange(captureThisStatement, node);
|
||||
statements.push(captureThisStatement);
|
||||
}
|
||||
@@ -1529,7 +1549,7 @@ namespace ts {
|
||||
* @param member The SemicolonClassElement node.
|
||||
*/
|
||||
function transformSemicolonClassElementToStatement(member: SemicolonClassElement) {
|
||||
return createEmptyStatement(/*location*/ member);
|
||||
return setTextRange(createEmptyStatement(), member);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1547,8 +1567,10 @@ namespace ts {
|
||||
setEmitFlags(memberFunction, EmitFlags.NoComments);
|
||||
setSourceMapRange(memberFunction, sourceMapRange);
|
||||
|
||||
const statement = createStatement(
|
||||
createAssignment(memberName, memberFunction),
|
||||
const statement = setTextRange(
|
||||
createStatement(
|
||||
createAssignment(memberName, memberFunction)
|
||||
),
|
||||
/*location*/ member
|
||||
);
|
||||
|
||||
@@ -1571,15 +1593,12 @@ namespace ts {
|
||||
* @param accessors The set of related get/set accessors.
|
||||
*/
|
||||
function transformAccessorsToStatement(receiver: LeftHandSideExpression, accessors: AllAccessorDeclarations, container: Node): Statement {
|
||||
const statement = createStatement(
|
||||
transformAccessorsToExpression(receiver, accessors, container, /*startsOnNewLine*/ false),
|
||||
/*location*/ getSourceMapRange(accessors.firstAccessor)
|
||||
);
|
||||
|
||||
const statement = createStatement(transformAccessorsToExpression(receiver, accessors, container, /*startsOnNewLine*/ false));
|
||||
// The location for the statement is used to emit source maps only.
|
||||
// No comments should be emitted for this statement to align with the
|
||||
// old emitter.
|
||||
setEmitFlags(statement, EmitFlags.NoComments);
|
||||
setSourceMapRange(statement, getSourceMapRange(accessors.firstAccessor));
|
||||
return statement;
|
||||
}
|
||||
|
||||
@@ -1622,8 +1641,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
properties.push(
|
||||
createPropertyAssignment("enumerable", createLiteral(true)),
|
||||
createPropertyAssignment("configurable", createLiteral(true))
|
||||
createPropertyAssignment("enumerable", createTrue()),
|
||||
createPropertyAssignment("configurable", createTrue())
|
||||
);
|
||||
|
||||
const call = createCall(
|
||||
@@ -1632,7 +1651,7 @@ namespace ts {
|
||||
[
|
||||
target,
|
||||
propertyName,
|
||||
createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true)
|
||||
createObjectLiteral(properties, /*multiLine*/ true)
|
||||
]
|
||||
);
|
||||
if (startsOnNewLine) {
|
||||
@@ -1662,9 +1681,9 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node),
|
||||
node
|
||||
transformFunctionBody(node)
|
||||
);
|
||||
setTextRange(func, node);
|
||||
setOriginalNode(func, node);
|
||||
setEmitFlags(func, EmitFlags.CapturesThis);
|
||||
exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None);
|
||||
@@ -1758,14 +1777,16 @@ namespace ts {
|
||||
exitSubtree(ancestorFacts, HierarchyFacts.PropagateNewTargetMask, HierarchyFacts.None);
|
||||
convertedLoopState = savedConvertedLoopState;
|
||||
return setOriginalNode(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
node.asteriskToken,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
parameters,
|
||||
/*type*/ undefined,
|
||||
body,
|
||||
setTextRange(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
node.asteriskToken,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
parameters,
|
||||
/*type*/ undefined,
|
||||
body
|
||||
),
|
||||
location
|
||||
),
|
||||
/*original*/ node
|
||||
@@ -1832,7 +1853,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
const expression = visitNode(body, visitor, isExpression);
|
||||
const returnStatement = createReturn(expression, /*location*/ body);
|
||||
const returnStatement = createReturn(expression);
|
||||
setTextRange(returnStatement, body);
|
||||
setEmitFlags(returnStatement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTrailingComments);
|
||||
statements.push(returnStatement);
|
||||
|
||||
@@ -1851,7 +1873,8 @@ namespace ts {
|
||||
multiLine = true;
|
||||
}
|
||||
|
||||
const block = createBlock(createNodeArray(statements, statementsLocation), node.body, multiLine);
|
||||
const block = createBlock(setTextRange(createNodeArray(statements), statementsLocation), multiLine);
|
||||
setTextRange(block, node.body);
|
||||
if (!multiLine && singleLine) {
|
||||
setEmitFlags(block, EmitFlags.SingleLine);
|
||||
}
|
||||
@@ -1868,8 +1891,10 @@ namespace ts {
|
||||
const updated = visitFunctionBody(node.body, functionBodyVisitor, context);
|
||||
return updateBlock(
|
||||
updated,
|
||||
createNodeArray(
|
||||
prependCaptureNewTargetIfNeeded(updated.statements, node, /*copyOnWrite*/ true),
|
||||
setTextRange(
|
||||
createNodeArray(
|
||||
prependCaptureNewTargetIfNeeded(updated.statements, node, /*copyOnWrite*/ true)
|
||||
),
|
||||
/*location*/ updated.statements
|
||||
)
|
||||
);
|
||||
@@ -1969,7 +1994,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
if (assignments) {
|
||||
updated = createStatement(reduceLeft(assignments, (acc, v) => createBinary(v, SyntaxKind.CommaToken, acc)), node);
|
||||
updated = setTextRange(createStatement(reduceLeft(assignments, (acc, v) => createBinary(v, SyntaxKind.CommaToken, acc))), node);
|
||||
}
|
||||
else {
|
||||
// none of declarations has initializer - the entire variable statement can be deleted
|
||||
@@ -1999,8 +2024,9 @@ namespace ts {
|
||||
? visitVariableDeclarationInLetDeclarationList
|
||||
: visitVariableDeclaration));
|
||||
|
||||
const declarationList = createVariableDeclarationList(declarations, /*location*/ node);
|
||||
const declarationList = createVariableDeclarationList(declarations);
|
||||
setOriginalNode(declarationList, node);
|
||||
setTextRange(declarationList, node);
|
||||
setCommentRange(declarationList, node);
|
||||
|
||||
if (node.transformFlags & TransformFlags.ContainsBindingPattern
|
||||
@@ -2225,7 +2251,7 @@ namespace ts {
|
||||
// we don't want to emit a temporary variable for the RHS, just use it directly.
|
||||
const counter = createLoopVariable();
|
||||
const rhsReference = expression.kind === SyntaxKind.Identifier
|
||||
? createUniqueName((<Identifier>expression).text)
|
||||
? createUniqueName(unescapeIdentifier((<Identifier>expression).text))
|
||||
: createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const elementAccess = createElementAccess(rhsReference, counter);
|
||||
|
||||
@@ -2248,8 +2274,9 @@ namespace ts {
|
||||
elementAccess
|
||||
);
|
||||
|
||||
const declarationList = createVariableDeclarationList(declarations, /*location*/ initializer);
|
||||
const declarationList = createVariableDeclarationList(declarations);
|
||||
setOriginalNode(declarationList, initializer);
|
||||
setTextRange(declarationList, initializer);
|
||||
|
||||
// Adjust the source map range for the first declaration to align with the old
|
||||
// emitter.
|
||||
@@ -2268,19 +2295,24 @@ namespace ts {
|
||||
// The following call does not include the initializer, so we have
|
||||
// to emit it separately.
|
||||
statements.push(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
setOriginalNode(
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined),
|
||||
/*type*/ undefined,
|
||||
createElementAccess(rhsReference, counter)
|
||||
)
|
||||
], /*location*/ moveRangePos(initializer, -1)),
|
||||
initializer
|
||||
setTextRange(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
setOriginalNode(
|
||||
setTextRange(
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined),
|
||||
/*type*/ undefined,
|
||||
createElementAccess(rhsReference, counter)
|
||||
)
|
||||
]),
|
||||
moveRangePos(initializer, -1)
|
||||
),
|
||||
initializer
|
||||
)
|
||||
),
|
||||
/*location*/ moveRangeEnd(initializer, -1)
|
||||
moveRangeEnd(initializer, -1)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -2306,7 +2338,7 @@ namespace ts {
|
||||
// Currently there is not way to check that assignment is binary expression of destructing assignment
|
||||
// so we have to cast never type to binaryExpression
|
||||
(<BinaryExpression>assignment).end = initializer.end;
|
||||
statements.push(createStatement(assignment, /*location*/ moveRangeEnd(initializer, -1)));
|
||||
statements.push(setTextRange(createStatement(assignment), moveRangeEnd(initializer, -1)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2332,33 +2364,38 @@ namespace ts {
|
||||
|
||||
// The old emitter does not emit source maps for the block.
|
||||
// We add the location to preserve comments.
|
||||
const body = createBlock(
|
||||
createNodeArray(statements, /*location*/ statementsLocation),
|
||||
/*location*/ bodyLocation
|
||||
);
|
||||
|
||||
const body = createBlock(setTextRange(createNodeArray(statements), /*location*/ statementsLocation));
|
||||
setTextRange(body, bodyLocation);
|
||||
setEmitFlags(body, EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps);
|
||||
|
||||
const forStatement = createFor(
|
||||
setEmitFlags(
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0), /*location*/ moveRangePos(node.expression, -1)),
|
||||
createVariableDeclaration(rhsReference, /*type*/ undefined, expression, /*location*/ node.expression)
|
||||
], /*location*/ node.expression),
|
||||
setTextRange(
|
||||
createVariableDeclarationList([
|
||||
setTextRange(createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0)), moveRangePos(node.expression, -1)),
|
||||
setTextRange(createVariableDeclaration(rhsReference, /*type*/ undefined, expression), node.expression)
|
||||
]),
|
||||
node.expression
|
||||
),
|
||||
EmitFlags.NoHoisting
|
||||
),
|
||||
createLessThan(
|
||||
counter,
|
||||
createPropertyAccess(rhsReference, "length"),
|
||||
/*location*/ node.expression
|
||||
setTextRange(
|
||||
createLessThan(
|
||||
counter,
|
||||
createPropertyAccess(rhsReference, "length")
|
||||
),
|
||||
node.expression
|
||||
),
|
||||
createPostfixIncrement(counter, /*location*/ node.expression),
|
||||
body,
|
||||
/*location*/ node
|
||||
setTextRange(
|
||||
createPostfixIncrement(counter),
|
||||
node.expression
|
||||
),
|
||||
body
|
||||
);
|
||||
|
||||
// Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter.
|
||||
setEmitFlags(forStatement, EmitFlags.NoTokenTrailingSourceMaps);
|
||||
setTextRange(forStatement, node);
|
||||
return restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel);
|
||||
}
|
||||
|
||||
@@ -2418,7 +2455,6 @@ namespace ts {
|
||||
setEmitFlags(
|
||||
createObjectLiteral(
|
||||
visitNodes(properties, visitor, isObjectLiteralElementLike, 0, numInitialProperties),
|
||||
/*location*/ undefined,
|
||||
node.multiLine
|
||||
),
|
||||
EmitFlags.Indented
|
||||
@@ -2546,14 +2582,14 @@ namespace ts {
|
||||
copyOutParameters(loopOutParameters, CopyDirection.ToOutParameter, statements);
|
||||
}
|
||||
addRange(statements, lexicalEnvironment)
|
||||
loopBody = createBlock(statements, /*location*/ undefined, /*multiline*/ true);
|
||||
loopBody = createBlock(statements, /*multiline*/ true);
|
||||
}
|
||||
|
||||
if (isBlock(loopBody)) {
|
||||
loopBody.multiLine = true;
|
||||
}
|
||||
else {
|
||||
loopBody = createBlock([loopBody], /*location*/ undefined, /*multiline*/ true);
|
||||
loopBody = createBlock([loopBody], /*multiline*/ true);
|
||||
}
|
||||
|
||||
const isAsyncBlockContainingAwait =
|
||||
@@ -2687,12 +2723,7 @@ namespace ts {
|
||||
// visit childnodes to transform initializer/condition/incrementor parts
|
||||
clone = visitEachChild(clone, visitor, context);
|
||||
// set loop statement
|
||||
clone.statement = createBlock(
|
||||
convertedLoopBodyStatements,
|
||||
/*location*/ undefined,
|
||||
/*multiline*/ true
|
||||
);
|
||||
|
||||
clone.statement = createBlock(convertedLoopBodyStatements, /*multiline*/ true);
|
||||
// reset and re-aggregate the transform flags
|
||||
clone.transformFlags = 0;
|
||||
aggregateTransformFlags(clone);
|
||||
@@ -2841,7 +2872,7 @@ namespace ts {
|
||||
else {
|
||||
loopParameters.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
|
||||
if (resolver.getNodeCheckFlags(decl) & NodeCheckFlags.NeedsLoopOutParameter) {
|
||||
const outParamName = createUniqueName("out_" + name.text);
|
||||
const outParamName = createUniqueName("out_" + unescapeIdentifier(name.text));
|
||||
loopOutParameters.push({ originalName: name, outParamName });
|
||||
}
|
||||
}
|
||||
@@ -2903,9 +2934,9 @@ namespace ts {
|
||||
receiver,
|
||||
visitNode(property.name, visitor, isPropertyName)
|
||||
),
|
||||
visitNode(property.initializer, visitor, isExpression),
|
||||
/*location*/ property
|
||||
visitNode(property.initializer, visitor, isExpression)
|
||||
);
|
||||
setTextRange(expression, property);
|
||||
if (startsOnNewLine) {
|
||||
expression.startsOnNewLine = true;
|
||||
}
|
||||
@@ -2925,9 +2956,9 @@ namespace ts {
|
||||
receiver,
|
||||
visitNode(property.name, visitor, isPropertyName)
|
||||
),
|
||||
getSynthesizedClone(property.name),
|
||||
/*location*/ property
|
||||
getSynthesizedClone(property.name)
|
||||
);
|
||||
setTextRange(expression, property);
|
||||
if (startsOnNewLine) {
|
||||
expression.startsOnNewLine = true;
|
||||
}
|
||||
@@ -2948,9 +2979,9 @@ namespace ts {
|
||||
receiver,
|
||||
visitNode(method.name, visitor, isPropertyName)
|
||||
),
|
||||
transformFunctionLikeToExpression(method, /*location*/ method, /*name*/ undefined, container),
|
||||
/*location*/ method
|
||||
transformFunctionLikeToExpression(method, /*location*/ method, /*name*/ undefined, container)
|
||||
);
|
||||
setTextRange(expression, method);
|
||||
if (startsOnNewLine) {
|
||||
expression.startsOnNewLine = true;
|
||||
}
|
||||
@@ -2963,7 +2994,8 @@ namespace ts {
|
||||
let updated: CatchClause;
|
||||
if (isBindingPattern(node.variableDeclaration.name)) {
|
||||
const temp = createTempVariable(undefined);
|
||||
const newVariableDeclaration = createVariableDeclaration(temp, undefined, undefined, node.variableDeclaration);
|
||||
const newVariableDeclaration = createVariableDeclaration(temp);
|
||||
setTextRange(newVariableDeclaration, node.variableDeclaration);
|
||||
const vars = flattenDestructuringBinding(
|
||||
node.variableDeclaration,
|
||||
visitor,
|
||||
@@ -2971,8 +3003,9 @@ namespace ts {
|
||||
FlattenLevel.All,
|
||||
temp
|
||||
);
|
||||
const list = createVariableDeclarationList(vars, /*location*/node.variableDeclaration, /*flags*/node.variableDeclaration.flags);
|
||||
const destructure = createVariableStatement(undefined, list);
|
||||
const list = createVariableDeclarationList(vars);
|
||||
setTextRange(list, node.variableDeclaration);
|
||||
const destructure = createVariableStatement(/*modifiers*/ undefined, list);
|
||||
updated = updateCatchClause(node, newVariableDeclaration, addStatementToStartOfBlock(node.block, destructure));
|
||||
}
|
||||
else {
|
||||
@@ -3001,9 +3034,11 @@ namespace ts {
|
||||
Debug.assert(!isComputedPropertyName(node.name));
|
||||
const functionExpression = transformFunctionLikeToExpression(node, /*location*/ moveRangePos(node, -1), /*name*/ undefined, /*container*/ undefined);
|
||||
setEmitFlags(functionExpression, EmitFlags.NoLeadingComments | getEmitFlags(functionExpression));
|
||||
return createPropertyAssignment(
|
||||
node.name,
|
||||
functionExpression,
|
||||
return setTextRange(
|
||||
createPropertyAssignment(
|
||||
node.name,
|
||||
functionExpression
|
||||
),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
@@ -3030,9 +3065,11 @@ namespace ts {
|
||||
* @param node A ShorthandPropertyAssignment node.
|
||||
*/
|
||||
function visitShorthandPropertyAssignment(node: ShorthandPropertyAssignment): ObjectLiteralElementLike {
|
||||
return createPropertyAssignment(
|
||||
node.name,
|
||||
getSynthesizedClone(node.name),
|
||||
return setTextRange(
|
||||
createPropertyAssignment(
|
||||
node.name,
|
||||
getSynthesizedClone(node.name)
|
||||
),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
@@ -3225,8 +3262,7 @@ namespace ts {
|
||||
|
||||
function visitSpanOfNonSpreads(chunk: Expression[], multiLine: boolean, hasTrailingComma: boolean): VisitResult<Expression> {
|
||||
return createArrayLiteral(
|
||||
visitNodes(createNodeArray(chunk, /*location*/ undefined, hasTrailingComma), visitor, isExpression),
|
||||
/*location*/ undefined,
|
||||
visitNodes(createNodeArray(chunk, hasTrailingComma), visitor, isExpression),
|
||||
multiLine
|
||||
);
|
||||
}
|
||||
@@ -3250,7 +3286,7 @@ namespace ts {
|
||||
* @param node A template literal.
|
||||
*/
|
||||
function visitTemplateLiteral(node: LiteralExpression): LeftHandSideExpression {
|
||||
return createLiteral(node.text, /*location*/ node);
|
||||
return setTextRange(createLiteral(node.text), node);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3318,7 +3354,7 @@ namespace ts {
|
||||
// ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's
|
||||
// <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for both TV and TRV.
|
||||
text = text.replace(/\r\n?/g, "\n");
|
||||
return createLiteral(text, /*location*/ node);
|
||||
return setTextRange(createLiteral(text), node);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3342,7 +3378,8 @@ namespace ts {
|
||||
// "abc" + (1 << 2) + ""
|
||||
const expression = reduceLeft(expressions, createAdd);
|
||||
if (nodeIsSynthesized(expression)) {
|
||||
setTextRange(expression, node);
|
||||
expression.pos = node.pos;
|
||||
expression.end = node.end;
|
||||
}
|
||||
|
||||
return expression;
|
||||
@@ -3435,9 +3472,11 @@ namespace ts {
|
||||
/**
|
||||
* Called by the printer just before a node is printed.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to be printed.
|
||||
* @param emitCallback The callback used to emit the node.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis && isFunctionLike(node)) {
|
||||
// If we are tracking a captured `this`, keep track of the enclosing function.
|
||||
const ancestorFacts = enterSubtree(
|
||||
@@ -3445,11 +3484,11 @@ namespace ts {
|
||||
getEmitFlags(node) & EmitFlags.CapturesThis
|
||||
? HierarchyFacts.FunctionIncludes | HierarchyFacts.CapturesThis
|
||||
: HierarchyFacts.FunctionIncludes);
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None);
|
||||
return;
|
||||
}
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3484,13 +3523,13 @@ namespace ts {
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param emitContext The context for the emitter.
|
||||
* @param hint The context for the emitter.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
|
||||
if (emitContext === EmitContext.Expression) {
|
||||
if (hint === EmitHint.Expression) {
|
||||
return substituteExpression(node);
|
||||
}
|
||||
|
||||
@@ -3578,7 +3617,7 @@ namespace ts {
|
||||
function substituteThisKeyword(node: PrimaryExpression): PrimaryExpression {
|
||||
if (enabledSubstitutions & ES2015SubstitutionFlags.CapturedThis
|
||||
&& hierarchyFacts & HierarchyFacts.CapturesThis) {
|
||||
return createIdentifier("_this", /*location*/ node);
|
||||
return setTextRange(createIdentifier("_this"), node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -48,29 +48,37 @@ namespace ts {
|
||||
// Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)`
|
||||
const expressionTemp = createTempVariable(hoistVariableDeclaration);
|
||||
const argumentExpressionTemp = createTempVariable(hoistVariableDeclaration);
|
||||
target = createElementAccess(
|
||||
createAssignment(expressionTemp, left.expression, /*location*/ left.expression),
|
||||
createAssignment(argumentExpressionTemp, left.argumentExpression, /*location*/ left.argumentExpression),
|
||||
/*location*/ left
|
||||
target = setTextRange(
|
||||
createElementAccess(
|
||||
setTextRange(createAssignment(expressionTemp, left.expression), left.expression),
|
||||
setTextRange(createAssignment(argumentExpressionTemp, left.argumentExpression), left.argumentExpression)
|
||||
),
|
||||
left
|
||||
);
|
||||
value = createElementAccess(
|
||||
expressionTemp,
|
||||
argumentExpressionTemp,
|
||||
/*location*/ left
|
||||
value = setTextRange(
|
||||
createElementAccess(
|
||||
expressionTemp,
|
||||
argumentExpressionTemp
|
||||
),
|
||||
left
|
||||
);
|
||||
}
|
||||
else if (isPropertyAccessExpression(left)) {
|
||||
// Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)`
|
||||
const expressionTemp = createTempVariable(hoistVariableDeclaration);
|
||||
target = createPropertyAccess(
|
||||
createAssignment(expressionTemp, left.expression, /*location*/ left.expression),
|
||||
left.name,
|
||||
/*location*/ left
|
||||
target = setTextRange(
|
||||
createPropertyAccess(
|
||||
setTextRange(createAssignment(expressionTemp, left.expression), left.expression),
|
||||
left.name
|
||||
),
|
||||
left
|
||||
);
|
||||
value = createPropertyAccess(
|
||||
expressionTemp,
|
||||
left.name,
|
||||
/*location*/ left
|
||||
value = setTextRange(
|
||||
createPropertyAccess(
|
||||
expressionTemp,
|
||||
left.name
|
||||
),
|
||||
left
|
||||
);
|
||||
}
|
||||
else {
|
||||
@@ -78,7 +86,13 @@ namespace ts {
|
||||
target = left;
|
||||
value = left;
|
||||
}
|
||||
return createAssignment(target, createMathPow(value, right, /*location*/ node), /*location*/ node);
|
||||
return setTextRange(
|
||||
createAssignment(
|
||||
target,
|
||||
createMathPow(value, right, /*location*/ node)
|
||||
),
|
||||
node
|
||||
);
|
||||
}
|
||||
|
||||
function visitExponentiationExpression(node: BinaryExpression) {
|
||||
|
||||
@@ -104,10 +104,12 @@ namespace ts {
|
||||
*/
|
||||
function visitAwaitExpression(node: AwaitExpression): Expression {
|
||||
return setOriginalNode(
|
||||
createYield(
|
||||
/*asteriskToken*/ undefined,
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
/*location*/ node
|
||||
setTextRange(
|
||||
createYield(
|
||||
/*asteriskToken*/ undefined,
|
||||
visitNode(node.expression, visitor, isExpression)
|
||||
),
|
||||
node
|
||||
),
|
||||
node
|
||||
);
|
||||
@@ -238,7 +240,8 @@ namespace ts {
|
||||
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
|
||||
const block = createBlock(statements, /*location*/ node.body, /*multiLine*/ true);
|
||||
const block = createBlock(statements, /*multiLine*/ true);
|
||||
setTextRange(block, node.body);
|
||||
|
||||
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
|
||||
// This step isn't needed if we eventually transform this to ES5.
|
||||
@@ -266,7 +269,7 @@ namespace ts {
|
||||
const declarations = endLexicalEnvironment();
|
||||
if (some(declarations)) {
|
||||
const block = convertToFunctionBody(expression);
|
||||
return updateBlock(block, createNodeArray(concatenate(block.statements, declarations), block.statements));
|
||||
return updateBlock(block, setTextRange(createNodeArray(concatenate(block.statements, declarations)), block.statements));
|
||||
}
|
||||
|
||||
return expression;
|
||||
@@ -281,7 +284,7 @@ namespace ts {
|
||||
startLexicalEnvironment();
|
||||
const visited = convertToFunctionBody(visitNode(body, visitor, isConciseBody));
|
||||
const declarations = endLexicalEnvironment();
|
||||
return updateBlock(visited, createNodeArray(concatenate(visited.statements, declarations), visited.statements));
|
||||
return updateBlock(visited, setTextRange(createNodeArray(concatenate(visited.statements, declarations)), visited.statements));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,33 +399,33 @@ namespace ts {
|
||||
/**
|
||||
* Hook for node emit.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emit A callback used to emit the node in the printer.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
// If we need to support substitutions for `super` in an async method,
|
||||
// we should track it here.
|
||||
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
|
||||
const savedCurrentSuperContainer = currentSuperContainer;
|
||||
currentSuperContainer = node;
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
currentSuperContainer = savedCurrentSuperContainer;
|
||||
}
|
||||
else {
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
* @param isExpression A value indicating whether the node is to be used in an expression
|
||||
* position.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
if (emitContext === EmitContext.Expression) {
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (hint === EmitHint.Expression) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
|
||||
@@ -431,21 +434,25 @@ namespace ts {
|
||||
|
||||
function createSuperAccessInAsyncMethod(argumentExpression: Expression, flags: NodeCheckFlags, location: TextRange): LeftHandSideExpression {
|
||||
if (flags & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
return createPropertyAccess(
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
createCall(
|
||||
createIdentifier("_super"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression]
|
||||
),
|
||||
"value"
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
else {
|
||||
return setTextRange(
|
||||
createCall(
|
||||
createIdentifier("_super"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression]
|
||||
),
|
||||
"value",
|
||||
location
|
||||
);
|
||||
}
|
||||
else {
|
||||
return createCall(
|
||||
createIdentifier("_super"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression],
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace ts {
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
|
||||
// enable emit notification only if using --jsx preserve or react-native
|
||||
let previousOnEmitNode: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void;
|
||||
let previousOnEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
let noSubstitution: boolean[];
|
||||
if (compilerOptions.jsx === JsxEmit.Preserve || compilerOptions.jsx === JsxEmit.ReactNative) {
|
||||
previousOnEmitNode = context.onEmitNode;
|
||||
@@ -41,9 +41,11 @@ namespace ts {
|
||||
/**
|
||||
* Called by the printer just before a node is printed.
|
||||
*
|
||||
* @param node The node to be printed.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback A callback used to emit the node.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) {
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (emitContext: EmitHint, node: Node) => void) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
case SyntaxKind.JsxClosingElement:
|
||||
@@ -53,21 +55,21 @@ namespace ts {
|
||||
break;
|
||||
}
|
||||
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param emitContext The context for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
if (node.id && noSubstitution && noSubstitution[node.id]) {
|
||||
return previousOnSubstituteNode(emitContext, node);
|
||||
return previousOnSubstituteNode(hint, node);
|
||||
}
|
||||
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (isPropertyAccessExpression(node)) {
|
||||
return substitutePropertyAccessExpression(node);
|
||||
}
|
||||
@@ -85,7 +87,7 @@ namespace ts {
|
||||
function substitutePropertyAccessExpression(node: PropertyAccessExpression): Expression {
|
||||
const literalName = trySubstituteReservedName(node.name);
|
||||
if (literalName) {
|
||||
return createElementAccess(node.expression, literalName, /*location*/ node);
|
||||
return setTextRange(createElementAccess(node.expression, literalName), node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -111,7 +113,7 @@ namespace ts {
|
||||
function trySubstituteReservedName(name: Identifier) {
|
||||
const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(name.text) : undefined);
|
||||
if (token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord) {
|
||||
return createLiteral(name, /*location*/ name);
|
||||
return setTextRange(createLiteral(name), name);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -210,36 +210,40 @@ namespace ts {
|
||||
const statement = createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
updateVariableDeclarationList(initializer, declarations),
|
||||
/*location*/ initializer
|
||||
);
|
||||
setTextRange(statement, initializer);
|
||||
leadingStatements = append(leadingStatements, statement);
|
||||
}
|
||||
}
|
||||
else if (isAssignmentPattern(initializer)) {
|
||||
temp = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const expression = flattenDestructuringAssignment(
|
||||
aggregateTransformFlags(createAssignment(initializer, temp, /*location*/ node.initializer)),
|
||||
aggregateTransformFlags(
|
||||
setTextRange(
|
||||
createAssignment(initializer, temp),
|
||||
node.initializer
|
||||
)
|
||||
),
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.ObjectRest
|
||||
);
|
||||
leadingStatements = append(leadingStatements, createStatement(expression, /*location*/ node.initializer));
|
||||
leadingStatements = append(leadingStatements, setTextRange(createStatement(expression), node.initializer));
|
||||
}
|
||||
}
|
||||
if (temp) {
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
const statement = visitNode(node.statement, visitor, isStatement);
|
||||
const block = isBlock(statement)
|
||||
? updateBlock(statement, createNodeArray(concatenate(leadingStatements, statement.statements), statement.statements))
|
||||
: createBlock(append(leadingStatements, statement), statement, /*multiLine*/ true);
|
||||
? updateBlock(statement, setTextRange(createNodeArray(concatenate(leadingStatements, statement.statements)), statement.statements))
|
||||
: setTextRange(createBlock(append(leadingStatements, statement), /*multiLine*/ true), statement);
|
||||
return updateForOf(
|
||||
node,
|
||||
createVariableDeclarationList(
|
||||
[
|
||||
createVariableDeclaration(temp, /*type*/ undefined, /*initializer*/ undefined, node.initializer)
|
||||
],
|
||||
node.initializer,
|
||||
NodeFlags.Let
|
||||
setTextRange(
|
||||
createVariableDeclarationList([
|
||||
setTextRange(createVariableDeclaration(temp), node.initializer)
|
||||
], NodeFlags.Let),
|
||||
node.initializer
|
||||
),
|
||||
expression,
|
||||
block
|
||||
@@ -380,7 +384,7 @@ namespace ts {
|
||||
const trailingStatements = endLexicalEnvironment();
|
||||
if (some(leadingStatements) || some(trailingStatements)) {
|
||||
const block = convertToFunctionBody(body, /*multiLine*/ true);
|
||||
return updateBlock(block, createNodeArray(concatenate(concatenate(leadingStatements, block.statements), trailingStatements), block.statements));
|
||||
return updateBlock(block, setTextRange(createNodeArray(concatenate(concatenate(leadingStatements, block.statements), trailingStatements)), block.statements));
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
@@ -450,15 +450,17 @@ namespace ts {
|
||||
// Currently, we only support generators that were originally async functions.
|
||||
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
node = setOriginalNode(
|
||||
createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
/*asteriskToken*/ undefined,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformGeneratorFunctionBody(node.body),
|
||||
setTextRange(
|
||||
createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
/*asteriskToken*/ undefined,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformGeneratorFunctionBody(node.body)
|
||||
),
|
||||
/*location*/ node
|
||||
),
|
||||
node
|
||||
@@ -498,14 +500,16 @@ namespace ts {
|
||||
// Currently, we only support generators that were originally async functions.
|
||||
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
node = setOriginalNode(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformGeneratorFunctionBody(node.body),
|
||||
setTextRange(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformGeneratorFunctionBody(node.body)
|
||||
),
|
||||
/*location*/ node
|
||||
),
|
||||
node
|
||||
@@ -606,7 +610,7 @@ namespace ts {
|
||||
operationLocations = savedOperationLocations;
|
||||
state = savedState;
|
||||
|
||||
return createBlock(statements, /*location*/ body, body.multiLine);
|
||||
return setTextRange(createBlock(statements, body.multiLine), body);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -739,14 +743,17 @@ namespace ts {
|
||||
|
||||
const operator = node.operatorToken.kind;
|
||||
if (isCompoundAssignment(operator)) {
|
||||
return createBinary(
|
||||
target,
|
||||
SyntaxKind.EqualsToken,
|
||||
createBinary(
|
||||
cacheExpression(target),
|
||||
getOperatorForCompoundAssignment(operator),
|
||||
visitNode(right, visitor, isExpression),
|
||||
node
|
||||
return setTextRange(
|
||||
createAssignment(
|
||||
target,
|
||||
setTextRange(
|
||||
createBinary(
|
||||
cacheExpression(target),
|
||||
getOperatorForCompoundAssignment(operator),
|
||||
visitNode(right, visitor, isExpression)
|
||||
),
|
||||
node
|
||||
)
|
||||
),
|
||||
node
|
||||
);
|
||||
@@ -988,8 +995,11 @@ namespace ts {
|
||||
|
||||
const expressions = reduceLeft(elements, reduceElement, <Expression[]>[], numInitialElements);
|
||||
return hasAssignedTemp
|
||||
? createArrayConcat(temp, [createArrayLiteral(expressions, /*location*/ undefined, multiLine)])
|
||||
: createArrayLiteral(leadingElement ? [leadingElement, ...expressions] : expressions, location, multiLine);
|
||||
? createArrayConcat(temp, [createArrayLiteral(expressions, multiLine)])
|
||||
: setTextRange(
|
||||
createArrayLiteral(leadingElement ? [leadingElement, ...expressions] : expressions, multiLine),
|
||||
location
|
||||
);
|
||||
|
||||
function reduceElement(expressions: Expression[], element: Expression) {
|
||||
if (containsYield(element) && expressions.length > 0) {
|
||||
@@ -998,11 +1008,10 @@ namespace ts {
|
||||
hasAssignedTemp
|
||||
? createArrayConcat(
|
||||
temp,
|
||||
[createArrayLiteral(expressions, /*location*/ undefined, multiLine)]
|
||||
[createArrayLiteral(expressions, multiLine)]
|
||||
)
|
||||
: createArrayLiteral(
|
||||
leadingElement ? [leadingElement, ...expressions] : expressions,
|
||||
/*location*/ undefined,
|
||||
multiLine
|
||||
)
|
||||
);
|
||||
@@ -1043,7 +1052,6 @@ namespace ts {
|
||||
emitAssignment(temp,
|
||||
createObjectLiteral(
|
||||
visitNodes(properties, visitor, isObjectLiteralElementLike, 0, numInitialProperties),
|
||||
/*location*/ undefined,
|
||||
multiLine
|
||||
)
|
||||
);
|
||||
@@ -1139,18 +1147,20 @@ namespace ts {
|
||||
|
||||
const { target, thisArg } = createCallBinding(createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration);
|
||||
return setOriginalNode(
|
||||
createNew(
|
||||
createFunctionApply(
|
||||
cacheExpression(visitNode(target, visitor, isExpression)),
|
||||
thisArg,
|
||||
visitElements(
|
||||
node.arguments,
|
||||
/*leadingElement*/ createVoidZero()
|
||||
)
|
||||
setTextRange(
|
||||
createNew(
|
||||
createFunctionApply(
|
||||
cacheExpression(visitNode(target, visitor, isExpression)),
|
||||
thisArg,
|
||||
visitElements(
|
||||
node.arguments,
|
||||
/*leadingElement*/ createVoidZero()
|
||||
)
|
||||
),
|
||||
/*typeArguments*/ undefined,
|
||||
[]
|
||||
),
|
||||
/*typeArguments*/ undefined,
|
||||
[],
|
||||
/*location*/ node
|
||||
node
|
||||
),
|
||||
node
|
||||
);
|
||||
@@ -1423,9 +1433,11 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
emitStatement(
|
||||
createStatement(
|
||||
visitNode(initializer, visitor, isExpression),
|
||||
/*location*/ initializer
|
||||
setTextRange(
|
||||
createStatement(
|
||||
visitNode(initializer, visitor, isExpression)
|
||||
),
|
||||
initializer
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -1441,9 +1453,11 @@ namespace ts {
|
||||
markLabel(incrementLabel);
|
||||
if (node.incrementor) {
|
||||
emitStatement(
|
||||
createStatement(
|
||||
visitNode(node.incrementor, visitor, isExpression),
|
||||
/*location*/ node.incrementor
|
||||
setTextRange(
|
||||
createStatement(
|
||||
visitNode(node.incrementor, visitor, isExpression)
|
||||
),
|
||||
node.incrementor
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -1909,9 +1923,9 @@ namespace ts {
|
||||
return -1;
|
||||
}
|
||||
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node): Node {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
if (emitContext === EmitContext.Expression) {
|
||||
function onSubstituteNode(hint: EmitHint, node: Node): Node {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (hint === EmitHint.Expression) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
return node;
|
||||
@@ -2417,11 +2431,13 @@ namespace ts {
|
||||
*/
|
||||
function createInlineBreak(label: Label, location?: TextRange): ReturnStatement {
|
||||
Debug.assert(label > 0, `Invalid label: ${label}`);
|
||||
return createReturn(
|
||||
createArrayLiteral([
|
||||
createInstruction(Instruction.Break),
|
||||
createLabel(label)
|
||||
]),
|
||||
return setTextRange(
|
||||
createReturn(
|
||||
createArrayLiteral([
|
||||
createInstruction(Instruction.Break),
|
||||
createLabel(label)
|
||||
])
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
@@ -2433,10 +2449,12 @@ namespace ts {
|
||||
* @param location An optional source map location for the statement.
|
||||
*/
|
||||
function createInlineReturn(expression?: Expression, location?: TextRange): ReturnStatement {
|
||||
return createReturn(
|
||||
createArrayLiteral(expression
|
||||
? [createInstruction(Instruction.Return), expression]
|
||||
: [createInstruction(Instruction.Return)]
|
||||
return setTextRange(
|
||||
createReturn(
|
||||
createArrayLiteral(expression
|
||||
? [createInstruction(Instruction.Return), expression]
|
||||
: [createInstruction(Instruction.Return)]
|
||||
)
|
||||
),
|
||||
location
|
||||
);
|
||||
@@ -2446,7 +2464,14 @@ namespace ts {
|
||||
* Creates an expression that can be used to resume from a Yield operation.
|
||||
*/
|
||||
function createGeneratorResume(location?: TextRange): LeftHandSideExpression {
|
||||
return createCall(createPropertyAccess(state, "sent"), /*typeArguments*/ undefined, [], location);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
createPropertyAccess(state, "sent"),
|
||||
/*typeArguments*/ undefined,
|
||||
[]
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2614,7 +2639,6 @@ namespace ts {
|
||||
/*type*/ undefined,
|
||||
createBlock(
|
||||
buildResult,
|
||||
/*location*/ undefined,
|
||||
/*multiLine*/ buildResult.length > 0
|
||||
)
|
||||
),
|
||||
@@ -2944,7 +2968,7 @@ namespace ts {
|
||||
* @param operationLocation The source map location for the operation.
|
||||
*/
|
||||
function writeAssign(left: Expression, right: Expression, operationLocation: TextRange): void {
|
||||
writeStatement(createStatement(createAssignment(left, right), operationLocation));
|
||||
writeStatement(setTextRange(createStatement(createAssignment(left, right)), operationLocation));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2956,7 +2980,7 @@ namespace ts {
|
||||
function writeThrow(expression: Expression, operationLocation: TextRange): void {
|
||||
lastOperationWasAbrupt = true;
|
||||
lastOperationWasCompletion = true;
|
||||
writeStatement(createThrow(expression, operationLocation));
|
||||
writeStatement(setTextRange(createThrow(expression), operationLocation));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2970,10 +2994,12 @@ namespace ts {
|
||||
lastOperationWasCompletion = true;
|
||||
writeStatement(
|
||||
setEmitFlags(
|
||||
createReturn(
|
||||
createArrayLiteral(expression
|
||||
? [createInstruction(Instruction.Return), expression]
|
||||
: [createInstruction(Instruction.Return)]
|
||||
setTextRange(
|
||||
createReturn(
|
||||
createArrayLiteral(expression
|
||||
? [createInstruction(Instruction.Return), expression]
|
||||
: [createInstruction(Instruction.Return)]
|
||||
)
|
||||
),
|
||||
operationLocation
|
||||
),
|
||||
@@ -2992,11 +3018,13 @@ namespace ts {
|
||||
lastOperationWasAbrupt = true;
|
||||
writeStatement(
|
||||
setEmitFlags(
|
||||
createReturn(
|
||||
createArrayLiteral([
|
||||
createInstruction(Instruction.Break),
|
||||
createLabel(label)
|
||||
]),
|
||||
setTextRange(
|
||||
createReturn(
|
||||
createArrayLiteral([
|
||||
createInstruction(Instruction.Break),
|
||||
createLabel(label)
|
||||
])
|
||||
),
|
||||
operationLocation
|
||||
),
|
||||
EmitFlags.NoTokenSourceMaps
|
||||
@@ -3017,11 +3045,13 @@ namespace ts {
|
||||
createIf(
|
||||
condition,
|
||||
setEmitFlags(
|
||||
createReturn(
|
||||
createArrayLiteral([
|
||||
createInstruction(Instruction.Break),
|
||||
createLabel(label)
|
||||
]),
|
||||
setTextRange(
|
||||
createReturn(
|
||||
createArrayLiteral([
|
||||
createInstruction(Instruction.Break),
|
||||
createLabel(label)
|
||||
])
|
||||
),
|
||||
operationLocation
|
||||
),
|
||||
EmitFlags.NoTokenSourceMaps
|
||||
@@ -3045,11 +3075,13 @@ namespace ts {
|
||||
createIf(
|
||||
createLogicalNot(condition),
|
||||
setEmitFlags(
|
||||
createReturn(
|
||||
createArrayLiteral([
|
||||
createInstruction(Instruction.Break),
|
||||
createLabel(label)
|
||||
]),
|
||||
setTextRange(
|
||||
createReturn(
|
||||
createArrayLiteral([
|
||||
createInstruction(Instruction.Break),
|
||||
createLabel(label)
|
||||
])
|
||||
),
|
||||
operationLocation
|
||||
),
|
||||
EmitFlags.NoTokenSourceMaps
|
||||
@@ -3070,11 +3102,13 @@ namespace ts {
|
||||
lastOperationWasAbrupt = true;
|
||||
writeStatement(
|
||||
setEmitFlags(
|
||||
createReturn(
|
||||
createArrayLiteral(
|
||||
expression
|
||||
? [createInstruction(Instruction.Yield), expression]
|
||||
: [createInstruction(Instruction.Yield)]
|
||||
setTextRange(
|
||||
createReturn(
|
||||
createArrayLiteral(
|
||||
expression
|
||||
? [createInstruction(Instruction.Yield), expression]
|
||||
: [createInstruction(Instruction.Yield)]
|
||||
)
|
||||
),
|
||||
operationLocation
|
||||
),
|
||||
@@ -3093,11 +3127,13 @@ namespace ts {
|
||||
lastOperationWasAbrupt = true;
|
||||
writeStatement(
|
||||
setEmitFlags(
|
||||
createReturn(
|
||||
createArrayLiteral([
|
||||
createInstruction(Instruction.YieldStar),
|
||||
expression
|
||||
]),
|
||||
setTextRange(
|
||||
createReturn(
|
||||
createArrayLiteral([
|
||||
createInstruction(Instruction.YieldStar),
|
||||
expression
|
||||
])
|
||||
),
|
||||
operationLocation
|
||||
),
|
||||
EmitFlags.NoTokenSourceMaps
|
||||
|
||||
@@ -143,15 +143,15 @@ namespace ts {
|
||||
|
||||
function transformJsxAttributeInitializer(node: StringLiteral | JsxExpression) {
|
||||
if (node === undefined) {
|
||||
return createLiteral(true);
|
||||
return createTrue();
|
||||
}
|
||||
else if (node.kind === SyntaxKind.StringLiteral) {
|
||||
const decoded = tryDecodeEntities((<StringLiteral>node).text);
|
||||
return decoded ? createLiteral(decoded, /*location*/ node) : node;
|
||||
return decoded ? setTextRange(createLiteral(decoded), node) : node;
|
||||
}
|
||||
else if (node.kind === SyntaxKind.JsxExpression) {
|
||||
if (node.expression === undefined) {
|
||||
return createLiteral(true);
|
||||
return createTrue();
|
||||
}
|
||||
return visitJsxExpression(<JsxExpression>node);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace ts {
|
||||
addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset));
|
||||
return updateSourceFileNode(
|
||||
node,
|
||||
createNodeArray(statements, node.statements));
|
||||
setTextRange(createNodeArray(statements), node.statements));
|
||||
}
|
||||
else {
|
||||
return visitEachChild(node, visitor, context);
|
||||
@@ -71,18 +71,18 @@ namespace ts {
|
||||
/**
|
||||
* Hook for node emit.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emit A callback used to emit the node in the printer.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
if (isSourceFile(node)) {
|
||||
currentSourceFile = node;
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
currentSourceFile = undefined;
|
||||
}
|
||||
else {
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,12 +93,12 @@ namespace ts {
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
if (isIdentifier(node) && emitContext === EmitContext.Expression) {
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (isIdentifier(node) && hint === EmitHint.Expression) {
|
||||
return substituteExpressionIdentifier(node);
|
||||
}
|
||||
return node;
|
||||
|
||||
@@ -83,16 +83,20 @@ namespace ts {
|
||||
|
||||
const statements: Statement[] = [];
|
||||
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
|
||||
|
||||
if (!currentModuleInfo.exportEquals) {
|
||||
append(statements, createUnderscoreUnderscoreESModule());
|
||||
}
|
||||
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement, /*optional*/ true));
|
||||
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false);
|
||||
|
||||
const updated = updateSourceFileNode(node, createNodeArray(statements, node.statements));
|
||||
const updated = updateSourceFileNode(node, setTextRange(createNodeArray(statements), node.statements));
|
||||
if (currentModuleInfo.hasExportStarsToExportValues) {
|
||||
addEmitHelper(updated, exportStarHelper);
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
@@ -131,47 +135,49 @@ namespace ts {
|
||||
// Create an updated SourceFile:
|
||||
//
|
||||
// define(moduleName?, ["module1", "module2"], function ...
|
||||
return updateSourceFileNode(node, createNodeArray(
|
||||
[
|
||||
createStatement(
|
||||
createCall(
|
||||
define,
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
// Add the module name (if provided).
|
||||
...(moduleName ? [moduleName] : []),
|
||||
return updateSourceFileNode(node,
|
||||
setTextRange(
|
||||
createNodeArray([
|
||||
createStatement(
|
||||
createCall(
|
||||
define,
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
// Add the module name (if provided).
|
||||
...(moduleName ? [moduleName] : []),
|
||||
|
||||
// Add the dependency array argument:
|
||||
//
|
||||
// ["require", "exports", module1", "module2", ...]
|
||||
createArrayLiteral([
|
||||
createLiteral("require"),
|
||||
createLiteral("exports"),
|
||||
...aliasedModuleNames,
|
||||
...unaliasedModuleNames
|
||||
]),
|
||||
// Add the dependency array argument:
|
||||
//
|
||||
// ["require", "exports", module1", "module2", ...]
|
||||
createArrayLiteral([
|
||||
createLiteral("require"),
|
||||
createLiteral("exports"),
|
||||
...aliasedModuleNames,
|
||||
...unaliasedModuleNames
|
||||
]),
|
||||
|
||||
// Add the module body function argument:
|
||||
//
|
||||
// function (require, exports, module1, module2) ...
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
[
|
||||
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"),
|
||||
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports"),
|
||||
...importAliasNames
|
||||
],
|
||||
/*type*/ undefined,
|
||||
transformAsynchronousModuleBody(node)
|
||||
)
|
||||
]
|
||||
// Add the module body function argument:
|
||||
//
|
||||
// function (require, exports, module1, module2) ...
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
[
|
||||
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"),
|
||||
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports"),
|
||||
...importAliasNames
|
||||
],
|
||||
/*type*/ undefined,
|
||||
transformAsynchronousModuleBody(node)
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
)
|
||||
],
|
||||
/*location*/ node.statements)
|
||||
]),
|
||||
/*location*/ node.statements
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -189,74 +195,76 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "factory")],
|
||||
/*type*/ undefined,
|
||||
createBlock(
|
||||
[
|
||||
createIf(
|
||||
createLogicalAnd(
|
||||
createTypeCheck(createIdentifier("module"), "object"),
|
||||
createTypeCheck(createPropertyAccess(createIdentifier("module"), "exports"), "object")
|
||||
),
|
||||
createBlock([
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
[
|
||||
createVariableDeclaration(
|
||||
"v",
|
||||
/*type*/ undefined,
|
||||
setTextRange(
|
||||
createBlock(
|
||||
[
|
||||
createIf(
|
||||
createLogicalAnd(
|
||||
createTypeCheck(createIdentifier("module"), "object"),
|
||||
createTypeCheck(createPropertyAccess(createIdentifier("module"), "exports"), "object")
|
||||
),
|
||||
createBlock([
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
[
|
||||
createVariableDeclaration(
|
||||
"v",
|
||||
/*type*/ undefined,
|
||||
createCall(
|
||||
createIdentifier("factory"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createIdentifier("require"),
|
||||
createIdentifier("exports")
|
||||
]
|
||||
)
|
||||
)
|
||||
]
|
||||
),
|
||||
setEmitFlags(
|
||||
createIf(
|
||||
createStrictInequality(
|
||||
createIdentifier("v"),
|
||||
createIdentifier("undefined")
|
||||
),
|
||||
createStatement(
|
||||
createAssignment(
|
||||
createPropertyAccess(createIdentifier("module"), "exports"),
|
||||
createIdentifier("v")
|
||||
)
|
||||
)
|
||||
),
|
||||
EmitFlags.SingleLine
|
||||
)
|
||||
]),
|
||||
createIf(
|
||||
createLogicalAnd(
|
||||
createTypeCheck(createIdentifier("define"), "function"),
|
||||
createPropertyAccess(createIdentifier("define"), "amd")
|
||||
),
|
||||
createBlock([
|
||||
createStatement(
|
||||
createCall(
|
||||
createIdentifier("factory"),
|
||||
createIdentifier("define"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createIdentifier("require"),
|
||||
createIdentifier("exports")
|
||||
createArrayLiteral([
|
||||
createLiteral("require"),
|
||||
createLiteral("exports"),
|
||||
...aliasedModuleNames,
|
||||
...unaliasedModuleNames
|
||||
]),
|
||||
createIdentifier("factory")
|
||||
]
|
||||
)
|
||||
)
|
||||
]
|
||||
),
|
||||
setEmitFlags(
|
||||
createIf(
|
||||
createStrictInequality(
|
||||
createIdentifier("v"),
|
||||
createIdentifier("undefined")
|
||||
),
|
||||
createStatement(
|
||||
createAssignment(
|
||||
createPropertyAccess(createIdentifier("module"), "exports"),
|
||||
createIdentifier("v")
|
||||
)
|
||||
)
|
||||
),
|
||||
EmitFlags.SingleLine
|
||||
])
|
||||
)
|
||||
]),
|
||||
createIf(
|
||||
createLogicalAnd(
|
||||
createTypeCheck(createIdentifier("define"), "function"),
|
||||
createPropertyAccess(createIdentifier("define"), "amd")
|
||||
),
|
||||
createBlock([
|
||||
createStatement(
|
||||
createCall(
|
||||
createIdentifier("define"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createArrayLiteral([
|
||||
createLiteral("require"),
|
||||
createLiteral("exports"),
|
||||
...aliasedModuleNames,
|
||||
...unaliasedModuleNames
|
||||
]),
|
||||
createIdentifier("factory")
|
||||
]
|
||||
)
|
||||
)
|
||||
])
|
||||
)
|
||||
)
|
||||
],
|
||||
/*location*/ undefined,
|
||||
/*multiLine*/ true
|
||||
],
|
||||
/*multiLine*/ true
|
||||
),
|
||||
/*location*/ undefined
|
||||
)
|
||||
);
|
||||
|
||||
@@ -274,8 +282,8 @@ namespace ts {
|
||||
|
||||
return updateSourceFileNode(
|
||||
node,
|
||||
createNodeArray(
|
||||
[
|
||||
setTextRange(
|
||||
createNodeArray([
|
||||
createStatement(
|
||||
createCall(
|
||||
umdHeader,
|
||||
@@ -300,7 +308,7 @@ namespace ts {
|
||||
]
|
||||
)
|
||||
)
|
||||
],
|
||||
]),
|
||||
/*location*/ node.statements
|
||||
)
|
||||
);
|
||||
@@ -367,6 +375,10 @@ namespace ts {
|
||||
const statements: Statement[] = [];
|
||||
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
|
||||
|
||||
if (!currentModuleInfo.exportEquals) {
|
||||
append(statements, createUnderscoreUnderscoreESModule());
|
||||
}
|
||||
|
||||
// Visit each statement of the module body.
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement, /*optional*/ true));
|
||||
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
|
||||
@@ -378,7 +390,7 @@ namespace ts {
|
||||
// Append the 'export =' statement if provided.
|
||||
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ true);
|
||||
|
||||
const body = createBlock(statements, /*location*/ undefined, /*multiLine*/ true);
|
||||
const body = createBlock(statements, /*multiLine*/ true);
|
||||
if (currentModuleInfo.hasExportStarsToExportValues) {
|
||||
// If we have any `export * from ...` declarations
|
||||
// we need to inform the emitter to add the __export helper.
|
||||
@@ -399,11 +411,8 @@ namespace ts {
|
||||
function addExportEqualsIfNeeded(statements: Statement[], emitAsReturn: boolean) {
|
||||
if (currentModuleInfo.exportEquals) {
|
||||
if (emitAsReturn) {
|
||||
const statement = createReturn(
|
||||
currentModuleInfo.exportEquals.expression,
|
||||
/*location*/ currentModuleInfo.exportEquals
|
||||
);
|
||||
|
||||
const statement = createReturn(currentModuleInfo.exportEquals.expression);
|
||||
setTextRange(statement, currentModuleInfo.exportEquals);
|
||||
setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments);
|
||||
statements.push(statement);
|
||||
}
|
||||
@@ -415,10 +424,10 @@ namespace ts {
|
||||
"exports"
|
||||
),
|
||||
currentModuleInfo.exportEquals.expression
|
||||
),
|
||||
/*location*/ currentModuleInfo.exportEquals
|
||||
)
|
||||
);
|
||||
|
||||
setTextRange(statement, currentModuleInfo.exportEquals);
|
||||
setEmitFlags(statement, EmitFlags.NoComments);
|
||||
statements.push(statement);
|
||||
}
|
||||
@@ -481,7 +490,7 @@ namespace ts {
|
||||
if (moduleKind !== ModuleKind.AMD) {
|
||||
if (!node.importClause) {
|
||||
// import "mod";
|
||||
return createStatement(createRequireCall(node), /*location*/ node);
|
||||
return setTextRange(createStatement(createRequireCall(node)), node);
|
||||
}
|
||||
else {
|
||||
const variables: VariableDeclaration[] = [];
|
||||
@@ -520,12 +529,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
statements = append(statements,
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(
|
||||
variables,
|
||||
/*location*/ undefined,
|
||||
languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None
|
||||
setTextRange(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(
|
||||
variables,
|
||||
languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None
|
||||
)
|
||||
),
|
||||
/*location*/ node
|
||||
)
|
||||
@@ -539,14 +549,15 @@ namespace ts {
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(
|
||||
[
|
||||
createVariableDeclaration(
|
||||
getSynthesizedClone(namespaceDeclaration.name),
|
||||
/*type*/ undefined,
|
||||
getGeneratedNameForNode(node),
|
||||
setTextRange(
|
||||
createVariableDeclaration(
|
||||
getSynthesizedClone(namespaceDeclaration.name),
|
||||
/*type*/ undefined,
|
||||
getGeneratedNameForNode(node)
|
||||
),
|
||||
/*location*/ node
|
||||
)
|
||||
],
|
||||
/*location*/ undefined,
|
||||
languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None
|
||||
)
|
||||
)
|
||||
@@ -592,31 +603,34 @@ namespace ts {
|
||||
if (moduleKind !== ModuleKind.AMD) {
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
statements = append(statements,
|
||||
createStatement(
|
||||
createExportExpression(
|
||||
node.name,
|
||||
createRequireCall(node)
|
||||
setTextRange(
|
||||
createStatement(
|
||||
createExportExpression(
|
||||
node.name,
|
||||
createRequireCall(node)
|
||||
)
|
||||
),
|
||||
/*location*/ node
|
||||
node
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
statements = append(statements,
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(
|
||||
[
|
||||
createVariableDeclaration(
|
||||
getSynthesizedClone(node.name),
|
||||
/*type*/ undefined,
|
||||
createRequireCall(node)
|
||||
)
|
||||
],
|
||||
/*location*/ undefined,
|
||||
/*flags*/ languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None
|
||||
setTextRange(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(
|
||||
[
|
||||
createVariableDeclaration(
|
||||
getSynthesizedClone(node.name),
|
||||
/*type*/ undefined,
|
||||
createRequireCall(node)
|
||||
)
|
||||
],
|
||||
/*flags*/ languageVersion >= ScriptTarget.ES2015 ? NodeFlags.Const : NodeFlags.None
|
||||
)
|
||||
),
|
||||
/*location*/ node
|
||||
node
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -624,9 +638,11 @@ namespace ts {
|
||||
else {
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
statements = append(statements,
|
||||
createStatement(
|
||||
createExportExpression(getExportName(node), getLocalName(node)),
|
||||
/*location*/ node
|
||||
setTextRange(
|
||||
createStatement(
|
||||
createExportExpression(getExportName(node), getLocalName(node))
|
||||
),
|
||||
node
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -657,20 +673,23 @@ namespace ts {
|
||||
}
|
||||
|
||||
const generatedName = getGeneratedNameForNode(node);
|
||||
|
||||
if (node.exportClause) {
|
||||
const statements: Statement[] = [];
|
||||
// export { x, y } from "mod";
|
||||
if (moduleKind !== ModuleKind.AMD) {
|
||||
statements.push(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
generatedName,
|
||||
/*type*/ undefined,
|
||||
createRequireCall(node)
|
||||
)
|
||||
]),
|
||||
setTextRange(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
generatedName,
|
||||
/*type*/ undefined,
|
||||
createRequireCall(node)
|
||||
)
|
||||
])
|
||||
),
|
||||
/*location*/ node
|
||||
)
|
||||
);
|
||||
@@ -681,9 +700,11 @@ namespace ts {
|
||||
specifier.propertyName || specifier.name
|
||||
);
|
||||
statements.push(
|
||||
createStatement(
|
||||
createExportExpression(getExportName(specifier), exportedValue),
|
||||
/*location*/ specifier
|
||||
setTextRange(
|
||||
createStatement(
|
||||
createExportExpression(getExportName(specifier), exportedValue)
|
||||
),
|
||||
specifier
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -692,17 +713,19 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
// export * from "mod";
|
||||
return createStatement(
|
||||
createCall(
|
||||
createIdentifier("__export"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
moduleKind !== ModuleKind.AMD
|
||||
? createRequireCall(node)
|
||||
: generatedName
|
||||
]
|
||||
return setTextRange(
|
||||
createStatement(
|
||||
createCall(
|
||||
createIdentifier("__export"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
moduleKind !== ModuleKind.AMD
|
||||
? createRequireCall(node)
|
||||
: generatedName
|
||||
]
|
||||
)
|
||||
),
|
||||
/*location*/ node
|
||||
node
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -741,15 +764,17 @@ namespace ts {
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
statements = append(statements,
|
||||
setOriginalNode(
|
||||
createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
node.asteriskToken,
|
||||
getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
|
||||
/*typeParameters*/ undefined,
|
||||
node.parameters,
|
||||
/*type*/ undefined,
|
||||
node.body,
|
||||
setTextRange(
|
||||
createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
node.asteriskToken,
|
||||
getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
|
||||
/*typeParameters*/ undefined,
|
||||
node.parameters,
|
||||
/*type*/ undefined,
|
||||
node.body
|
||||
),
|
||||
/*location*/ node
|
||||
),
|
||||
/*original*/ node
|
||||
@@ -782,16 +807,18 @@ namespace ts {
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
statements = append(statements,
|
||||
setOriginalNode(
|
||||
createClassDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
|
||||
/*typeParameters*/ undefined,
|
||||
node.heritageClauses,
|
||||
node.members,
|
||||
/*location*/ node
|
||||
setTextRange(
|
||||
createClassDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
|
||||
/*typeParameters*/ undefined,
|
||||
node.heritageClauses,
|
||||
node.members
|
||||
),
|
||||
node
|
||||
),
|
||||
/*original*/ node
|
||||
node
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -820,6 +847,7 @@ namespace ts {
|
||||
let statements: Statement[];
|
||||
let variables: VariableDeclaration[];
|
||||
let expressions: Expression[];
|
||||
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
let modifiers: NodeArray<Modifier>;
|
||||
|
||||
@@ -843,7 +871,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (expressions) {
|
||||
statements = append(statements, createStatement(inlineExpressions(expressions), /*location*/ node));
|
||||
statements = append(statements, setTextRange(createStatement(inlineExpressions(expressions)), node));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -880,9 +908,11 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
return createAssignment(
|
||||
createPropertyAccess(
|
||||
createIdentifier("exports"),
|
||||
node.name,
|
||||
setTextRange(
|
||||
createPropertyAccess(
|
||||
createIdentifier("exports"),
|
||||
node.name
|
||||
),
|
||||
/*location*/ node.name
|
||||
),
|
||||
node.initializer
|
||||
@@ -1107,43 +1137,39 @@ namespace ts {
|
||||
* @param allowComments Whether to allow comments on the export.
|
||||
*/
|
||||
function appendExportStatement(statements: Statement[] | undefined, exportName: Identifier, expression: Expression, location?: TextRange, allowComments?: boolean): Statement[] | undefined {
|
||||
if (exportName.text === "default") {
|
||||
const sourceFile = getOriginalNode(currentSourceFile, isSourceFile);
|
||||
if (sourceFile && !sourceFile.symbol.exports.get("___esModule")) {
|
||||
if (languageVersion === ScriptTarget.ES3) {
|
||||
statements = append(statements,
|
||||
createStatement(
|
||||
createExportExpression(
|
||||
createIdentifier("__esModule"),
|
||||
createLiteral(true)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
statements = append(statements,
|
||||
createStatement(
|
||||
createCall(
|
||||
createPropertyAccess(createIdentifier("Object"), "defineProperty"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createIdentifier("exports"),
|
||||
createLiteral("__esModule"),
|
||||
createObjectLiteral([
|
||||
createPropertyAssignment("value", createLiteral(true))
|
||||
])
|
||||
]
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
statements = append(statements, createExportStatement(exportName, expression, location, allowComments));
|
||||
return statements;
|
||||
}
|
||||
|
||||
function createUnderscoreUnderscoreESModule() {
|
||||
let statement: Statement;
|
||||
if (languageVersion === ScriptTarget.ES3) {
|
||||
statement = createStatement(
|
||||
createExportExpression(
|
||||
createIdentifier("__esModule"),
|
||||
createLiteral(true)
|
||||
)
|
||||
)
|
||||
}
|
||||
else {
|
||||
statement = createStatement(
|
||||
createCall(
|
||||
createPropertyAccess(createIdentifier("Object"), "defineProperty"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createIdentifier("exports"),
|
||||
createLiteral("__esModule"),
|
||||
createObjectLiteral([
|
||||
createPropertyAssignment("value", createLiteral(true))
|
||||
])
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
setEmitFlags(statement, EmitFlags.CustomPrologue);
|
||||
return statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a call to the current file's export function to export a value.
|
||||
*
|
||||
@@ -1153,7 +1179,7 @@ namespace ts {
|
||||
* @param allowComments An optional value indicating whether to emit comments for the statement.
|
||||
*/
|
||||
function createExportStatement(name: Identifier, value: Expression, location?: TextRange, allowComments?: boolean) {
|
||||
const statement = createStatement(createExportExpression(name, value), location);
|
||||
const statement = setTextRange(createStatement(createExportExpression(name, value)), location);
|
||||
startOnNewLine(statement);
|
||||
if (!allowComments) {
|
||||
setEmitFlags(statement, EmitFlags.NoComments);
|
||||
@@ -1170,12 +1196,14 @@ namespace ts {
|
||||
* @param location The location to use for source maps and comments for the export.
|
||||
*/
|
||||
function createExportExpression(name: Identifier, value: Expression, location?: TextRange) {
|
||||
return createAssignment(
|
||||
createPropertyAccess(
|
||||
createIdentifier("exports"),
|
||||
getSynthesizedClone(name)
|
||||
return setTextRange(
|
||||
createAssignment(
|
||||
createPropertyAccess(
|
||||
createIdentifier("exports"),
|
||||
getSynthesizedClone(name)
|
||||
),
|
||||
value
|
||||
),
|
||||
value,
|
||||
location
|
||||
);
|
||||
}
|
||||
@@ -1207,24 +1235,24 @@ namespace ts {
|
||||
/**
|
||||
* Hook for node emit notifications.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emit A callback used to emit the node in the printer.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
if (node.kind === SyntaxKind.SourceFile) {
|
||||
currentSourceFile = <SourceFile>node;
|
||||
currentModuleInfo = moduleInfoMap[getOriginalNodeId(currentSourceFile)];
|
||||
noSubstitution = [];
|
||||
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
|
||||
currentSourceFile = undefined;
|
||||
currentModuleInfo = undefined;
|
||||
noSubstitution = undefined;
|
||||
}
|
||||
else {
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1235,16 +1263,16 @@ namespace ts {
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (node.id && noSubstitution[node.id]) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (emitContext === EmitContext.Expression) {
|
||||
if (hint === EmitHint.Expression) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
else if (isShorthandPropertyAssignment(node)) {
|
||||
@@ -1268,9 +1296,9 @@ namespace ts {
|
||||
// destructuring assignment
|
||||
if (node.objectAssignmentInitializer) {
|
||||
const initializer = createAssignment(exportedOrImportedName, node.objectAssignmentInitializer);
|
||||
return createPropertyAssignment(name, initializer, /*location*/ node);
|
||||
return setTextRange(createPropertyAssignment(name, initializer), node);
|
||||
}
|
||||
return createPropertyAssignment(name, exportedOrImportedName, /*location*/ node);
|
||||
return setTextRange(createPropertyAssignment(name, exportedOrImportedName), node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -1312,9 +1340,11 @@ namespace ts {
|
||||
if (!isGeneratedIdentifier(node) && !isLocalName(node)) {
|
||||
const exportContainer = resolver.getReferencedExportContainer(node, isExportName(node));
|
||||
if (exportContainer && exportContainer.kind === SyntaxKind.SourceFile) {
|
||||
return createPropertyAccess(
|
||||
createIdentifier("exports"),
|
||||
getSynthesizedClone(node),
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
createIdentifier("exports"),
|
||||
getSynthesizedClone(node)
|
||||
),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
@@ -1322,17 +1352,21 @@ namespace ts {
|
||||
const importDeclaration = resolver.getReferencedImportDeclaration(node);
|
||||
if (importDeclaration) {
|
||||
if (isImportClause(importDeclaration)) {
|
||||
return createPropertyAccess(
|
||||
getGeneratedNameForNode(importDeclaration.parent),
|
||||
createIdentifier("default"),
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
getGeneratedNameForNode(importDeclaration.parent),
|
||||
createIdentifier("default")
|
||||
),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
else if (isImportSpecifier(importDeclaration)) {
|
||||
const name = importDeclaration.propertyName || importDeclaration.name;
|
||||
return createPropertyAccess(
|
||||
getGeneratedNameForNode(importDeclaration.parent.parent.parent),
|
||||
getSynthesizedClone(name),
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
getGeneratedNameForNode(importDeclaration.parent.parent.parent),
|
||||
getSynthesizedClone(name)
|
||||
),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
@@ -1400,10 +1434,12 @@ namespace ts {
|
||||
const exportedNames = getExports(node.operand);
|
||||
if (exportedNames) {
|
||||
let expression: Expression = node.kind === SyntaxKind.PostfixUnaryExpression
|
||||
? createBinary(
|
||||
node.operand,
|
||||
createToken(node.operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken),
|
||||
createLiteral(1),
|
||||
? setTextRange(
|
||||
createBinary(
|
||||
node.operand,
|
||||
createToken(node.operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken),
|
||||
createLiteral(1)
|
||||
),
|
||||
/*location*/ node)
|
||||
: node;
|
||||
for (const exportName of exportedNames) {
|
||||
|
||||
@@ -105,17 +105,20 @@ namespace ts {
|
||||
const updated = setEmitFlags(
|
||||
updateSourceFileNode(
|
||||
node,
|
||||
createNodeArray([
|
||||
createStatement(
|
||||
createCall(
|
||||
createPropertyAccess(createIdentifier("System"), "register"),
|
||||
/*typeArguments*/ undefined,
|
||||
moduleName
|
||||
? [moduleName, dependencies, moduleBodyFunction]
|
||||
: [dependencies, moduleBodyFunction]
|
||||
setTextRange(
|
||||
createNodeArray([
|
||||
createStatement(
|
||||
createCall(
|
||||
createPropertyAccess(createIdentifier("System"), "register"),
|
||||
/*typeArguments*/ undefined,
|
||||
moduleName
|
||||
? [moduleName, dependencies, moduleBodyFunction]
|
||||
: [dependencies, moduleBodyFunction]
|
||||
)
|
||||
)
|
||||
)
|
||||
], node.statements)
|
||||
]),
|
||||
node.statements
|
||||
)
|
||||
), EmitFlags.NoTrailingComments);
|
||||
|
||||
if (!(compilerOptions.outFile || compilerOptions.out)) {
|
||||
@@ -260,35 +263,26 @@ namespace ts {
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
|
||||
const exportStarFunction = addExportStarIfNeeded(statements);
|
||||
statements.push(
|
||||
createReturn(
|
||||
setMultiLine(
|
||||
createObjectLiteral([
|
||||
createPropertyAssignment("setters",
|
||||
createSettersArray(exportStarFunction, dependencyGroups)
|
||||
),
|
||||
createPropertyAssignment("execute",
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
/*parameters*/ [],
|
||||
/*type*/ undefined,
|
||||
createBlock(
|
||||
executeStatements,
|
||||
/*location*/ undefined,
|
||||
/*multiLine*/ true
|
||||
)
|
||||
)
|
||||
)
|
||||
]),
|
||||
/*multiLine*/ true
|
||||
const moduleObject = createObjectLiteral([
|
||||
createPropertyAssignment("setters",
|
||||
createSettersArray(exportStarFunction, dependencyGroups)
|
||||
),
|
||||
createPropertyAssignment("execute",
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
/*parameters*/ [],
|
||||
/*type*/ undefined,
|
||||
createBlock(executeStatements, /*multiLine*/ true)
|
||||
)
|
||||
)
|
||||
);
|
||||
]);
|
||||
|
||||
return createBlock(statements, /*location*/ undefined, /*multiLine*/ true);
|
||||
moduleObject.multiLine = true;
|
||||
statements.push(createReturn(moduleObject));
|
||||
return createBlock(statements, /*multiLine*/ true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,7 +331,7 @@ namespace ts {
|
||||
exportedNames.push(
|
||||
createPropertyAssignment(
|
||||
createLiteral(exportedLocalName),
|
||||
createLiteral(true)
|
||||
createTrue()
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -359,7 +353,7 @@ namespace ts {
|
||||
exportedNames.push(
|
||||
createPropertyAssignment(
|
||||
createLiteral((element.name || element.propertyName).text),
|
||||
createLiteral(true)
|
||||
createTrue()
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -373,7 +367,7 @@ namespace ts {
|
||||
createVariableDeclaration(
|
||||
exportedNamesStorageRef,
|
||||
/*type*/ undefined,
|
||||
createObjectLiteral(exportedNames, /*location*/ undefined, /*multiline*/ true)
|
||||
createObjectLiteral(exportedNames, /*multiline*/ true)
|
||||
)
|
||||
])
|
||||
)
|
||||
@@ -456,9 +450,7 @@ namespace ts {
|
||||
[exports]
|
||||
)
|
||||
)
|
||||
],
|
||||
/*location*/ undefined,
|
||||
/*multiline*/ true)
|
||||
], /*multiline*/ true)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -525,7 +517,7 @@ namespace ts {
|
||||
createCall(
|
||||
exportFunction,
|
||||
/*typeArguments*/ undefined,
|
||||
[createObjectLiteral(properties, /*location*/ undefined, /*multiline*/ true)]
|
||||
[createObjectLiteral(properties, /*multiline*/ true)]
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -558,12 +550,12 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)],
|
||||
/*type*/ undefined,
|
||||
createBlock(statements, /*location*/ undefined, /*multiLine*/ true)
|
||||
createBlock(statements, /*multiLine*/ true)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return createArrayLiteral(setters, /*location*/ undefined, /*multiLine*/ true);
|
||||
return createArrayLiteral(setters, /*multiLine*/ true);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -713,19 +705,23 @@ namespace ts {
|
||||
|
||||
// Rewrite the class declaration into an assignment of a class expression.
|
||||
statements = append(statements,
|
||||
createStatement(
|
||||
createAssignment(
|
||||
name,
|
||||
createClassExpression(
|
||||
/*modifiers*/ undefined,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.heritageClauses, destructuringVisitor, isHeritageClause),
|
||||
visitNodes(node.members, destructuringVisitor, isClassElement),
|
||||
/*location*/ node
|
||||
setTextRange(
|
||||
createStatement(
|
||||
createAssignment(
|
||||
name,
|
||||
setTextRange(
|
||||
createClassExpression(
|
||||
/*modifiers*/ undefined,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.heritageClauses, destructuringVisitor, isHeritageClause),
|
||||
visitNodes(node.members, destructuringVisitor, isClassElement)
|
||||
),
|
||||
node
|
||||
)
|
||||
)
|
||||
),
|
||||
/*location*/ node
|
||||
node
|
||||
)
|
||||
);
|
||||
|
||||
@@ -766,7 +762,7 @@ namespace ts {
|
||||
|
||||
let statements: Statement[];
|
||||
if (expressions) {
|
||||
statements = append(statements, createStatement(inlineExpressions(expressions), /*location*/ node));
|
||||
statements = append(statements, setTextRange(createStatement(inlineExpressions(expressions)), node));
|
||||
}
|
||||
|
||||
if (isMarkedDeclaration) {
|
||||
@@ -864,8 +860,8 @@ namespace ts {
|
||||
function createVariableAssignment(name: Identifier, value: Expression, location: TextRange, isExportedDeclaration: boolean) {
|
||||
hoistVariableDeclaration(getSynthesizedClone(name));
|
||||
return isExportedDeclaration
|
||||
? createExportExpression(name, preventSubstitution(createAssignment(name, value, location)))
|
||||
: preventSubstitution(createAssignment(name, value, location));
|
||||
? createExportExpression(name, preventSubstitution(setTextRange(createAssignment(name, value), location)))
|
||||
: preventSubstitution(setTextRange(createAssignment(name, value), location));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1548,11 +1544,11 @@ namespace ts {
|
||||
/**
|
||||
* Hook for node emit notifications.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emit A callback used to emit the node in the printer.
|
||||
* @param emitCallback A callback used to emit the node in the printer.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
if (node.kind === SyntaxKind.SourceFile) {
|
||||
const id = getOriginalNodeId(node);
|
||||
currentSourceFile = <SourceFile>node;
|
||||
@@ -1564,7 +1560,7 @@ namespace ts {
|
||||
delete noSubstitutionMap[id];
|
||||
}
|
||||
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
|
||||
currentSourceFile = undefined;
|
||||
moduleInfo = undefined;
|
||||
@@ -1572,7 +1568,7 @@ namespace ts {
|
||||
noSubstitution = undefined;
|
||||
}
|
||||
else {
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1583,16 +1579,16 @@ namespace ts {
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (isSubstitutionPrevented(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (emitContext === EmitContext.Expression) {
|
||||
if (hint === EmitHint.Expression) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
|
||||
@@ -1642,16 +1638,20 @@ namespace ts {
|
||||
const importDeclaration = resolver.getReferencedImportDeclaration(node);
|
||||
if (importDeclaration) {
|
||||
if (isImportClause(importDeclaration)) {
|
||||
return createPropertyAccess(
|
||||
getGeneratedNameForNode(importDeclaration.parent),
|
||||
createIdentifier("default"),
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
getGeneratedNameForNode(importDeclaration.parent),
|
||||
createIdentifier("default")
|
||||
),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
else if (isImportSpecifier(importDeclaration)) {
|
||||
return createPropertyAccess(
|
||||
getGeneratedNameForNode(importDeclaration.parent.parent.parent),
|
||||
getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name),
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
getGeneratedNameForNode(importDeclaration.parent.parent.parent),
|
||||
getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name)
|
||||
),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
@@ -1718,10 +1718,13 @@ namespace ts {
|
||||
const exportedNames = getExports(node.operand);
|
||||
if (exportedNames) {
|
||||
let expression: Expression = node.kind === SyntaxKind.PostfixUnaryExpression
|
||||
? createPrefix(
|
||||
node.operator,
|
||||
node.operand,
|
||||
/*location*/ node)
|
||||
? setTextRange(
|
||||
createPrefix(
|
||||
node.operator,
|
||||
node.operand
|
||||
),
|
||||
node
|
||||
)
|
||||
: node;
|
||||
|
||||
for (const exportName of exportedNames) {
|
||||
|
||||
+156
-117
@@ -588,17 +588,17 @@ namespace ts {
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.heritageClauses, visitor, isHeritageClause),
|
||||
transformClassMembers(node, hasExtendsClause),
|
||||
node);
|
||||
|
||||
let emitFlags = getEmitFlags(node);
|
||||
transformClassMembers(node, hasExtendsClause)
|
||||
);
|
||||
|
||||
// To better align with the old emitter, we should not emit a trailing source map
|
||||
// entry if the class has static properties.
|
||||
let emitFlags = getEmitFlags(node);
|
||||
if (hasStaticProperties) {
|
||||
emitFlags |= EmitFlags.NoTrailingSourceMap;
|
||||
}
|
||||
|
||||
setTextRange(classDeclaration, node);
|
||||
setOriginalNode(classDeclaration, node);
|
||||
setEmitFlags(classDeclaration, emitFlags);
|
||||
return classDeclaration;
|
||||
@@ -709,13 +709,24 @@ namespace ts {
|
||||
// }
|
||||
const heritageClauses = visitNodes(node.heritageClauses, visitor, isHeritageClause);
|
||||
const members = transformClassMembers(node, hasExtendsClause);
|
||||
const classExpression = createClassExpression(/*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members, location);
|
||||
const classExpression = createClassExpression(/*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members);
|
||||
setOriginalNode(classExpression, node);
|
||||
setTextRange(classExpression, location);
|
||||
|
||||
// let ${name} = ${classExpression} where name is either declaredName if the class doesn't contain self-reference
|
||||
// or decoratedClassAlias if the class contain self-reference.
|
||||
const statement = createLetStatement(declName, classAlias ? createAssignment(classAlias, classExpression) : classExpression, location);
|
||||
const statement = createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
declName,
|
||||
/*type*/ undefined,
|
||||
classAlias ? createAssignment(classAlias, classExpression) : classExpression
|
||||
)
|
||||
], NodeFlags.Let)
|
||||
);
|
||||
setOriginalNode(statement, node);
|
||||
setTextRange(statement, location);
|
||||
setCommentRange(statement, node);
|
||||
return statement;
|
||||
}
|
||||
@@ -734,18 +745,17 @@ namespace ts {
|
||||
const heritageClauses = visitNodes(node.heritageClauses, visitor, isHeritageClause);
|
||||
const members = transformClassMembers(node, some(heritageClauses, c => c.token === SyntaxKind.ExtendsKeyword));
|
||||
|
||||
const classExpression = setOriginalNode(
|
||||
createClassExpression(
|
||||
/*modifiers*/ undefined,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
heritageClauses,
|
||||
members,
|
||||
/*location*/ node
|
||||
),
|
||||
node
|
||||
const classExpression = createClassExpression(
|
||||
/*modifiers*/ undefined,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
heritageClauses,
|
||||
members
|
||||
);
|
||||
|
||||
setOriginalNode(classExpression, node);
|
||||
setTextRange(classExpression, node);
|
||||
|
||||
if (staticProperties.length > 0) {
|
||||
const expressions: Expression[] = [];
|
||||
const temp = createTempVariable(hoistVariableDeclaration);
|
||||
@@ -781,7 +791,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
addRange(members, visitNodes(node.members, classElementVisitor, isClassElement));
|
||||
return createNodeArray(members, /*location*/ node.members);
|
||||
return setTextRange(createNodeArray(members), /*location*/ node.members);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -812,12 +822,14 @@ namespace ts {
|
||||
// }
|
||||
return startOnNewLine(
|
||||
setOriginalNode(
|
||||
createConstructor(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
parameters,
|
||||
body,
|
||||
/*location*/ constructor || node
|
||||
setTextRange(
|
||||
createConstructor(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
parameters,
|
||||
body
|
||||
),
|
||||
constructor || node
|
||||
),
|
||||
constructor
|
||||
)
|
||||
@@ -919,13 +931,15 @@ namespace ts {
|
||||
|
||||
// End the lexical environment.
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
return createBlock(
|
||||
createNodeArray(
|
||||
statements,
|
||||
/*location*/ constructor ? constructor.body.statements : node.members
|
||||
return setTextRange(
|
||||
createBlock(
|
||||
setTextRange(
|
||||
createNodeArray(statements),
|
||||
/*location*/ constructor ? constructor.body.statements : node.members
|
||||
),
|
||||
/*multiLine*/ true
|
||||
),
|
||||
/*location*/ constructor ? constructor.body : /*location*/ undefined,
|
||||
/*multiLine*/ true
|
||||
/*location*/ constructor ? constructor.body : undefined
|
||||
);
|
||||
}
|
||||
|
||||
@@ -991,16 +1005,20 @@ namespace ts {
|
||||
setEmitFlags(localName, EmitFlags.NoComments);
|
||||
|
||||
return startOnNewLine(
|
||||
createStatement(
|
||||
createAssignment(
|
||||
createPropertyAccess(
|
||||
createThis(),
|
||||
propertyName,
|
||||
/*location*/ node.name
|
||||
),
|
||||
localName
|
||||
setTextRange(
|
||||
createStatement(
|
||||
createAssignment(
|
||||
setTextRange(
|
||||
createPropertyAccess(
|
||||
createThis(),
|
||||
propertyName
|
||||
),
|
||||
node.name
|
||||
),
|
||||
localName
|
||||
)
|
||||
),
|
||||
/*location*/ moveRangePos(node, -1)
|
||||
moveRangePos(node, -1)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -1504,7 +1522,7 @@ namespace ts {
|
||||
(properties || (properties = [])).push(createPropertyAssignment("returnType", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, createToken(SyntaxKind.EqualsGreaterThanToken), serializeReturnTypeOfNode(node))));
|
||||
}
|
||||
if (properties) {
|
||||
decoratorExpressions.push(createMetadataHelper(context, "design:typeinfo", createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true)));
|
||||
decoratorExpressions.push(createMetadataHelper(context, "design:typeinfo", createObjectLiteral(properties, /*multiLine*/ true)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1939,10 +1957,7 @@ namespace ts {
|
||||
expression = createAssignment(generatedName, expression);
|
||||
}
|
||||
|
||||
return setOriginalNode(
|
||||
createComputedPropertyName(expression, /*location*/ name),
|
||||
name
|
||||
);
|
||||
return updateComputedPropertyName(name, expression);
|
||||
}
|
||||
else {
|
||||
return name;
|
||||
@@ -1961,9 +1976,11 @@ namespace ts {
|
||||
function visitHeritageClause(node: HeritageClause): HeritageClause {
|
||||
if (node.token === SyntaxKind.ExtendsKeyword) {
|
||||
const types = visitNodes(node.types, visitor, isExpressionWithTypeArguments, 0, 1);
|
||||
return createHeritageClause(
|
||||
SyntaxKind.ExtendsKeyword,
|
||||
types,
|
||||
return setTextRange(
|
||||
createHeritageClause(
|
||||
SyntaxKind.ExtendsKeyword,
|
||||
types
|
||||
),
|
||||
node
|
||||
);
|
||||
}
|
||||
@@ -1980,11 +1997,10 @@ namespace ts {
|
||||
* @param node The ExpressionWithTypeArguments to transform.
|
||||
*/
|
||||
function visitExpressionWithTypeArguments(node: ExpressionWithTypeArguments): ExpressionWithTypeArguments {
|
||||
const expression = visitNode(node.expression, visitor, isLeftHandSideExpression);
|
||||
return createExpressionWithTypeArguments(
|
||||
return updateExpressionWithTypeArguments(
|
||||
node,
|
||||
/*typeArguments*/ undefined,
|
||||
expression,
|
||||
node
|
||||
visitNode(node.expression, visitor, isLeftHandSideExpression)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2205,13 +2221,13 @@ namespace ts {
|
||||
visitNode(node.name, visitor, isBindingName),
|
||||
/*questionToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
visitNode(node.initializer, visitor, isExpression),
|
||||
/*location*/ moveRangePastModifiers(node)
|
||||
visitNode(node.initializer, visitor, isExpression)
|
||||
);
|
||||
|
||||
// While we emit the source map for the node after skipping decorators and modifiers,
|
||||
// we need to emit the comments for the original range.
|
||||
setOriginalNode(parameter, node);
|
||||
setTextRange(parameter, moveRangePastModifiers(node));
|
||||
setCommentRange(parameter, node);
|
||||
setSourceMapRange(parameter, moveRangePastModifiers(node));
|
||||
setEmitFlags(parameter.name, EmitFlags.NoTrailingSourceMap);
|
||||
@@ -2233,11 +2249,13 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return createStatement(
|
||||
inlineExpressions(
|
||||
map(variables, transformInitializedVariable)
|
||||
return setTextRange(
|
||||
createStatement(
|
||||
inlineExpressions(
|
||||
map(variables, transformInitializedVariable)
|
||||
)
|
||||
),
|
||||
/*location*/ node
|
||||
node
|
||||
);
|
||||
}
|
||||
else {
|
||||
@@ -2258,9 +2276,11 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
else {
|
||||
return createAssignment(
|
||||
getNamespaceMemberNameWithSourceMapsAndWithoutComments(name),
|
||||
visitNode(node.initializer, visitor, isExpression),
|
||||
return setTextRange(
|
||||
createAssignment(
|
||||
getNamespaceMemberNameWithSourceMapsAndWithoutComments(name),
|
||||
visitNode(node.initializer, visitor, isExpression)
|
||||
),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
@@ -2418,11 +2438,11 @@ namespace ts {
|
||||
),
|
||||
/*typeArguments*/ undefined,
|
||||
[moduleArg]
|
||||
),
|
||||
/*location*/ node
|
||||
)
|
||||
);
|
||||
|
||||
setOriginalNode(enumStatement, node);
|
||||
setTextRange(enumStatement, node);
|
||||
setEmitFlags(enumStatement, emitFlags);
|
||||
statements.push(enumStatement);
|
||||
|
||||
@@ -2448,8 +2468,7 @@ namespace ts {
|
||||
|
||||
currentNamespaceContainerName = savedCurrentNamespaceLocalName;
|
||||
return createBlock(
|
||||
createNodeArray(statements, /*location*/ node.members),
|
||||
/*location*/ undefined,
|
||||
setTextRange(createNodeArray(statements), /*location*/ node.members),
|
||||
/*multiLine*/ true
|
||||
);
|
||||
}
|
||||
@@ -2464,22 +2483,26 @@ namespace ts {
|
||||
// we pass false as 'generateNameForComputedPropertyName' for a backward compatibility purposes
|
||||
// old emitter always generate 'expression' part of the name as-is.
|
||||
const name = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ false);
|
||||
return createStatement(
|
||||
createAssignment(
|
||||
createElementAccess(
|
||||
currentNamespaceContainerName,
|
||||
return setTextRange(
|
||||
createStatement(
|
||||
setTextRange(
|
||||
createAssignment(
|
||||
createElementAccess(
|
||||
currentNamespaceContainerName,
|
||||
name
|
||||
createAssignment(
|
||||
createElementAccess(
|
||||
currentNamespaceContainerName,
|
||||
name
|
||||
),
|
||||
transformEnumMemberDeclarationValue(member)
|
||||
)
|
||||
),
|
||||
transformEnumMemberDeclarationValue(member)
|
||||
)
|
||||
),
|
||||
name,
|
||||
/*location*/ member
|
||||
name
|
||||
),
|
||||
member
|
||||
)
|
||||
),
|
||||
/*location*/ member
|
||||
member
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2697,11 +2720,11 @@ namespace ts {
|
||||
),
|
||||
/*typeArguments*/ undefined,
|
||||
[moduleArg]
|
||||
),
|
||||
/*location*/ node
|
||||
)
|
||||
);
|
||||
|
||||
setOriginalNode(moduleStatement, node);
|
||||
setTextRange(moduleStatement, node);
|
||||
setEmitFlags(moduleStatement, emitFlags);
|
||||
statements.push(moduleStatement);
|
||||
|
||||
@@ -2756,13 +2779,13 @@ namespace ts {
|
||||
currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
|
||||
|
||||
const block = createBlock(
|
||||
createNodeArray(
|
||||
statements,
|
||||
setTextRange(
|
||||
createNodeArray(statements),
|
||||
/*location*/ statementsLocation
|
||||
),
|
||||
/*location*/ blockLocation,
|
||||
/*multiLine*/ true
|
||||
);
|
||||
setTextRange(block, blockLocation);
|
||||
|
||||
// namespace hello.hi.world {
|
||||
// function foo() {}
|
||||
@@ -2962,18 +2985,20 @@ namespace ts {
|
||||
// export var ${name} = ${moduleReference};
|
||||
// var ${name} = ${moduleReference};
|
||||
return setOriginalNode(
|
||||
createVariableStatement(
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
createVariableDeclarationList([
|
||||
setOriginalNode(
|
||||
createVariableDeclaration(
|
||||
node.name,
|
||||
/*type*/ undefined,
|
||||
moduleReference
|
||||
),
|
||||
node
|
||||
)
|
||||
]),
|
||||
setTextRange(
|
||||
createVariableStatement(
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
createVariableDeclarationList([
|
||||
setOriginalNode(
|
||||
createVariableDeclaration(
|
||||
node.name,
|
||||
/*type*/ undefined,
|
||||
moduleReference
|
||||
),
|
||||
node
|
||||
)
|
||||
])
|
||||
),
|
||||
node
|
||||
),
|
||||
node
|
||||
@@ -3034,7 +3059,7 @@ namespace ts {
|
||||
* Creates a statement for the provided expression. This is used in calls to `map`.
|
||||
*/
|
||||
function expressionToStatement(expression: Expression) {
|
||||
return createStatement(expression, /*location*/ undefined);
|
||||
return createStatement(expression);
|
||||
}
|
||||
|
||||
function addExportMemberAssignment(statements: Statement[], node: ClassDeclaration | FunctionDeclaration) {
|
||||
@@ -3050,17 +3075,19 @@ namespace ts {
|
||||
}
|
||||
|
||||
function createNamespaceExport(exportName: Identifier, exportValue: Expression, location?: TextRange) {
|
||||
return createStatement(
|
||||
createAssignment(
|
||||
getNamespaceMemberName(currentNamespaceContainerName, exportName, /*allowComments*/ false, /*allowSourceMaps*/ true),
|
||||
exportValue
|
||||
return setTextRange(
|
||||
createStatement(
|
||||
createAssignment(
|
||||
getNamespaceMemberName(currentNamespaceContainerName, exportName, /*allowComments*/ false, /*allowSourceMaps*/ true),
|
||||
exportValue
|
||||
)
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
function createNamespaceExportExpression(exportName: Identifier, exportValue: Expression, location?: TextRange) {
|
||||
return createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(exportName), exportValue, location);
|
||||
return setTextRange(createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(exportName), exportValue), location);
|
||||
}
|
||||
|
||||
function getNamespaceMemberNameWithSourceMapsAndWithoutComments(name: Identifier) {
|
||||
@@ -3092,7 +3119,7 @@ namespace ts {
|
||||
function getClassAliasIfNeeded(node: ClassDeclaration) {
|
||||
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) {
|
||||
enableSubstitutionForClassAliases();
|
||||
const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? node.name.text : "default");
|
||||
const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? unescapeIdentifier(node.name.text) : "default");
|
||||
classAliases[getOriginalNodeId(node)] = classAlias;
|
||||
hoistVariableDeclaration(classAlias);
|
||||
return classAlias;
|
||||
@@ -3154,11 +3181,11 @@ namespace ts {
|
||||
/**
|
||||
* Hook for node emit.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emit A callback used to emit the node in the printer.
|
||||
*/
|
||||
function onEmitNode(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void {
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
const savedApplicableSubstitutions = applicableSubstitutions;
|
||||
|
||||
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && isTransformedModuleDeclaration(node)) {
|
||||
@@ -3169,7 +3196,7 @@ namespace ts {
|
||||
applicableSubstitutions |= TypeScriptSubstitutionFlags.NonQualifiedEnumMembers;
|
||||
}
|
||||
|
||||
previousOnEmitNode(emitContext, node, emitCallback);
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
|
||||
applicableSubstitutions = savedApplicableSubstitutions;
|
||||
}
|
||||
@@ -3177,12 +3204,12 @@ namespace ts {
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param emitContext A context hint for the emitter.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
if (emitContext === EmitContext.Expression) {
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (hint === EmitHint.Expression) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
else if (isShorthandPropertyAssignment(node)) {
|
||||
@@ -3201,9 +3228,9 @@ namespace ts {
|
||||
// destructuring assignment
|
||||
if (node.objectAssignmentInitializer) {
|
||||
const initializer = createAssignment(exportedName, node.objectAssignmentInitializer);
|
||||
return createPropertyAssignment(name, initializer, /*location*/ node);
|
||||
return setTextRange(createPropertyAssignment(name, initializer), node);
|
||||
}
|
||||
return createPropertyAssignment(name, exportedName, /*location*/ node);
|
||||
return setTextRange(createPropertyAssignment(name, exportedName), node);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
@@ -3263,7 +3290,10 @@ namespace ts {
|
||||
(applicableSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && container.kind === SyntaxKind.ModuleDeclaration) ||
|
||||
(applicableSubstitutions & TypeScriptSubstitutionFlags.NonQualifiedEnumMembers && container.kind === SyntaxKind.EnumDeclaration);
|
||||
if (substitute) {
|
||||
return createPropertyAccess(getGeneratedNameForNode(container), node, /*location*/ node);
|
||||
return setTextRange(
|
||||
createPropertyAccess(getGeneratedNameForNode(container), node),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3322,13 +3352,15 @@ namespace ts {
|
||||
|
||||
function createParamHelper(context: TransformationContext, expression: Expression, parameterOffset: number, location?: TextRange) {
|
||||
context.requestEmitHelper(paramHelper);
|
||||
return createCall(
|
||||
getHelperName("__param"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createLiteral(parameterOffset),
|
||||
expression
|
||||
],
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__param"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createLiteral(parameterOffset),
|
||||
expression
|
||||
]
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
@@ -3371,7 +3403,7 @@ namespace ts {
|
||||
function createDecorateHelper(context: TransformationContext, decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression, location?: TextRange) {
|
||||
context.requestEmitHelper(decorateHelper);
|
||||
const argumentsArray: Expression[] = [];
|
||||
argumentsArray.push(createArrayLiteral(decoratorExpressions, /*location*/ undefined, /*multiLine*/ true));
|
||||
argumentsArray.push(createArrayLiteral(decoratorExpressions, /*multiLine*/ true));
|
||||
argumentsArray.push(target);
|
||||
if (memberName) {
|
||||
argumentsArray.push(memberName);
|
||||
@@ -3380,6 +3412,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
return createCall(getHelperName("__decorate"), /*typeArguments*/ undefined, argumentsArray, location);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__decorate"),
|
||||
/*typeArguments*/ undefined,
|
||||
argumentsArray
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+202
-60
@@ -349,6 +349,7 @@
|
||||
EnumMember,
|
||||
// Top-level nodes
|
||||
SourceFile,
|
||||
Bundle,
|
||||
|
||||
// JSDoc nodes
|
||||
JSDocTypeExpression,
|
||||
@@ -959,8 +960,7 @@
|
||||
}
|
||||
|
||||
// Represents an expression that is elided as part of a transformation to emit comments on a
|
||||
// not-emitted node. The 'expression' property of a NotEmittedExpression should be emitted.
|
||||
// @internal
|
||||
// not-emitted node. The 'expression' property of a PartiallyEmittedExpression should be emitted.
|
||||
export interface PartiallyEmittedExpression extends LeftHandSideExpression {
|
||||
kind: SyntaxKind.PartiallyEmittedExpression;
|
||||
expression: Expression;
|
||||
@@ -1542,7 +1542,6 @@
|
||||
|
||||
// Represents a statement that is elided as part of a transformation to emit comments on a
|
||||
// not-emitted node.
|
||||
// @internal
|
||||
export interface NotEmittedStatement extends Statement {
|
||||
kind: SyntaxKind.NotEmittedStatement;
|
||||
}
|
||||
@@ -1777,24 +1776,28 @@
|
||||
members: NodeArray<EnumMember>;
|
||||
}
|
||||
|
||||
export type ModuleBody = ModuleBlock | ModuleDeclaration;
|
||||
|
||||
export type ModuleName = Identifier | StringLiteral;
|
||||
|
||||
export type ModuleBody = NamespaceBody | JSDocNamespaceBody;
|
||||
|
||||
export interface ModuleDeclaration extends DeclarationStatement {
|
||||
kind: SyntaxKind.ModuleDeclaration;
|
||||
name: Identifier | StringLiteral;
|
||||
body?: ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | Identifier;
|
||||
body?: ModuleBody | JSDocNamespaceDeclaration | Identifier;
|
||||
}
|
||||
|
||||
export type NamespaceBody = ModuleBlock | NamespaceDeclaration;
|
||||
|
||||
export interface NamespaceDeclaration extends ModuleDeclaration {
|
||||
name: Identifier;
|
||||
body: ModuleBlock | NamespaceDeclaration;
|
||||
body: NamespaceBody;
|
||||
}
|
||||
|
||||
export type JSDocNamespaceBody = Identifier | JSDocNamespaceDeclaration;
|
||||
|
||||
export interface JSDocNamespaceDeclaration extends ModuleDeclaration {
|
||||
name: Identifier;
|
||||
body: JSDocNamespaceDeclaration | Identifier;
|
||||
body: JSDocNamespaceBody;
|
||||
}
|
||||
|
||||
export interface ModuleBlock extends Node, Statement {
|
||||
@@ -2073,10 +2076,25 @@
|
||||
ArrayMutation = 1 << 8, // Potential array mutation
|
||||
Referenced = 1 << 9, // Referenced as antecedent once
|
||||
Shared = 1 << 10, // Referenced as antecedent more than once
|
||||
PreFinally = 1 << 11, // Injected edge that links pre-finally label and pre-try flow
|
||||
AfterFinally = 1 << 12, // Injected edge that links post-finally flow with the rest of the graph
|
||||
Label = BranchLabel | LoopLabel,
|
||||
Condition = TrueCondition | FalseCondition
|
||||
}
|
||||
|
||||
export interface FlowLock {
|
||||
locked?: boolean;
|
||||
}
|
||||
|
||||
export interface AfterFinallyFlow extends FlowNode, FlowLock {
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
|
||||
export interface PreFinallyFlow extends FlowNode {
|
||||
antecedent: FlowNode;
|
||||
lock: FlowLock;
|
||||
}
|
||||
|
||||
export interface FlowNode {
|
||||
flags: FlowFlags;
|
||||
id?: number; // Node id used by flow type cache in checker
|
||||
@@ -2206,6 +2224,11 @@
|
||||
/* @internal */ ambientModuleNames: string[];
|
||||
}
|
||||
|
||||
export interface Bundle extends Node {
|
||||
kind: SyntaxKind.Bundle;
|
||||
sourceFiles: SourceFile[];
|
||||
}
|
||||
|
||||
export interface ScriptReferenceHost {
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
getSourceFile(fileName: string): SourceFile;
|
||||
@@ -2471,7 +2494,8 @@
|
||||
InFirstTypeArgument = 0x00000100, // Writing first type argument of the instantiated type
|
||||
InTypeAlias = 0x00000200, // Writing type in type alias declaration
|
||||
UseTypeAliasValue = 0x00000400, // Serialize the type instead of using type-alias. This is needed when we emit declaration file.
|
||||
SuppressAnyReturnType = 0x00000800, // If the return type is any-like, don't offer a return type.
|
||||
SuppressAnyReturnType = 0x00000800, // If the return type is any-like, don't offer a return type.
|
||||
AddUndefined = 0x00001000, // Add undefined to types of initialized, non-optional parameters
|
||||
}
|
||||
|
||||
export const enum SymbolFormatFlags {
|
||||
@@ -2576,6 +2600,7 @@
|
||||
isDeclarationVisible(node: Declaration): boolean;
|
||||
collectLinkedAliases(node: Identifier): Node[];
|
||||
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
|
||||
isRequiredInitializedParameter(node: ParameterDeclaration): boolean;
|
||||
writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
|
||||
writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
|
||||
writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
|
||||
@@ -2599,37 +2624,34 @@
|
||||
|
||||
export const enum SymbolFlags {
|
||||
None = 0,
|
||||
FunctionScopedVariable = 0x00000001, // Variable (var) or parameter
|
||||
BlockScopedVariable = 0x00000002, // A block-scoped variable (let or const)
|
||||
Property = 0x00000004, // Property or enum member
|
||||
EnumMember = 0x00000008, // Enum member
|
||||
Function = 0x00000010, // Function
|
||||
Class = 0x00000020, // Class
|
||||
Interface = 0x00000040, // Interface
|
||||
ConstEnum = 0x00000080, // Const enum
|
||||
RegularEnum = 0x00000100, // Enum
|
||||
ValueModule = 0x00000200, // Instantiated module
|
||||
NamespaceModule = 0x00000400, // Uninstantiated module
|
||||
TypeLiteral = 0x00000800, // Type Literal or mapped type
|
||||
ObjectLiteral = 0x00001000, // Object Literal
|
||||
Method = 0x00002000, // Method
|
||||
Constructor = 0x00004000, // Constructor
|
||||
GetAccessor = 0x00008000, // Get accessor
|
||||
SetAccessor = 0x00010000, // Set accessor
|
||||
Signature = 0x00020000, // Call, construct, or index signature
|
||||
TypeParameter = 0x00040000, // Type parameter
|
||||
TypeAlias = 0x00080000, // Type alias
|
||||
ExportValue = 0x00100000, // Exported value marker (see comment in declareModuleMember in binder)
|
||||
ExportType = 0x00200000, // Exported type marker (see comment in declareModuleMember in binder)
|
||||
ExportNamespace = 0x00400000, // Exported namespace marker (see comment in declareModuleMember in binder)
|
||||
Alias = 0x00800000, // An alias for another symbol (see comment in isAliasSymbolDeclaration in checker)
|
||||
Instantiated = 0x01000000, // Instantiated symbol
|
||||
Merged = 0x02000000, // Merged symbol (created during program binding)
|
||||
Transient = 0x04000000, // Transient symbol (created during type check)
|
||||
Prototype = 0x08000000, // Prototype property (no source representation)
|
||||
SyntheticProperty = 0x10000000, // Property in union or intersection type
|
||||
Optional = 0x20000000, // Optional property
|
||||
ExportStar = 0x40000000, // Export * declaration
|
||||
FunctionScopedVariable = 1 << 0, // Variable (var) or parameter
|
||||
BlockScopedVariable = 1 << 1, // A block-scoped variable (let or const)
|
||||
Property = 1 << 2, // Property or enum member
|
||||
EnumMember = 1 << 3, // Enum member
|
||||
Function = 1 << 4, // Function
|
||||
Class = 1 << 5, // Class
|
||||
Interface = 1 << 6, // Interface
|
||||
ConstEnum = 1 << 7, // Const enum
|
||||
RegularEnum = 1 << 8, // Enum
|
||||
ValueModule = 1 << 9, // Instantiated module
|
||||
NamespaceModule = 1 << 10, // Uninstantiated module
|
||||
TypeLiteral = 1 << 11, // Type Literal or mapped type
|
||||
ObjectLiteral = 1 << 12, // Object Literal
|
||||
Method = 1 << 13, // Method
|
||||
Constructor = 1 << 14, // Constructor
|
||||
GetAccessor = 1 << 15, // Get accessor
|
||||
SetAccessor = 1 << 16, // Set accessor
|
||||
Signature = 1 << 17, // Call, construct, or index signature
|
||||
TypeParameter = 1 << 18, // Type parameter
|
||||
TypeAlias = 1 << 19, // Type alias
|
||||
ExportValue = 1 << 20, // Exported value marker (see comment in declareModuleMember in binder)
|
||||
ExportType = 1 << 21, // Exported type marker (see comment in declareModuleMember in binder)
|
||||
ExportNamespace = 1 << 22, // Exported namespace marker (see comment in declareModuleMember in binder)
|
||||
Alias = 1 << 23, // An alias for another symbol (see comment in isAliasSymbolDeclaration in checker)
|
||||
Prototype = 1 << 24, // Prototype property (no source representation)
|
||||
ExportStar = 1 << 25, // Export * declaration
|
||||
Optional = 1 << 26, // Optional property
|
||||
Transient = 1 << 27, // Transient symbol (created during type check)
|
||||
|
||||
Enum = RegularEnum | ConstEnum,
|
||||
Variable = FunctionScopedVariable | BlockScopedVariable,
|
||||
@@ -2689,11 +2711,9 @@
|
||||
name: string; // Name of symbol
|
||||
declarations?: Declaration[]; // Declarations associated with this symbol
|
||||
valueDeclaration?: Declaration; // First value declaration of the symbol
|
||||
|
||||
members?: SymbolTable; // Class, interface or literal instance members
|
||||
exports?: SymbolTable; // Module exports
|
||||
globalExports?: SymbolTable; // Conditional global UMD exports
|
||||
/* @internal */ isReadonly?: boolean; // readonly? (set only for intersections and unions)
|
||||
/* @internal */ id?: number; // Unique id (used to look up SymbolLinks)
|
||||
/* @internal */ mergeId?: number; // Merge id (used to look up merged symbol)
|
||||
/* @internal */ parent?: Symbol; // Parent symbol
|
||||
@@ -2718,8 +2738,6 @@
|
||||
leftSpread?: Symbol; // Left source for synthetic spread property
|
||||
rightSpread?: Symbol; // Right source for synthetic spread property
|
||||
mappedTypeOrigin?: Symbol; // For a property on a mapped type, points back to the orignal 'T' from 'keyof T'.
|
||||
hasNonUniformType?: boolean; // True if constituents have non-uniform types
|
||||
isPartial?: boolean; // True if syntheric property of union type occurs in some but not all constituents
|
||||
isDiscriminantProperty?: boolean; // True if discriminant synthetic property
|
||||
resolvedExports?: SymbolTable; // Resolved exports of module
|
||||
exportsChecked?: boolean; // True if exports of external module have been checked
|
||||
@@ -2729,7 +2747,22 @@
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface TransientSymbol extends Symbol, SymbolLinks { }
|
||||
export const enum CheckFlags {
|
||||
Instantiated = 1 << 0, // Instantiated symbol
|
||||
SyntheticProperty = 1 << 1, // Property in union or intersection type
|
||||
Readonly = 1 << 2, // Readonly transient symbol
|
||||
Partial = 1 << 3, // Synthetic property present in some but not all constituents
|
||||
HasNonUniformType = 1 << 4, // Synthetic property with non-uniform type in constituents
|
||||
ContainsPublic = 1 << 5, // Synthetic property with public constituent(s)
|
||||
ContainsProtected = 1 << 6, // Synthetic property with protected constituent(s)
|
||||
ContainsPrivate = 1 << 7, // Synthetic property with private constituent(s)
|
||||
ContainsStatic = 1 << 8, // Synthetic property with static constituent(s)
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface TransientSymbol extends Symbol, SymbolLinks {
|
||||
checkFlags: CheckFlags;
|
||||
}
|
||||
|
||||
export type SymbolTable = Map<Symbol>;
|
||||
|
||||
@@ -3144,9 +3177,8 @@
|
||||
ThisProperty
|
||||
}
|
||||
|
||||
export interface FileExtensionInfo {
|
||||
export interface JsFileExtensionInfo {
|
||||
extension: string;
|
||||
scriptKind: ScriptKind;
|
||||
isMixedContent: boolean;
|
||||
}
|
||||
|
||||
@@ -3190,7 +3222,11 @@
|
||||
NodeJs = 2
|
||||
}
|
||||
|
||||
export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]>;
|
||||
export interface PluginImport {
|
||||
name: string
|
||||
}
|
||||
|
||||
export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[];
|
||||
|
||||
export interface CompilerOptions {
|
||||
allowJs?: boolean;
|
||||
@@ -3245,6 +3281,7 @@
|
||||
outDir?: string;
|
||||
outFile?: string;
|
||||
paths?: MapLike<string[]>;
|
||||
/*@internal*/ plugins?: PluginImport[];
|
||||
preserveConstEnums?: boolean;
|
||||
project?: string;
|
||||
/* @internal */ pretty?: DiagnosticStyle;
|
||||
@@ -3328,7 +3365,8 @@
|
||||
JS = 1,
|
||||
JSX = 2,
|
||||
TS = 3,
|
||||
TSX = 4
|
||||
TSX = 4,
|
||||
External = 5
|
||||
}
|
||||
|
||||
export const enum ScriptTarget {
|
||||
@@ -3403,7 +3441,7 @@
|
||||
/* @internal */
|
||||
export interface CommandLineOptionOfListType extends CommandLineOptionBase {
|
||||
type: "list";
|
||||
element: CommandLineOptionOfCustomType | CommandLineOptionOfPrimitiveType;
|
||||
element: CommandLineOptionOfCustomType | CommandLineOptionOfPrimitiveType | TsConfigOnlyOption;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -3731,7 +3769,6 @@
|
||||
helpers?: EmitHelper[]; // Emit helpers for the node
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const enum EmitFlags {
|
||||
SingleLine = 1 << 0, // The contents of this node should be emitted on a single line.
|
||||
AdviseOnEmitNode = 1 << 1, // The printer should invoke the onEmitNode callback when printing this node.
|
||||
@@ -3760,7 +3797,6 @@
|
||||
HasEndOfDeclarationMarker = 1 << 21, // Declaration has an associated NotEmittedStatement to mark the end of the declaration
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface EmitHelper {
|
||||
readonly name: string; // A unique name for this helper.
|
||||
readonly scoped: boolean; // Indicates whether ther helper MUST be emitted in the current scope.
|
||||
@@ -3787,8 +3823,7 @@
|
||||
LastEmitHelper = Generator
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const enum EmitContext {
|
||||
export const enum EmitHint {
|
||||
SourceFile, // Emitting a SourceFile
|
||||
Expression, // Emitting an Expression
|
||||
IdentifierName, // Emitting an IdentifierName
|
||||
@@ -3863,7 +3898,7 @@
|
||||
* Hook used by transformers to substitute expressions just before they
|
||||
* are emitted by the pretty printer.
|
||||
*/
|
||||
onSubstituteNode?: (emitContext: EmitContext, node: Node) => Node;
|
||||
onSubstituteNode?: (hint: EmitHint, node: Node) => Node;
|
||||
|
||||
/**
|
||||
* Enables before/after emit notifications in the pretty printer for the provided
|
||||
@@ -3881,7 +3916,7 @@
|
||||
* Hook used to allow transformers to capture state before or after
|
||||
* the printer emits a node.
|
||||
*/
|
||||
onEmitNode?: (emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void) => void;
|
||||
onEmitNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -3894,25 +3929,132 @@
|
||||
/**
|
||||
* Emits the substitute for a node, if one is available; otherwise, emits the node.
|
||||
*
|
||||
* @param emitContext The current emit context.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
* @param emitCallback A callback used to emit the node or its substitute.
|
||||
*/
|
||||
emitNodeWithSubstitution(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
|
||||
emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
|
||||
/**
|
||||
* Emits a node with possible notification.
|
||||
*
|
||||
* @param emitContext The current emit context.
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback A callback used to emit the node.
|
||||
*/
|
||||
emitNodeWithNotification(emitContext: EmitContext, node: Node, emitCallback: (emitContext: EmitContext, node: Node) => void): void;
|
||||
emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type Transformer = (context: TransformationContext) => (node: SourceFile) => SourceFile;
|
||||
|
||||
export interface Printer {
|
||||
/**
|
||||
* Print a node and its subtree as-is, without any emit transformations.
|
||||
* @param hint A value indicating the purpose of a node. This is primarily used to
|
||||
* distinguish between an `Identifier` used in an expression position, versus an
|
||||
* `Identifier` used as an `IdentifierName` as part of a declaration. For most nodes you
|
||||
* should just pass `Unspecified`.
|
||||
* @param node The node to print. The node and its subtree are printed as-is, without any
|
||||
* emit transformations.
|
||||
* @param sourceFile A source file that provides context for the node. The source text of
|
||||
* the file is used to emit the original source content for literals and identifiers, while
|
||||
* the identifiers of the source file are used when generating unique names to avoid
|
||||
* collisions.
|
||||
*/
|
||||
printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): string;
|
||||
/**
|
||||
* Prints a source file as-is, without any emit transformations.
|
||||
*/
|
||||
printFile(sourceFile: SourceFile): string;
|
||||
/**
|
||||
* Prints a bundle of source files as-is, without any emit transformations.
|
||||
*/
|
||||
printBundle(bundle: Bundle): string;
|
||||
/*@internal*/ writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile, writer: EmitTextWriter): void;
|
||||
/*@internal*/ writeFile(sourceFile: SourceFile, writer: EmitTextWriter): void;
|
||||
/*@internal*/ writeBundle(bundle: Bundle, writer: EmitTextWriter): void;
|
||||
}
|
||||
|
||||
export interface PrintHandlers {
|
||||
/**
|
||||
* A hook used by the Printer when generating unique names to avoid collisions with
|
||||
* globally defined names that exist outside of the current source file.
|
||||
*/
|
||||
hasGlobalName?(name: string): boolean;
|
||||
/**
|
||||
* A hook used by the Printer to provide notifications prior to emitting a node. A
|
||||
* compatible implementation **must** invoke `emitCallback` with the provided `hint` and
|
||||
* `node` values.
|
||||
* @param hint A hint indicating the intended purpose of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback A callback that, when invoked, will emit the node.
|
||||
* @example
|
||||
* ```ts
|
||||
* var printer = createPrinter(printerOptions, {
|
||||
* onEmitNode(hint, node, emitCallback) {
|
||||
* // set up or track state prior to emitting the node...
|
||||
* emitCallback(hint, node);
|
||||
* // restore state after emitting the node...
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
onEmitNode?(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
/**
|
||||
* A hook used by the Printer to perform just-in-time substitution of a node. This is
|
||||
* primarily used by node transformations that need to substitute one node for another,
|
||||
* such as replacing `myExportedVar` with `exports.myExportedVar`. A compatible
|
||||
* implementation **must** invoke `emitCallback` eith the provided `hint` and either
|
||||
* the provided `node`, or its substitute.
|
||||
* @param hint A hint indicating the intended purpose of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback A callback that, when invoked, will emit the node.
|
||||
* @example
|
||||
* ```ts
|
||||
* var printer = createPrinter(printerOptions, {
|
||||
* onSubstituteNode(hint, node, emitCallback) {
|
||||
* // perform substitution if necessary...
|
||||
* emitCallback(hint, node);
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
onSubstituteNode?(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
/*@internal*/ onEmitSourceMapOfNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
/*@internal*/ onEmitSourceMapOfToken?: (node: Node, token: SyntaxKind, pos: number, emitCallback: (token: SyntaxKind, pos: number) => number) => number;
|
||||
/*@internal*/ onEmitSourceMapOfPosition?: (pos: number) => void;
|
||||
/*@internal*/ onEmitHelpers?: (node: Node, writeLines: (text: string) => void) => void;
|
||||
/*@internal*/ onSetSourceFile?: (node: SourceFile) => void;
|
||||
}
|
||||
|
||||
export interface PrinterOptions {
|
||||
target?: ScriptTarget;
|
||||
removeComments?: boolean;
|
||||
newLine?: NewLineKind;
|
||||
/*@internal*/ sourceMap?: boolean;
|
||||
/*@internal*/ inlineSourceMap?: boolean;
|
||||
/*@internal*/ extendedDiagnostics?: boolean;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export interface EmitTextWriter {
|
||||
write(s: string): void;
|
||||
writeTextOfNode(text: string, node: Node): void;
|
||||
writeLine(): void;
|
||||
increaseIndent(): void;
|
||||
decreaseIndent(): void;
|
||||
getText(): string;
|
||||
rawWrite(s: string): void;
|
||||
writeLiteral(s: string): void;
|
||||
getTextPos(): number;
|
||||
getLine(): number;
|
||||
getColumn(): number;
|
||||
getIndent(): number;
|
||||
isAtStartOfLine(): boolean;
|
||||
reset(): void;
|
||||
}
|
||||
|
||||
export interface TextSpan {
|
||||
start: number;
|
||||
length: number;
|
||||
|
||||
+88
-76
@@ -1523,6 +1523,11 @@ namespace ts {
|
||||
return map(getJSDocs(node), doc => doc.comment);
|
||||
}
|
||||
|
||||
export function hasJSDocParameterTags(node: FunctionLikeDeclaration | SignatureDeclaration) {
|
||||
const parameterTags = getJSDocTags(node, SyntaxKind.JSDocParameterTag);
|
||||
return parameterTags && parameterTags.length > 0;
|
||||
}
|
||||
|
||||
function getJSDocTags(node: Node, kind: SyntaxKind): JSDocTag[] {
|
||||
const docs = getJSDocs(node);
|
||||
if (docs) {
|
||||
@@ -2047,67 +2052,19 @@ namespace ts {
|
||||
|| positionIsSynthesized(node.end);
|
||||
}
|
||||
|
||||
export function getOriginalNode(node: Node): Node;
|
||||
export function getOriginalNode<T extends Node>(node: Node, nodeTest: (node: Node) => node is T): T;
|
||||
export function getOriginalNode(node: Node, nodeTest?: (node: Node) => boolean): Node {
|
||||
if (node) {
|
||||
while (node.original !== undefined) {
|
||||
node = node.original;
|
||||
}
|
||||
export function getOriginalSourceFileOrBundle(sourceFileOrBundle: SourceFile | Bundle) {
|
||||
if (sourceFileOrBundle.kind === SyntaxKind.Bundle) {
|
||||
return updateBundle(sourceFileOrBundle, sameMap(sourceFileOrBundle.sourceFiles, getOriginalSourceFile));
|
||||
}
|
||||
|
||||
return !nodeTest || nodeTest(node) ? node : undefined;
|
||||
return getOriginalSourceFile(sourceFileOrBundle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether a node originated in the parse tree.
|
||||
*
|
||||
* @param node The node to test.
|
||||
*/
|
||||
export function isParseTreeNode(node: Node): boolean {
|
||||
return (node.flags & NodeFlags.Synthesized) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the original parse tree node for a node.
|
||||
*
|
||||
* @param node The original node.
|
||||
* @returns The original parse tree node if found; otherwise, undefined.
|
||||
*/
|
||||
export function getParseTreeNode(node: Node): Node;
|
||||
|
||||
/**
|
||||
* Gets the original parse tree node for a node.
|
||||
*
|
||||
* @param node The original node.
|
||||
* @param nodeTest A callback used to ensure the correct type of parse tree node is returned.
|
||||
* @returns The original parse tree node if found; otherwise, undefined.
|
||||
*/
|
||||
export function getParseTreeNode<T extends Node>(node: Node, nodeTest?: (node: Node) => node is T): T;
|
||||
export function getParseTreeNode(node: Node, nodeTest?: (node: Node) => boolean): Node {
|
||||
if (isParseTreeNode(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
node = getOriginalNode(node);
|
||||
|
||||
if (isParseTreeNode(node) && (!nodeTest || nodeTest(node))) {
|
||||
return node;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
function getOriginalSourceFile(sourceFile: SourceFile) {
|
||||
return getParseTreeNode(sourceFile, isSourceFile) || sourceFile;
|
||||
}
|
||||
|
||||
export function getOriginalSourceFiles(sourceFiles: SourceFile[]) {
|
||||
const originalSourceFiles: SourceFile[] = [];
|
||||
for (const sourceFile of sourceFiles) {
|
||||
const originalSourceFile = getParseTreeNode(sourceFile, isSourceFile);
|
||||
if (originalSourceFile) {
|
||||
originalSourceFiles.push(originalSourceFile);
|
||||
}
|
||||
}
|
||||
|
||||
return originalSourceFiles;
|
||||
return sameMap(sourceFiles, getOriginalSourceFile);
|
||||
}
|
||||
|
||||
export function getOriginalNodeId(node: Node) {
|
||||
@@ -2446,23 +2403,6 @@ namespace ts {
|
||||
s;
|
||||
}
|
||||
|
||||
export interface EmitTextWriter {
|
||||
write(s: string): void;
|
||||
writeTextOfNode(text: string, node: Node): void;
|
||||
writeLine(): void;
|
||||
increaseIndent(): void;
|
||||
decreaseIndent(): void;
|
||||
getText(): string;
|
||||
rawWrite(s: string): void;
|
||||
writeLiteral(s: string): void;
|
||||
getTextPos(): number;
|
||||
getLine(): number;
|
||||
getColumn(): number;
|
||||
getIndent(): number;
|
||||
isAtStartOfLine(): boolean;
|
||||
reset(): void;
|
||||
}
|
||||
|
||||
const indentStrings: string[] = ["", " "];
|
||||
export function getIndentString(level: number) {
|
||||
if (indentStrings[level] === undefined) {
|
||||
@@ -2645,7 +2585,7 @@ namespace ts {
|
||||
* Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit.
|
||||
*/
|
||||
export function forEachEmittedFile(
|
||||
host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean, emitOnlyDtsFiles: boolean) => void,
|
||||
host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean) => void,
|
||||
sourceFilesOrTargetSourceFile?: SourceFile[] | SourceFile,
|
||||
emitOnlyDtsFiles?: boolean) {
|
||||
|
||||
@@ -2656,7 +2596,7 @@ namespace ts {
|
||||
const jsFilePath = options.outFile || options.out;
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined;
|
||||
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFiles, /*isBundledEmit*/true, emitOnlyDtsFiles);
|
||||
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -2664,7 +2604,7 @@ namespace ts {
|
||||
const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options));
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined;
|
||||
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, [sourceFile], /*isBundledEmit*/false, emitOnlyDtsFiles);
|
||||
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFile, emitOnlyDtsFiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3239,7 +3179,7 @@ namespace ts {
|
||||
|
||||
const carriageReturnLineFeed = "\r\n";
|
||||
const lineFeed = "\n";
|
||||
export function getNewLineCharacter(options: CompilerOptions): string {
|
||||
export function getNewLineCharacter(options: CompilerOptions | PrinterOptions): string {
|
||||
if (options.newLine === NewLineKind.CarriageReturnLineFeed) {
|
||||
return carriageReturnLineFeed;
|
||||
}
|
||||
@@ -3350,6 +3290,14 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function getRangePos(range: TextRange | undefined) {
|
||||
return range ? range.pos : -1;
|
||||
}
|
||||
|
||||
export function getRangeEnd(range: TextRange | undefined) {
|
||||
return range ? range.end : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases (or decreases) a position by the provided amount.
|
||||
*
|
||||
@@ -3949,6 +3897,19 @@ namespace ts {
|
||||
export function isModuleBody(node: Node): node is ModuleBody {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.ModuleBlock
|
||||
|| kind === SyntaxKind.ModuleDeclaration
|
||||
|| kind === SyntaxKind.Identifier;
|
||||
}
|
||||
|
||||
export function isNamespaceBody(node: Node): node is NamespaceBody {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.ModuleBlock
|
||||
|| kind === SyntaxKind.ModuleDeclaration;
|
||||
}
|
||||
|
||||
export function isJSDocNamespaceBody(node: Node): node is JSDocNamespaceBody {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.Identifier
|
||||
|| kind === SyntaxKind.ModuleDeclaration;
|
||||
}
|
||||
|
||||
@@ -4551,4 +4512,55 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export function getOriginalNode(node: Node): Node;
|
||||
export function getOriginalNode<T extends Node>(node: Node, nodeTest: (node: Node) => node is T): T;
|
||||
export function getOriginalNode(node: Node, nodeTest?: (node: Node) => boolean): Node {
|
||||
if (node) {
|
||||
while (node.original !== undefined) {
|
||||
node = node.original;
|
||||
}
|
||||
}
|
||||
|
||||
return !nodeTest || nodeTest(node) ? node : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether a node originated in the parse tree.
|
||||
*
|
||||
* @param node The node to test.
|
||||
*/
|
||||
export function isParseTreeNode(node: Node): boolean {
|
||||
return (node.flags & NodeFlags.Synthesized) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the original parse tree node for a node.
|
||||
*
|
||||
* @param node The original node.
|
||||
* @returns The original parse tree node if found; otherwise, undefined.
|
||||
*/
|
||||
export function getParseTreeNode(node: Node): Node;
|
||||
|
||||
/**
|
||||
* Gets the original parse tree node for a node.
|
||||
*
|
||||
* @param node The original node.
|
||||
* @param nodeTest A callback used to ensure the correct type of parse tree node is returned.
|
||||
* @returns The original parse tree node if found; otherwise, undefined.
|
||||
*/
|
||||
export function getParseTreeNode<T extends Node>(node: Node, nodeTest?: (node: Node) => node is T): T;
|
||||
export function getParseTreeNode(node: Node, nodeTest?: (node: Node) => boolean): Node {
|
||||
if (isParseTreeNode(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
node = getOriginalNode(node);
|
||||
|
||||
if (isParseTreeNode(node) && (!nodeTest || nodeTest(node))) {
|
||||
return node;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
+147
-166
@@ -6,97 +6,6 @@
|
||||
namespace ts {
|
||||
export type VisitResult<T extends Node> = T | T[];
|
||||
|
||||
/**
|
||||
* Describes an edge of a Node, used when traversing a syntax tree.
|
||||
*/
|
||||
interface NodeEdge {
|
||||
/** The property name for the edge. */
|
||||
name: string;
|
||||
|
||||
/** Indicates that the result is optional. */
|
||||
optional?: boolean;
|
||||
|
||||
/** A callback used to test whether a node is valid. */
|
||||
test?: (node: Node) => node is Node;
|
||||
|
||||
/** A callback used to lift a NodeArrayNode into a valid node. */
|
||||
lift?: (nodes: NodeArray<Node>) => Node;
|
||||
|
||||
/** A callback used to parenthesize a node to preserve the intended order of operations. */
|
||||
parenthesize?: (value: Node, parentNode: Node) => Node;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the shape of a Node.
|
||||
*/
|
||||
type NodeTraversalPath = NodeEdge[];
|
||||
|
||||
/**
|
||||
* This map contains information about the shape of each Node in "types.ts" pertaining to how
|
||||
* each node should be traversed during a transformation.
|
||||
*
|
||||
* Each edge corresponds to a property in a Node subtype that should be traversed when visiting
|
||||
* each child. The properties are assigned in the order in which traversal should occur.
|
||||
*
|
||||
* We only add entries for nodes that do not have a create/update pair defined in factory.ts
|
||||
*
|
||||
* NOTE: This needs to be kept up to date with changes to nodes in "types.ts". Currently, this
|
||||
* map is not comprehensive. Only node edges relevant to tree transformation are
|
||||
* currently defined. We may extend this to be more comprehensive, and eventually
|
||||
* supplant the existing `forEachChild` implementation if performance is not
|
||||
* significantly impacted.
|
||||
*/
|
||||
function getNodeEdgeTraversal(kind: SyntaxKind): NodeTraversalPath {
|
||||
switch (kind) {
|
||||
case SyntaxKind.QualifiedName: return [
|
||||
{ name: "left", test: isEntityName },
|
||||
{ name: "right", test: isIdentifier }
|
||||
];
|
||||
case SyntaxKind.Decorator: return [
|
||||
{ name: "expression", test: isLeftHandSideExpression }
|
||||
];
|
||||
case SyntaxKind.TypeAssertionExpression: return [
|
||||
{ name: "type", test: isTypeNode },
|
||||
{ name: "expression", test: isUnaryExpression }
|
||||
];
|
||||
case SyntaxKind.AsExpression: return [
|
||||
{ name: "expression", test: isExpression },
|
||||
{ name: "type", test: isTypeNode }
|
||||
];
|
||||
case SyntaxKind.NonNullExpression: return [
|
||||
{ name: "expression", test: isLeftHandSideExpression }
|
||||
];
|
||||
case SyntaxKind.EnumDeclaration: return [
|
||||
{ name: "decorators", test: isDecorator },
|
||||
{ name: "modifiers", test: isModifier },
|
||||
{ name: "name", test: isIdentifier },
|
||||
{ name: "members", test: isEnumMember }
|
||||
];
|
||||
case SyntaxKind.ModuleDeclaration: return [
|
||||
{ name: "decorators", test: isDecorator },
|
||||
{ name: "modifiers", test: isModifier },
|
||||
{ name: "name", test: isModuleName },
|
||||
{ name: "body", test: isModuleBody }
|
||||
];
|
||||
case SyntaxKind.ModuleBlock: return [
|
||||
{ name: "statements", test: isStatement }
|
||||
];
|
||||
case SyntaxKind.ImportEqualsDeclaration: return [
|
||||
{ name: "decorators", test: isDecorator },
|
||||
{ name: "modifiers", test: isModifier },
|
||||
{ name: "name", test: isIdentifier },
|
||||
{ name: "moduleReference", test: isModuleReference }
|
||||
];
|
||||
case SyntaxKind.ExternalModuleReference: return [
|
||||
{ name: "expression", test: isExpression, optional: true }
|
||||
];
|
||||
case SyntaxKind.EnumMember: return [
|
||||
{ name: "name", test: isPropertyName },
|
||||
{ name: "initializer", test: isExpression, optional: true, parenthesize: parenthesizeExpressionForList }
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
function reduceNode<T>(node: Node, f: (memo: T, node: Node) => T, initial: T) {
|
||||
return node ? f(initial, node) : initial;
|
||||
}
|
||||
@@ -107,8 +16,7 @@ namespace ts {
|
||||
|
||||
/**
|
||||
* Similar to `reduceLeft`, performs a reduction against each child of a node.
|
||||
* NOTE: Unlike `forEachChild`, this does *not* visit every node. Only nodes added to the
|
||||
* `nodeEdgeTraversalMap` above will be visited.
|
||||
* NOTE: Unlike `forEachChild`, this does *not* visit every node.
|
||||
*
|
||||
* @param node The node containing the children to reduce.
|
||||
* @param initial The initial value to supply to the reduction.
|
||||
@@ -145,6 +53,11 @@ namespace ts {
|
||||
break;
|
||||
|
||||
// Names
|
||||
case SyntaxKind.QualifiedName:
|
||||
result = reduceNode((<QualifiedName>node).left, cbNode, result);
|
||||
result = reduceNode((<QualifiedName>node).right, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
result = reduceNode((<ComputedPropertyName>node).expression, cbNode, result);
|
||||
break;
|
||||
@@ -252,6 +165,11 @@ namespace ts {
|
||||
result = reduceNode((<TaggedTemplateExpression>node).template, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
result = reduceNode((<TypeAssertion>node).type, cbNode, result);
|
||||
result = reduceNode((<TypeAssertion>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.FunctionExpression:
|
||||
result = reduceNodes((<FunctionExpression>node).modifiers, cbNodes, result);
|
||||
result = reduceNode((<FunctionExpression>node).name, cbNode, result);
|
||||
@@ -314,6 +232,15 @@ namespace ts {
|
||||
result = reduceNodes((<ExpressionWithTypeArguments>node).typeArguments, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.AsExpression:
|
||||
result = reduceNode((<AsExpression>node).expression, cbNode, result);
|
||||
result = reduceNode((<AsExpression>node).type, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.NonNullExpression:
|
||||
result = reduceNode((<NonNullExpression>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
// Misc
|
||||
case SyntaxKind.TemplateSpan:
|
||||
result = reduceNode((<TemplateSpan>node).expression, cbNode, result);
|
||||
@@ -415,10 +342,35 @@ namespace ts {
|
||||
result = reduceNodes((<ClassDeclaration>node).members, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
result = reduceNodes((<EnumDeclaration>node).decorators, cbNodes, result);
|
||||
result = reduceNodes((<EnumDeclaration>node).modifiers, cbNodes, result);
|
||||
result = reduceNode((<EnumDeclaration>node).name, cbNode, result);
|
||||
result = reduceNodes((<EnumDeclaration>node).members, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
result = reduceNodes((<ModuleDeclaration>node).decorators, cbNodes, result);
|
||||
result = reduceNodes((<ModuleDeclaration>node).modifiers, cbNodes, result);
|
||||
result = reduceNode((<ModuleDeclaration>node).name, cbNode, result);
|
||||
result = reduceNode((<ModuleDeclaration>node).body, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ModuleBlock:
|
||||
result = reduceNodes((<ModuleBlock>node).statements, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.CaseBlock:
|
||||
result = reduceNodes((<CaseBlock>node).clauses, cbNodes, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
result = reduceNodes((<ImportEqualsDeclaration>node).decorators, cbNodes, result);
|
||||
result = reduceNodes((<ImportEqualsDeclaration>node).modifiers, cbNodes, result);
|
||||
result = reduceNode((<ImportEqualsDeclaration>node).name, cbNode, result);
|
||||
result = reduceNode((<ImportEqualsDeclaration>node).moduleReference, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
result = reduceNodes((<ImportDeclaration>node).decorators, cbNodes, result);
|
||||
result = reduceNodes((<ImportDeclaration>node).modifiers, cbNodes, result);
|
||||
@@ -459,6 +411,11 @@ namespace ts {
|
||||
result = reduceNode((<ExportDeclaration>node).moduleSpecifier, cbNode, result);
|
||||
break;
|
||||
|
||||
// Module references
|
||||
case SyntaxKind.ExternalModuleReference:
|
||||
result = reduceNode((<ExternalModuleReference>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
// JSX
|
||||
case SyntaxKind.JsxElement:
|
||||
result = reduceNode((<JsxElement>node).openingElement, cbNode, result);
|
||||
@@ -523,30 +480,25 @@ namespace ts {
|
||||
break;
|
||||
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
result = reduceNode((node as SpreadAssignment).expression, cbNode, result);
|
||||
result = reduceNode((<SpreadAssignment>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
// Enum
|
||||
case SyntaxKind.EnumMember:
|
||||
result = reduceNode((<EnumMember>node).name, cbNode, result);
|
||||
result = reduceNode((<EnumMember>node).initializer, cbNode, result);
|
||||
|
||||
// Top-level nodes
|
||||
case SyntaxKind.SourceFile:
|
||||
result = reduceNodes((<SourceFile>node).statements, cbNodes, result);
|
||||
break;
|
||||
|
||||
// Transformation nodes
|
||||
case SyntaxKind.PartiallyEmittedExpression:
|
||||
result = reduceNode((<PartiallyEmittedExpression>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
default:
|
||||
const edgeTraversalPath = getNodeEdgeTraversal(kind);
|
||||
if (edgeTraversalPath) {
|
||||
for (const edge of edgeTraversalPath) {
|
||||
const value = (<MapLike<any>>node)[edge.name];
|
||||
if (value !== undefined) {
|
||||
result = isArray(value)
|
||||
? reduceNodes(<NodeArray<Node>>value, cbNodes, result)
|
||||
: cbNode(result, <Node>value);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -560,11 +512,9 @@ namespace ts {
|
||||
* @param visitor The callback used to visit the Node.
|
||||
* @param test A callback to execute to verify the Node is valid.
|
||||
* @param optional An optional value indicating whether the Node is itself optional.
|
||||
* @param lift An optional callback to execute to lift a NodeArrayNode into a valid Node.
|
||||
* @param lift An optional callback to execute to lift a NodeArray into a valid Node.
|
||||
*/
|
||||
export function visitNode<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional?: boolean, lift?: (node: NodeArray<Node>) => T): T;
|
||||
export function visitNode<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional: boolean, lift: (node: NodeArray<Node>) => T, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node): T;
|
||||
export function visitNode(node: Node, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional?: boolean, lift?: (node: Node[]) => Node, parenthesize?: (node: Node, parentNode: Node) => Node, parentNode?: Node): Node {
|
||||
export function visitNode<T extends Node>(node: T, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, optional?: boolean, lift?: (node: NodeArray<Node>) => T): T {
|
||||
if (node === undefined || visitor === undefined) {
|
||||
return node;
|
||||
}
|
||||
@@ -590,13 +540,9 @@ namespace ts {
|
||||
visitedNode = visited;
|
||||
}
|
||||
|
||||
if (parenthesize !== undefined) {
|
||||
visitedNode = parenthesize(visitedNode, parentNode);
|
||||
}
|
||||
|
||||
Debug.assertNode(visitedNode, test);
|
||||
aggregateTransformFlags(visitedNode);
|
||||
return visitedNode;
|
||||
return <T>visitedNode;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -608,14 +554,12 @@ namespace ts {
|
||||
* @param start An optional value indicating the starting offset at which to start visiting.
|
||||
* @param count An optional value indicating the maximum number of nodes to visit.
|
||||
*/
|
||||
export function visitNodes<T extends Node>(nodes: NodeArray<T>, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, start?: number, count?: number): NodeArray<T>;
|
||||
export function visitNodes<T extends Node>(nodes: NodeArray<T>, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, start: number, count: number, parenthesize: (node: Node, parentNode: Node) => Node, parentNode: Node): NodeArray<T>;
|
||||
export function visitNodes(nodes: NodeArray<Node>, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, start?: number, count?: number, parenthesize?: (node: Node, parentNode: Node) => Node, parentNode?: Node): NodeArray<Node> {
|
||||
export function visitNodes<T extends Node>(nodes: NodeArray<T>, visitor: (node: Node) => VisitResult<Node>, test: (node: Node) => boolean, start?: number, count?: number): NodeArray<T> {
|
||||
if (nodes === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let updated: NodeArray<Node>;
|
||||
let updated: NodeArray<T>;
|
||||
|
||||
// Ensure start and count have valid values
|
||||
const length = nodes.length;
|
||||
@@ -631,8 +575,7 @@ namespace ts {
|
||||
// If we are not visiting all of the original nodes, we must always create a new array.
|
||||
// Since this is a fragment of a node array, we do not copy over the previous location
|
||||
// and will only copy over `hasTrailingComma` if we are including the last element.
|
||||
updated = createNodeArray<Node>([], /*location*/ undefined,
|
||||
/*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length);
|
||||
updated = createNodeArray<T>([], /*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length);
|
||||
}
|
||||
|
||||
// Visit each original node.
|
||||
@@ -643,26 +586,21 @@ namespace ts {
|
||||
if (updated !== undefined || visited === undefined || visited !== node) {
|
||||
if (updated === undefined) {
|
||||
// Ensure we have a copy of `nodes`, up to the current index.
|
||||
updated = createNodeArray(nodes.slice(0, i), /*location*/ nodes, nodes.hasTrailingComma);
|
||||
updated = createNodeArray(nodes.slice(0, i), nodes.hasTrailingComma);
|
||||
setTextRange(updated, nodes);
|
||||
}
|
||||
if (visited) {
|
||||
if (isArray(visited)) {
|
||||
for (let visitedNode of visited) {
|
||||
visitedNode = parenthesize
|
||||
? parenthesize(visitedNode, parentNode)
|
||||
: visitedNode;
|
||||
for (const visitedNode of visited) {
|
||||
Debug.assertNode(visitedNode, test);
|
||||
aggregateTransformFlags(visitedNode);
|
||||
updated.push(visitedNode);
|
||||
updated.push(<T>visitedNode);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const visitedNode = parenthesize
|
||||
? parenthesize(visited, parentNode)
|
||||
: visited;
|
||||
Debug.assertNode(visitedNode, test);
|
||||
aggregateTransformFlags(visitedNode);
|
||||
updated.push(visitedNode);
|
||||
Debug.assertNode(visited, test);
|
||||
aggregateTransformFlags(visited);
|
||||
updated.push(<T>visited);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -679,10 +617,10 @@ namespace ts {
|
||||
context.startLexicalEnvironment();
|
||||
statements = visitNodes(statements, visitor, isStatement, start);
|
||||
if (ensureUseStrict && !startsWithUseStrict(statements)) {
|
||||
statements = createNodeArray([createStatement(createLiteral("use strict")), ...statements], statements);
|
||||
statements = setTextRange(createNodeArray([createStatement(createLiteral("use strict")), ...statements]), statements);
|
||||
}
|
||||
const declarations = context.endLexicalEnvironment();
|
||||
return createNodeArray(concatenate(statements, declarations), statements);
|
||||
return setTextRange(createNodeArray(concatenate(statements, declarations)), statements);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -751,6 +689,11 @@ namespace ts {
|
||||
return node;
|
||||
|
||||
// Names
|
||||
case SyntaxKind.QualifiedName:
|
||||
return updateQualifiedName(<QualifiedName>node,
|
||||
visitNode((<QualifiedName>node).left, visitor, isEntityName),
|
||||
visitNode((<QualifiedName>node).right, visitor, isIdentifier));
|
||||
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
return updateComputedPropertyName(<ComputedPropertyName>node,
|
||||
visitNode((<ComputedPropertyName>node).expression, visitor, isExpression));
|
||||
@@ -765,6 +708,10 @@ namespace ts {
|
||||
visitNode((<ParameterDeclaration>node).type, visitor, isTypeNode, /*optional*/ true),
|
||||
visitNode((<ParameterDeclaration>node).initializer, visitor, isExpression, /*optional*/ true));
|
||||
|
||||
case SyntaxKind.Decorator:
|
||||
return updateDecorator(<Decorator>node,
|
||||
visitNode((<Decorator>node).expression, visitor, isExpression));
|
||||
|
||||
// Type member
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
return updateProperty(<PropertyDeclaration>node,
|
||||
@@ -860,6 +807,11 @@ namespace ts {
|
||||
visitNode((<TaggedTemplateExpression>node).tag, visitor, isExpression),
|
||||
visitNode((<TaggedTemplateExpression>node).template, visitor, isTemplateLiteral));
|
||||
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
return updateTypeAssertion(<TypeAssertion>node,
|
||||
visitNode((<TypeAssertion>node).type, visitor, isTypeNode),
|
||||
visitNode((<TypeAssertion>node).expression, visitor, isExpression));
|
||||
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return updateParen(<ParenthesizedExpression>node,
|
||||
visitNode((<ParenthesizedExpression>node).expression, visitor, isExpression));
|
||||
@@ -942,6 +894,15 @@ namespace ts {
|
||||
visitNodes((<ExpressionWithTypeArguments>node).typeArguments, visitor, isTypeNode),
|
||||
visitNode((<ExpressionWithTypeArguments>node).expression, visitor, isExpression));
|
||||
|
||||
case SyntaxKind.AsExpression:
|
||||
return updateAsExpression(<AsExpression>node,
|
||||
visitNode((<AsExpression>node).expression, visitor, isExpression),
|
||||
visitNode((<AsExpression>node).type, visitor, isTypeNode));
|
||||
|
||||
case SyntaxKind.NonNullExpression:
|
||||
return updateNonNullExpression(<NonNullExpression>node,
|
||||
visitNode((<NonNullExpression>node).expression, visitor, isExpression));
|
||||
|
||||
// Misc
|
||||
case SyntaxKind.TemplateSpan:
|
||||
return updateTemplateSpan(<TemplateSpan>node,
|
||||
@@ -1063,10 +1024,35 @@ namespace ts {
|
||||
visitNodes((<ClassDeclaration>node).heritageClauses, visitor, isHeritageClause),
|
||||
visitNodes((<ClassDeclaration>node).members, visitor, isClassElement));
|
||||
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
return updateEnumDeclaration(<EnumDeclaration>node,
|
||||
visitNodes((<EnumDeclaration>node).decorators, visitor, isDecorator),
|
||||
visitNodes((<EnumDeclaration>node).modifiers, visitor, isModifier),
|
||||
visitNode((<EnumDeclaration>node).name, visitor, isIdentifier),
|
||||
visitNodes((<EnumDeclaration>node).members, visitor, isEnumMember));
|
||||
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return updateModuleDeclaration(<ModuleDeclaration>node,
|
||||
visitNodes((<ModuleDeclaration>node).decorators, visitor, isDecorator),
|
||||
visitNodes((<ModuleDeclaration>node).modifiers, visitor, isModifier),
|
||||
visitNode((<ModuleDeclaration>node).name, visitor, isIdentifier),
|
||||
visitNode((<ModuleDeclaration>node).body, visitor, isModuleBody));
|
||||
|
||||
case SyntaxKind.ModuleBlock:
|
||||
return updateModuleBlock(<ModuleBlock>node,
|
||||
visitNodes((<ModuleBlock>node).statements, visitor, isStatement));
|
||||
|
||||
case SyntaxKind.CaseBlock:
|
||||
return updateCaseBlock(<CaseBlock>node,
|
||||
visitNodes((<CaseBlock>node).clauses, visitor, isCaseOrDefaultClause));
|
||||
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return updateImportEqualsDeclaration(<ImportEqualsDeclaration>node,
|
||||
visitNodes((<ImportEqualsDeclaration>node).decorators, visitor, isDecorator),
|
||||
visitNodes((<ImportEqualsDeclaration>node).modifiers, visitor, isModifier),
|
||||
visitNode((<ImportEqualsDeclaration>node).name, visitor, isIdentifier),
|
||||
visitNode((<ImportEqualsDeclaration>node).moduleReference, visitor, isModuleReference));
|
||||
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
return updateImportDeclaration(<ImportDeclaration>node,
|
||||
visitNodes((<ImportDeclaration>node).decorators, visitor, isDecorator),
|
||||
@@ -1114,6 +1100,11 @@ namespace ts {
|
||||
visitNode((<ExportSpecifier>node).propertyName, visitor, isIdentifier, /*optional*/ true),
|
||||
visitNode((<ExportSpecifier>node).name, visitor, isIdentifier));
|
||||
|
||||
// Module references
|
||||
case SyntaxKind.ExternalModuleReference:
|
||||
return updateExternalModuleReference(<ExternalModuleReference>node,
|
||||
visitNode((<ExternalModuleReference>node).expression, visitor, isExpression));
|
||||
|
||||
// JSX
|
||||
case SyntaxKind.JsxElement:
|
||||
return updateJsxElement(<JsxElement>node,
|
||||
@@ -1183,10 +1174,16 @@ namespace ts {
|
||||
visitNode((<ShorthandPropertyAssignment>node).objectAssignmentInitializer, visitor, isExpression));
|
||||
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
return updateSpreadAssignment(node as SpreadAssignment,
|
||||
visitNode((node as SpreadAssignment).expression, visitor, isExpression));
|
||||
return updateSpreadAssignment(<SpreadAssignment>node,
|
||||
visitNode((<SpreadAssignment>node).expression, visitor, isExpression));
|
||||
|
||||
// Top-level nodes
|
||||
// Enum
|
||||
case SyntaxKind.EnumMember:
|
||||
return updateEnumMember(<EnumMember>node,
|
||||
visitNode((<EnumMember>node).name, visitor, isPropertyName),
|
||||
visitNode((<EnumMember>node).initializer, visitor, isExpression, /*optional*/ true));
|
||||
|
||||
// Top-level nodes
|
||||
case SyntaxKind.SourceFile:
|
||||
return updateSourceFileNode(<SourceFile>node,
|
||||
visitLexicalEnvironment((<SourceFile>node).statements, visitor, context));
|
||||
@@ -1197,30 +1194,8 @@ namespace ts {
|
||||
visitNode((<PartiallyEmittedExpression>node).expression, visitor, isExpression));
|
||||
|
||||
default:
|
||||
let updated: Node & MapLike<any>;
|
||||
const edgeTraversalPath = getNodeEdgeTraversal(kind);
|
||||
if (edgeTraversalPath) {
|
||||
for (const edge of edgeTraversalPath) {
|
||||
const value = <Node | NodeArray<Node>>(<Node & MapLike<any>>node)[edge.name];
|
||||
if (value !== undefined) {
|
||||
const visited = isArray(value)
|
||||
? visitNodes(value, visitor, edge.test, 0, value.length, edge.parenthesize, node)
|
||||
: visitNode(value, visitor, edge.test, edge.optional, edge.lift, edge.parenthesize, node);
|
||||
if (updated !== undefined || visited !== value) {
|
||||
if (updated === undefined) {
|
||||
updated = getMutableClone(node);
|
||||
}
|
||||
if (visited !== value) {
|
||||
updated[edge.name] = visited;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return updated ? updateNode(updated, node) : node;
|
||||
return node;
|
||||
}
|
||||
|
||||
// return node;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1236,7 +1211,7 @@ namespace ts {
|
||||
return statements;
|
||||
}
|
||||
return isNodeArray(statements)
|
||||
? createNodeArray(concatenate(statements, declarations), statements)
|
||||
? setTextRange(createNodeArray(concatenate(statements, declarations)), statements)
|
||||
: addRange(statements, declarations);
|
||||
}
|
||||
|
||||
@@ -1260,13 +1235,19 @@ namespace ts {
|
||||
export function mergeFunctionBodyLexicalEnvironment(body: ConciseBody, declarations: Statement[]): ConciseBody {
|
||||
if (body && declarations !== undefined && declarations.length > 0) {
|
||||
if (isBlock(body)) {
|
||||
return updateBlock(body, createNodeArray(concatenate(body.statements, declarations), body.statements));
|
||||
return updateBlock(body, setTextRange(createNodeArray(concatenate(body.statements, declarations)), body.statements));
|
||||
}
|
||||
else {
|
||||
return createBlock(
|
||||
createNodeArray([createReturn(body, /*location*/ body), ...declarations], body),
|
||||
/*location*/ body,
|
||||
/*multiLine*/ true);
|
||||
return setTextRange(
|
||||
createBlock(
|
||||
setTextRange(
|
||||
createNodeArray([setTextRange(createReturn(body), body), ...declarations]),
|
||||
body
|
||||
),
|
||||
/*multiLine*/ true
|
||||
),
|
||||
/*location*/ body
|
||||
);
|
||||
}
|
||||
}
|
||||
return body;
|
||||
|
||||
+125
-36
@@ -183,7 +183,7 @@ namespace FourSlash {
|
||||
|
||||
// The current caret position in the active file
|
||||
public currentCaretPosition = 0;
|
||||
public lastKnownMarker: string = "";
|
||||
public lastKnownMarker = "";
|
||||
|
||||
// The file that's currently 'opened'
|
||||
public activeFile: FourSlashFile;
|
||||
@@ -263,6 +263,20 @@ namespace FourSlash {
|
||||
// Create map between fileName and its content for easily looking up when resolveReference flag is specified
|
||||
this.inputFiles.set(file.fileName, file.content);
|
||||
if (ts.getBaseFileName(file.fileName).toLowerCase() === "tsconfig.json") {
|
||||
const configJson = ts.parseConfigFileTextToJson(file.fileName, file.content);
|
||||
if (configJson.config === undefined) {
|
||||
throw new Error(`Failed to parse test tsconfig.json: ${configJson.error.messageText}`);
|
||||
}
|
||||
|
||||
// Extend our existing compiler options so that we can also support tsconfig only options
|
||||
if (configJson.config.compilerOptions) {
|
||||
const baseDirectory = ts.normalizePath(ts.getDirectoryPath(file.fileName));
|
||||
const tsConfig = ts.convertCompilerOptionsFromJson(configJson.config.compilerOptions, baseDirectory, file.fileName);
|
||||
|
||||
if (!tsConfig.errors || !tsConfig.errors.length) {
|
||||
compilationOptions = ts.extend(compilationOptions, tsConfig.options);
|
||||
}
|
||||
}
|
||||
configFileName = file.fileName;
|
||||
}
|
||||
|
||||
@@ -452,7 +466,8 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
private messageAtLastKnownMarker(message: string) {
|
||||
return "Marker: " + this.lastKnownMarker + "\n" + message;
|
||||
const locationDescription = this.lastKnownMarker ? this.lastKnownMarker : this.getLineColStringAtPosition(this.currentCaretPosition);
|
||||
return `At ${locationDescription}: ${message}`;
|
||||
}
|
||||
|
||||
private assertionMessageAtLastKnownMarker(msg: string) {
|
||||
@@ -562,7 +577,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
public verifyGoToDefinitionIs(endMarker: string | string[]) {
|
||||
this.verifyGoToXWorker(endMarker instanceof Array ? endMarker : [endMarker], () => this.getGoToDefinition());
|
||||
this.verifyGoToXWorker(toArray(endMarker), () => this.getGoToDefinition());
|
||||
}
|
||||
|
||||
public verifyGoToDefinition(arg0: any, endMarkerNames?: string | string[]) {
|
||||
@@ -582,7 +597,7 @@ namespace FourSlash {
|
||||
if (endMarkerNames) {
|
||||
this.verifyGoToXPlain(arg0, endMarkerNames, getDefs);
|
||||
}
|
||||
else if (arg0 instanceof Array) {
|
||||
else if (ts.isArray(arg0)) {
|
||||
const pairs: [string | string[], string | string[]][] = arg0;
|
||||
for (const [start, end] of pairs) {
|
||||
this.verifyGoToXPlain(start, end, getDefs);
|
||||
@@ -599,13 +614,8 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
private verifyGoToXPlain(startMarkerNames: string | string[], endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | undefined) {
|
||||
if (startMarkerNames instanceof Array) {
|
||||
for (const start of startMarkerNames) {
|
||||
this.verifyGoToXSingle(start, endMarkerNames, getDefs);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.verifyGoToXSingle(startMarkerNames, endMarkerNames, getDefs);
|
||||
for (const start of toArray(startMarkerNames)) {
|
||||
this.verifyGoToXSingle(start, endMarkerNames, getDefs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,7 +627,7 @@ namespace FourSlash {
|
||||
|
||||
private verifyGoToXSingle(startMarkerName: string, endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | undefined) {
|
||||
this.goToMarker(startMarkerName);
|
||||
this.verifyGoToXWorker(endMarkerNames instanceof Array ? endMarkerNames : [endMarkerNames], getDefs);
|
||||
this.verifyGoToXWorker(toArray(endMarkerNames), getDefs);
|
||||
}
|
||||
|
||||
private verifyGoToXWorker(endMarkers: string[], getDefs: () => ts.DefinitionInfo[] | undefined) {
|
||||
@@ -899,8 +909,74 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public verifyRangesWithSameTextReferenceEachOther() {
|
||||
this.rangesByText().forEach(ranges => this.verifyRangesReferenceEachOther(ranges));
|
||||
public verifyReferenceGroups(startRanges: Range | Range[], parts: Array<{ definition: string, ranges: Range[] }>): void {
|
||||
interface ReferenceJson { definition: string; ranges: ts.ReferenceEntry[]; }
|
||||
type ReferencesJson = ReferenceJson[];
|
||||
const fullExpected = parts.map<ReferenceJson>(({ definition, ranges }) => ({ definition, ranges: ranges.map(rangeToReferenceEntry) }));
|
||||
|
||||
for (const startRange of toArray(startRanges)) {
|
||||
this.goToRangeStart(startRange);
|
||||
const fullActual = this.findReferencesAtCaret().map<ReferenceJson>(({ definition, references }) => ({
|
||||
definition: definition.displayParts.map(d => d.text).join(""),
|
||||
ranges: references
|
||||
}));
|
||||
this.assertObjectsEqual<ReferencesJson>(fullActual, fullExpected);
|
||||
}
|
||||
|
||||
function rangeToReferenceEntry(r: Range) {
|
||||
let { isWriteAccess, isDefinition } = (r.marker && r.marker.data) || { isWriteAccess: false, isDefinition: false };
|
||||
isWriteAccess = !!isWriteAccess; isDefinition = !!isDefinition;
|
||||
return { fileName: r.fileName, textSpan: { start: r.start, length: r.end - r.start }, isWriteAccess, isDefinition }
|
||||
}
|
||||
}
|
||||
|
||||
public verifyNoReferences(markerNameOrRange?: string | Range) {
|
||||
if (markerNameOrRange) {
|
||||
if (typeof markerNameOrRange === "string") {
|
||||
this.goToMarker(markerNameOrRange);
|
||||
}
|
||||
else {
|
||||
this.goToRangeStart(markerNameOrRange);
|
||||
}
|
||||
}
|
||||
|
||||
const refs = this.getReferencesAtCaret();
|
||||
if (refs && refs.length) {
|
||||
console.log(refs);
|
||||
this.raiseError("Expected getReferences to fail");
|
||||
}
|
||||
}
|
||||
|
||||
public verifySingleReferenceGroup(definition: string, ranges?: Range[]) {
|
||||
ranges = ranges || this.getRanges();
|
||||
this.verifyReferenceGroups(ranges, [{ definition, ranges }]);
|
||||
}
|
||||
|
||||
private assertObjectsEqual<T>(fullActual: T, fullExpected: T, msgPrefix = ""): void {
|
||||
const recur = <U>(actual: U, expected: U, path: string) => {
|
||||
const fail = (msg: string) => {
|
||||
console.log("Expected:", stringify(fullExpected));
|
||||
console.log("Actual: ", stringify(fullActual));
|
||||
this.raiseError(`${msgPrefix}At ${path}: ${msg}`);
|
||||
};
|
||||
|
||||
for (const key in actual) if (ts.hasProperty(actual as any, key)) {
|
||||
const ak = actual[key], ek = expected[key];
|
||||
if (typeof ak === "object" && typeof ek === "object") {
|
||||
recur(ak, ek, path ? path + "." + key : key);
|
||||
}
|
||||
else if (ak !== ek) {
|
||||
fail(`Expected '${key}' to be '${ek}', got '${ak}'`);
|
||||
}
|
||||
}
|
||||
for (const key in expected) if (ts.hasProperty(expected as any, key)) {
|
||||
if (!ts.hasProperty(actual as any, key)) {
|
||||
fail(`${msgPrefix}Missing property '${key}'`);
|
||||
}
|
||||
}
|
||||
};
|
||||
recur(fullActual, fullExpected, "");
|
||||
|
||||
}
|
||||
|
||||
public verifyDisplayPartsOfReferencedSymbol(expected: ts.SymbolDisplayPart[]) {
|
||||
@@ -974,7 +1050,7 @@ namespace FourSlash {
|
||||
public verifyQuickInfos(namesAndTexts: { [name: string]: string | [string, string] }) {
|
||||
for (const name in namesAndTexts) if (ts.hasProperty(namesAndTexts, name)) {
|
||||
const text = namesAndTexts[name];
|
||||
if (text instanceof Array) {
|
||||
if (ts.isArray(text)) {
|
||||
assert(text.length === 2);
|
||||
const [expectedText, expectedDocumentation] = text;
|
||||
this.verifyQuickInfoAt(name, expectedText, expectedDocumentation);
|
||||
@@ -1411,13 +1487,6 @@ namespace FourSlash {
|
||||
Harness.IO.log(membersString);
|
||||
}
|
||||
|
||||
public printReferences() {
|
||||
const references = this.getReferencesAtCaret();
|
||||
ts.forEach(references, entry => {
|
||||
Harness.IO.log(stringify(entry));
|
||||
});
|
||||
}
|
||||
|
||||
public printContext() {
|
||||
ts.forEach(this.languageServiceAdapterHost.getFilenames(), Harness.IO.log);
|
||||
}
|
||||
@@ -2053,7 +2122,7 @@ namespace FourSlash {
|
||||
* Because codefixes are only applied on the working file, it is unsafe
|
||||
* to apply this more than once (consider a refactoring across files).
|
||||
*/
|
||||
public verifyRangeAfterCodeFix(expectedText: string, errorCode?: number) {
|
||||
public verifyRangeAfterCodeFix(expectedText: string, errorCode?: number, includeWhiteSpace?: boolean) {
|
||||
const ranges = this.getRanges();
|
||||
if (ranges.length !== 1) {
|
||||
this.raiseError("Exactly one range should be specified in the testfile.");
|
||||
@@ -2065,7 +2134,11 @@ namespace FourSlash {
|
||||
|
||||
const actualText = this.rangeText(ranges[0]);
|
||||
|
||||
if (this.removeWhitespace(actualText) !== this.removeWhitespace(expectedText)) {
|
||||
const result = includeWhiteSpace
|
||||
? actualText === expectedText
|
||||
: this.removeWhitespace(actualText) === this.removeWhitespace(expectedText)
|
||||
|
||||
if (!result) {
|
||||
this.raiseError(`Actual text doesn't match expected text. Actual:\n'${actualText}'\nExpected:\n'${expectedText}'`);
|
||||
}
|
||||
}
|
||||
@@ -2095,10 +2168,18 @@ namespace FourSlash {
|
||||
* @param fileName Path to file where error should be retrieved from.
|
||||
*/
|
||||
private getCodeFixActions(fileName: string, errorCode?: number): ts.CodeAction[] {
|
||||
const diagnostics: ts.Diagnostic[] = this.getDiagnostics(fileName);
|
||||
const diagnosticsForCodeFix = this.getDiagnostics(fileName).map(diagnostic => {
|
||||
return {
|
||||
start: diagnostic.start,
|
||||
length: diagnostic.length,
|
||||
code: diagnostic.code
|
||||
}
|
||||
});
|
||||
const dedupedDiagnositcs = ts.deduplicate(diagnosticsForCodeFix, ts.equalOwnProperties);
|
||||
|
||||
let actions: ts.CodeAction[] = undefined;
|
||||
for (const diagnostic of diagnostics) {
|
||||
|
||||
for (const diagnostic of dedupedDiagnositcs) {
|
||||
|
||||
if (errorCode && errorCode !== diagnostic.code) {
|
||||
continue;
|
||||
@@ -3082,6 +3163,10 @@ ${code}
|
||||
}
|
||||
return ts.arrayFrom(set.keys());
|
||||
}
|
||||
|
||||
function toArray<T>(x: T | T[]): T[] {
|
||||
return ts.isArray(x) ? x : [x];
|
||||
}
|
||||
}
|
||||
|
||||
namespace FourSlashInterface {
|
||||
@@ -3346,6 +3431,18 @@ namespace FourSlashInterface {
|
||||
this.state.verifyReferencesOf(start, references);
|
||||
}
|
||||
|
||||
public referenceGroups(startRanges: FourSlash.Range[], parts: Array<{ definition: string, ranges: FourSlash.Range[] }>) {
|
||||
this.state.verifyReferenceGroups(startRanges, parts);
|
||||
}
|
||||
|
||||
public noReferences(markerNameOrRange?: string | FourSlash.Range) {
|
||||
this.state.verifyNoReferences(markerNameOrRange);
|
||||
}
|
||||
|
||||
public singleReferenceGroup(definition: string, ranges?: FourSlash.Range[]) {
|
||||
this.state.verifySingleReferenceGroup(definition, ranges);
|
||||
}
|
||||
|
||||
public rangesReferenceEachOther(ranges?: FourSlash.Range[]) {
|
||||
this.state.verifyRangesReferenceEachOther(ranges);
|
||||
}
|
||||
@@ -3354,10 +3451,6 @@ namespace FourSlashInterface {
|
||||
this.state.verifyDisplayPartsOfReferencedSymbol(expected);
|
||||
}
|
||||
|
||||
public rangesWithSameTextReferenceEachOther() {
|
||||
this.state.verifyRangesWithSameTextReferenceEachOther();
|
||||
}
|
||||
|
||||
public currentParameterHelpArgumentNameIs(name: string) {
|
||||
this.state.verifyCurrentParameterHelpName(name);
|
||||
}
|
||||
@@ -3442,8 +3535,8 @@ namespace FourSlashInterface {
|
||||
this.DocCommentTemplate(/*expectedText*/ undefined, /*expectedOffset*/ undefined, /*empty*/ true);
|
||||
}
|
||||
|
||||
public rangeAfterCodeFix(expectedText: string, errorCode?: number): void {
|
||||
this.state.verifyRangeAfterCodeFix(expectedText, errorCode);
|
||||
public rangeAfterCodeFix(expectedText: string, errorCode?: number, includeWhiteSpace?: boolean): void {
|
||||
this.state.verifyRangeAfterCodeFix(expectedText, errorCode, includeWhiteSpace);
|
||||
}
|
||||
|
||||
public importFixAtPosition(expectedTextArray: string[], errorCode?: number): void {
|
||||
@@ -3660,10 +3753,6 @@ namespace FourSlashInterface {
|
||||
this.state.printNavigationBar();
|
||||
}
|
||||
|
||||
public printReferences() {
|
||||
this.state.printReferences();
|
||||
}
|
||||
|
||||
public printContext() {
|
||||
this.state.printContext();
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
namespace Harness.LanguageService {
|
||||
export class ScriptInfo {
|
||||
public version: number = 1;
|
||||
public version = 1;
|
||||
public editRanges: { length: number; textChangeRange: ts.TextChangeRange; }[] = [];
|
||||
private lineMap: number[] = undefined;
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace Harness.LanguageService {
|
||||
protected virtualFileSystem: Utils.VirtualFileSystem = new Utils.VirtualFileSystem(virtualFileSystemRoot, /*useCaseSensitiveFilenames*/false);
|
||||
|
||||
constructor(protected cancellationToken = DefaultHostCancellationToken.Instance,
|
||||
protected settings = ts.getDefaultCompilerOptions()) {
|
||||
protected settings = ts.getDefaultCompilerOptions()) {
|
||||
}
|
||||
|
||||
public getNewLine(): string {
|
||||
@@ -135,7 +135,7 @@ namespace Harness.LanguageService {
|
||||
|
||||
public getFilenames(): string[] {
|
||||
const fileNames: string[] = [];
|
||||
for (const virtualEntry of this.virtualFileSystem.getAllFileEntries()){
|
||||
for (const virtualEntry of this.virtualFileSystem.getAllFileEntries()) {
|
||||
const scriptInfo = virtualEntry.content;
|
||||
if (scriptInfo.isRootFile) {
|
||||
// only include root files here
|
||||
@@ -211,8 +211,8 @@ namespace Harness.LanguageService {
|
||||
readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[] {
|
||||
return ts.matchFiles(path, extensions, exclude, include,
|
||||
/*useCaseSensitiveFileNames*/false,
|
||||
this.getCurrentDirectory(),
|
||||
(p) => this.virtualFileSystem.getAccessibleFileSystemEntries(p));
|
||||
this.getCurrentDirectory(),
|
||||
(p) => this.virtualFileSystem.getAccessibleFileSystemEntries(p));
|
||||
}
|
||||
readFile(path: string): string {
|
||||
const snapshot = this.getScriptSnapshot(path);
|
||||
@@ -594,7 +594,7 @@ namespace Harness.LanguageService {
|
||||
class SessionServerHost implements ts.server.ServerHost, ts.server.Logger {
|
||||
args: string[] = [];
|
||||
newLine: string;
|
||||
useCaseSensitiveFileNames: boolean = false;
|
||||
useCaseSensitiveFileNames = false;
|
||||
|
||||
constructor(private host: NativeLanguageServiceHost) {
|
||||
this.newLine = this.host.getNewLine();
|
||||
@@ -724,6 +724,87 @@ namespace Harness.LanguageService {
|
||||
createHash(s: string) {
|
||||
return s;
|
||||
}
|
||||
|
||||
require(_initialDir: string, _moduleName: string): ts.server.RequireResult {
|
||||
switch (_moduleName) {
|
||||
// Adds to the Quick Info a fixed string and a string from the config file
|
||||
// and replaces the first display part
|
||||
case "quickinfo-augmeneter":
|
||||
return {
|
||||
module: () => ({
|
||||
create(info: ts.server.PluginCreateInfo) {
|
||||
const proxy = makeDefaultProxy(info);
|
||||
const langSvc: any = info.languageService;
|
||||
proxy.getQuickInfoAtPosition = function () {
|
||||
const parts = langSvc.getQuickInfoAtPosition.apply(langSvc, arguments);
|
||||
if (parts.displayParts.length > 0) {
|
||||
parts.displayParts[0].text = "Proxied";
|
||||
}
|
||||
parts.displayParts.push({ text: info.config.message, kind: "punctuation" });
|
||||
return parts;
|
||||
};
|
||||
|
||||
return proxy;
|
||||
}
|
||||
}),
|
||||
error: undefined
|
||||
};
|
||||
|
||||
// Throws during initialization
|
||||
case "create-thrower":
|
||||
return {
|
||||
module: () => ({
|
||||
create() {
|
||||
throw new Error("I am not a well-behaved plugin");
|
||||
}
|
||||
}),
|
||||
error: undefined
|
||||
};
|
||||
|
||||
// Adds another diagnostic
|
||||
case "diagnostic-adder":
|
||||
return {
|
||||
module: () => ({
|
||||
create(info: ts.server.PluginCreateInfo) {
|
||||
const proxy = makeDefaultProxy(info);
|
||||
proxy.getSemanticDiagnostics = function (filename: string) {
|
||||
const prev = info.languageService.getSemanticDiagnostics(filename);
|
||||
const sourceFile: ts.SourceFile = info.languageService.getSourceFile(filename);
|
||||
prev.push({
|
||||
category: ts.DiagnosticCategory.Warning,
|
||||
file: sourceFile,
|
||||
code: 9999,
|
||||
length: 3,
|
||||
messageText: `Plugin diagnostic`,
|
||||
start: 0
|
||||
});
|
||||
return prev;
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
}),
|
||||
error: undefined
|
||||
};
|
||||
|
||||
default:
|
||||
return {
|
||||
module: undefined,
|
||||
error: "Could not resolve module"
|
||||
};
|
||||
}
|
||||
|
||||
function makeDefaultProxy(info: ts.server.PluginCreateInfo) {
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
const proxy = Object.create(null);
|
||||
const langSvc: any = info.languageService;
|
||||
for (const k of Object.keys(langSvc)) {
|
||||
proxy[k] = function () {
|
||||
return langSvc[k].apply(langSvc, arguments);
|
||||
};
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class ServerLanguageServiceAdapter implements LanguageServiceAdapter {
|
||||
@@ -738,7 +819,7 @@ namespace Harness.LanguageService {
|
||||
// host to answer server queries about files on disk
|
||||
const serverHost = new SessionServerHost(clientHost);
|
||||
const server = new ts.server.Session(serverHost,
|
||||
{ isCancellationRequested: () => false },
|
||||
ts.server.nullCancellationToken,
|
||||
/*useOneInferredProject*/ false,
|
||||
/*typingsInstaller*/ undefined,
|
||||
Utils.byteLength,
|
||||
|
||||
@@ -118,6 +118,7 @@
|
||||
"./unittests/initializeTSConfig.ts",
|
||||
"./unittests/compileOnSave.ts",
|
||||
"./unittests/typingsInstaller.ts",
|
||||
"./unittests/projectErrors.ts"
|
||||
"./unittests/projectErrors.ts",
|
||||
"./unittests/printer.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
namespace ts.projectSystem {
|
||||
import CommandNames = server.CommandNames;
|
||||
const nullCancellationToken = server.nullCancellationToken;
|
||||
|
||||
function createTestTypingsInstaller(host: server.ServerHost) {
|
||||
return new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host);
|
||||
@@ -520,7 +521,7 @@ namespace ts.projectSystem {
|
||||
|
||||
const expectedEmittedFileName = "/a/b/f1.js";
|
||||
assert.isTrue(host.fileExists(expectedEmittedFileName));
|
||||
assert.equal(host.readFile(expectedEmittedFileName), `"use strict";\r\nfunction Foo() { return 10; }\r\nexports.Foo = Foo;\r\n`);
|
||||
assert.equal(host.readFile(expectedEmittedFileName), `"use strict";\r\nexports.__esModule = true;\r\nfunction Foo() { return 10; }\r\nexports.Foo = Foo;\r\n`);
|
||||
});
|
||||
|
||||
it("shoud not emit js files in external projects", () => {
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/// <reference path="..\..\compiler\emitter.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
|
||||
namespace ts {
|
||||
describe("PrinterAPI", () => {
|
||||
function makePrintsCorrectly(prefix: string) {
|
||||
return function printsCorrectly(name: string, options: PrinterOptions, printCallback: (printer: Printer) => string) {
|
||||
it(name, () => {
|
||||
Harness.Baseline.runBaseline(`printerApi/${prefix}.${name}.js`, () =>
|
||||
printCallback(createPrinter({ newLine: NewLineKind.CarriageReturnLineFeed, ...options })));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
describe("printFile", () => {
|
||||
const printsCorrectly = makePrintsCorrectly("printsFileCorrectly");
|
||||
const sourceFile = createSourceFile("source.ts", `
|
||||
interface A<T> {
|
||||
// comment1
|
||||
readonly prop?: T;
|
||||
|
||||
// comment2
|
||||
method(): void;
|
||||
|
||||
// comment3
|
||||
new <T>(): A<T>;
|
||||
|
||||
// comment4
|
||||
<T>(): A<T>;
|
||||
}
|
||||
|
||||
// comment5
|
||||
type B = number | string | object;
|
||||
type C = A<number> & { x: string; }; // comment6
|
||||
|
||||
// comment7
|
||||
enum E1 {
|
||||
// comment8
|
||||
first
|
||||
}
|
||||
|
||||
const enum E2 {
|
||||
second
|
||||
}
|
||||
|
||||
// comment9
|
||||
console.log(1 + 2);
|
||||
`, ScriptTarget.ES2015);
|
||||
|
||||
printsCorrectly("default", {}, printer => printer.printFile(sourceFile));
|
||||
printsCorrectly("removeComments", { removeComments: true }, printer => printer.printFile(sourceFile));
|
||||
});
|
||||
|
||||
describe("printBundle", () => {
|
||||
const printsCorrectly = makePrintsCorrectly("printsBundleCorrectly");
|
||||
const bundle = createBundle([
|
||||
createSourceFile("a.ts", `
|
||||
/*! [a.ts] */
|
||||
|
||||
// comment0
|
||||
const a = 1;
|
||||
`, ScriptTarget.ES2015),
|
||||
createSourceFile("b.ts", `
|
||||
/*! [b.ts] */
|
||||
|
||||
// comment1
|
||||
const b = 2;
|
||||
`, ScriptTarget.ES2015)
|
||||
]);
|
||||
printsCorrectly("default", {}, printer => printer.printBundle(bundle));
|
||||
printsCorrectly("removeComments", { removeComments: true }, printer => printer.printBundle(bundle));
|
||||
});
|
||||
|
||||
describe("printNode", () => {
|
||||
const printsCorrectly = makePrintsCorrectly("printsNodeCorrectly");
|
||||
const sourceFile = createSourceFile("source.ts", "", ScriptTarget.ES2015);
|
||||
const syntheticNode = createClassDeclaration(
|
||||
undefined,
|
||||
undefined,
|
||||
/*name*/ createIdentifier("C"),
|
||||
undefined,
|
||||
undefined,
|
||||
createNodeArray([
|
||||
createProperty(
|
||||
undefined,
|
||||
createNodeArray([createToken(SyntaxKind.PublicKeyword)]),
|
||||
createIdentifier("prop"),
|
||||
undefined,
|
||||
undefined,
|
||||
undefined
|
||||
)
|
||||
])
|
||||
);
|
||||
printsCorrectly("class", {}, printer => printer.printNode(EmitHint.Unspecified, syntheticNode, sourceFile));
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -27,7 +27,7 @@ namespace ts.server {
|
||||
clearImmediate: noop,
|
||||
createHash: s => s
|
||||
};
|
||||
const nullCancellationToken: HostCancellationToken = { isCancellationRequested: () => false };
|
||||
|
||||
const mockLogger: Logger = {
|
||||
close: noop,
|
||||
hasLevel(): boolean { return false; },
|
||||
|
||||
@@ -34,10 +34,6 @@ namespace ts.projectSystem {
|
||||
getLogFileName: (): string => undefined
|
||||
};
|
||||
|
||||
export const nullCancellationToken: HostCancellationToken = {
|
||||
isCancellationRequested: () => false
|
||||
};
|
||||
|
||||
export const { content: libFileContent } = Harness.getDefaultLibraryFile(Harness.IO);
|
||||
export const libFile: FileOrFolder = {
|
||||
path: "/a/lib/lib.d.ts",
|
||||
@@ -158,17 +154,33 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
class TestSession extends server.Session {
|
||||
private seq = 0;
|
||||
|
||||
getProjectService() {
|
||||
return this.projectService;
|
||||
}
|
||||
|
||||
public getSeq() {
|
||||
return this.seq;
|
||||
}
|
||||
|
||||
public getNextSeq() {
|
||||
return this.seq + 1;
|
||||
}
|
||||
|
||||
public executeCommandSeq<T extends server.protocol.Request>(request: Partial<T>) {
|
||||
this.seq++;
|
||||
request.seq = this.seq;
|
||||
request.type = "request";
|
||||
return this.executeCommand(<T>request);
|
||||
}
|
||||
};
|
||||
|
||||
export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler) {
|
||||
export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler, cancellationToken?: server.ServerCancellationToken) {
|
||||
if (typingsInstaller === undefined) {
|
||||
typingsInstaller = new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host);
|
||||
}
|
||||
|
||||
return new TestSession(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler);
|
||||
return new TestSession(host, cancellationToken || server.nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler);
|
||||
}
|
||||
|
||||
export interface CreateProjectServiceParameters {
|
||||
@@ -191,7 +203,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
}
|
||||
export function createProjectService(host: server.ServerHost, parameters: CreateProjectServiceParameters = {}) {
|
||||
const cancellationToken = parameters.cancellationToken || nullCancellationToken;
|
||||
const cancellationToken = parameters.cancellationToken || server.nullCancellationToken;
|
||||
const logger = parameters.logger || nullLogger;
|
||||
const useSingleInferredProject = parameters.useSingleInferredProject !== undefined ? parameters.useSingleInferredProject : false;
|
||||
return new TestProjectService(host, logger, cancellationToken, useSingleInferredProject, parameters.typingsInstaller, parameters.eventHandler);
|
||||
@@ -328,6 +340,8 @@ namespace ts.projectSystem {
|
||||
export class TestServerHost implements server.ServerHost {
|
||||
args: string[] = [];
|
||||
|
||||
private readonly output: string[] = [];
|
||||
|
||||
private fs: ts.FileMap<FSEntry>;
|
||||
private getCanonicalFileName: (s: string) => string;
|
||||
private toPath: (f: string) => Path;
|
||||
@@ -477,6 +491,10 @@ namespace ts.projectSystem {
|
||||
this.timeoutCallbacks.invoke();
|
||||
}
|
||||
|
||||
runQueuedImmediateCallbacks() {
|
||||
this.immediateCallbacks.invoke();
|
||||
}
|
||||
|
||||
setImmediate(callback: TimeOutCallback, _time: number, ...args: any[]) {
|
||||
return this.immediateCallbacks.register(callback, args);
|
||||
}
|
||||
@@ -509,7 +527,17 @@ namespace ts.projectSystem {
|
||||
this.reloadFS(filesOrFolders);
|
||||
}
|
||||
|
||||
write() { }
|
||||
write(message: string) {
|
||||
this.output.push(message);
|
||||
}
|
||||
|
||||
getOutput(): ReadonlyArray<string> {
|
||||
return this.output;
|
||||
}
|
||||
|
||||
clearOutput() {
|
||||
this.output.length = 0;
|
||||
}
|
||||
|
||||
readonly readFile = (s: string) => (<File>this.fs.get(this.toPath(s))).content;
|
||||
readonly resolvePath = (s: string) => s;
|
||||
@@ -1589,6 +1617,41 @@ namespace ts.projectSystem {
|
||||
checkProjectActualFiles(projectService.inferredProjects[1], [file2.path]);
|
||||
});
|
||||
|
||||
it ("loading files with correct priority", () => {
|
||||
const f1 = {
|
||||
path: "/a/main.ts",
|
||||
content: "let x = 1"
|
||||
};
|
||||
const f2 = {
|
||||
path: "/a/main.js",
|
||||
content: "var y = 1"
|
||||
};
|
||||
const config = {
|
||||
path: "/a/tsconfig.json",
|
||||
content: JSON.stringify({
|
||||
compilerOptions: { allowJs: true }
|
||||
})
|
||||
};
|
||||
const host = createServerHost([f1, f2, config]);
|
||||
const projectService = createProjectService(host);
|
||||
projectService.setHostConfiguration({
|
||||
extraFileExtensions: [
|
||||
{ extension: ".js", isMixedContent: false },
|
||||
{ extension: ".html", isMixedContent: true }
|
||||
]
|
||||
});
|
||||
projectService.openClientFile(f1.path);
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [ f1.path ]);
|
||||
|
||||
projectService.closeClientFile(f1.path);
|
||||
|
||||
projectService.openClientFile(f2.path);
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1, inferredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [ f1.path ]);
|
||||
checkProjectActualFiles(projectService.inferredProjects[0], [ f2.path ]);
|
||||
});
|
||||
|
||||
it("tsconfig script block support", () => {
|
||||
const file1 = {
|
||||
path: "/a/b/f1.ts",
|
||||
@@ -1650,6 +1713,115 @@ namespace ts.projectSystem {
|
||||
assert(completions && completions.entries[0].name !== "hello", `unexpected hello entry in completion list`);
|
||||
});
|
||||
|
||||
it("no tsconfig script block diagnostic errors", () => {
|
||||
|
||||
// #1. Ensure no diagnostic errors when allowJs is true
|
||||
const file1 = {
|
||||
path: "/a/b/f1.ts",
|
||||
content: ` `
|
||||
};
|
||||
const file2 = {
|
||||
path: "/a/b/f2.html",
|
||||
content: `var hello = "hello";`
|
||||
};
|
||||
const config1 = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: JSON.stringify({ compilerOptions: { allowJs: true } })
|
||||
};
|
||||
|
||||
let host = createServerHost([file1, file2, config1, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") });
|
||||
let session = createSession(host);
|
||||
|
||||
// Specify .html extension as mixed content in a configure host request
|
||||
const extraFileExtensions = [{ extension: ".html", scriptKind: ScriptKind.JS, isMixedContent: true }];
|
||||
const configureHostRequest = makeSessionRequest<protocol.ConfigureRequestArguments>(CommandNames.Configure, { extraFileExtensions });
|
||||
session.executeCommand(configureHostRequest).response;
|
||||
|
||||
openFilesForSession([file1], session);
|
||||
let projectService = session.getProjectService();
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
|
||||
let diagnostics = projectService.configuredProjects[0].getLanguageService().getCompilerOptionsDiagnostics();
|
||||
assert.deepEqual(diagnostics, []);
|
||||
|
||||
// #2. Ensure no errors when allowJs is false
|
||||
const config2 = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: JSON.stringify({ compilerOptions: { allowJs: false } })
|
||||
};
|
||||
|
||||
host = createServerHost([file1, file2, config2, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") });
|
||||
session = createSession(host);
|
||||
|
||||
session.executeCommand(configureHostRequest).response;
|
||||
|
||||
openFilesForSession([file1], session);
|
||||
projectService = session.getProjectService();
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
|
||||
diagnostics = projectService.configuredProjects[0].getLanguageService().getCompilerOptionsDiagnostics();
|
||||
assert.deepEqual(diagnostics, []);
|
||||
|
||||
// #3. Ensure no errors when compiler options aren't specified
|
||||
const config3 = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: JSON.stringify({ })
|
||||
};
|
||||
|
||||
host = createServerHost([file1, file2, config3, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") });
|
||||
session = createSession(host);
|
||||
|
||||
session.executeCommand(configureHostRequest).response;
|
||||
|
||||
openFilesForSession([file1], session);
|
||||
projectService = session.getProjectService();
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
|
||||
diagnostics = projectService.configuredProjects[0].getLanguageService().getCompilerOptionsDiagnostics();
|
||||
assert.deepEqual(diagnostics, []);
|
||||
|
||||
// #4. Ensure no errors when files are explicitly specified in tsconfig
|
||||
const config4 = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: JSON.stringify({ compilerOptions: { allowJs: true }, files: [file1.path, file2.path] })
|
||||
};
|
||||
|
||||
host = createServerHost([file1, file2, config4, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") });
|
||||
session = createSession(host);
|
||||
|
||||
session.executeCommand(configureHostRequest).response;
|
||||
|
||||
openFilesForSession([file1], session);
|
||||
projectService = session.getProjectService();
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
|
||||
diagnostics = projectService.configuredProjects[0].getLanguageService().getCompilerOptionsDiagnostics();
|
||||
assert.deepEqual(diagnostics, []);
|
||||
|
||||
// #4. Ensure no errors when files are explicitly excluded in tsconfig
|
||||
const config5 = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: JSON.stringify({ compilerOptions: { allowJs: true }, exclude: [file2.path] })
|
||||
};
|
||||
|
||||
host = createServerHost([file1, file2, config5, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") });
|
||||
session = createSession(host);
|
||||
|
||||
session.executeCommand(configureHostRequest).response;
|
||||
|
||||
openFilesForSession([file1], session);
|
||||
projectService = session.getProjectService();
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
|
||||
diagnostics = projectService.configuredProjects[0].getLanguageService().getCompilerOptionsDiagnostics();
|
||||
assert.deepEqual(diagnostics, []);
|
||||
});
|
||||
|
||||
it("project structure update is deferred if files are not added\removed", () => {
|
||||
const file1 = {
|
||||
path: "/a/b/f1.ts",
|
||||
@@ -3031,6 +3203,54 @@ namespace ts.projectSystem {
|
||||
});
|
||||
});
|
||||
|
||||
describe("emit with outFile or out setting", () => {
|
||||
function test(opts: CompilerOptions, expectedUsesOutFile: boolean) {
|
||||
const f1 = {
|
||||
path: "/a/a.ts",
|
||||
content: "let x = 1"
|
||||
};
|
||||
const f2 = {
|
||||
path: "/a/b.ts",
|
||||
content: "let y = 1"
|
||||
};
|
||||
const config = {
|
||||
path: "/a/tsconfig.json",
|
||||
content: JSON.stringify({
|
||||
compilerOptions: opts,
|
||||
compileOnSave: true
|
||||
})
|
||||
};
|
||||
const host = createServerHost([f1, f2, config]);
|
||||
const session = createSession(host);
|
||||
session.executeCommand(<protocol.OpenRequest>{
|
||||
seq: 1,
|
||||
type: "request",
|
||||
command: "open",
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
checkNumberOfProjects(session.getProjectService(), { configuredProjects: 1 });
|
||||
const { response } = session.executeCommand(<protocol.CompileOnSaveAffectedFileListRequest>{
|
||||
seq: 2,
|
||||
type: "request",
|
||||
command: "compileOnSaveAffectedFileList",
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
assert.equal((<protocol.CompileOnSaveAffectedFileListSingleProject[]>response).length, 1, "expected output for 1 project");
|
||||
assert.equal((<protocol.CompileOnSaveAffectedFileListSingleProject[]>response)[0].fileNames.length, 2, "expected output for 1 project");
|
||||
assert.equal((<protocol.CompileOnSaveAffectedFileListSingleProject[]>response)[0].projectUsesOutFile, expectedUsesOutFile, "usesOutFile");
|
||||
}
|
||||
|
||||
it ("projectUsesOutFile should not be returned if not set", () => {
|
||||
test({}, /*expectedUsesOutFile*/ false);
|
||||
});
|
||||
it ("projectUsesOutFile should be true if outFile is set", () => {
|
||||
test({ outFile: "/a/out.js" }, /*expectedUsesOutFile*/ true);
|
||||
});
|
||||
it ("projectUsesOutFile should be true if out is set", () => {
|
||||
test({ out: "/a/out.js" }, /*expectedUsesOutFile*/ true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("import helpers", () => {
|
||||
it("should not crash in tsserver", () => {
|
||||
const f1 = {
|
||||
@@ -3048,6 +3268,200 @@ namespace ts.projectSystem {
|
||||
});
|
||||
});
|
||||
|
||||
describe("cancellationToken", () => {
|
||||
it("is attached to request", () => {
|
||||
const f1 = {
|
||||
path: "/a/b/app.ts",
|
||||
content: "let xyz = 1;"
|
||||
};
|
||||
const host = createServerHost([f1]);
|
||||
let expectedRequestId: number;
|
||||
const cancellationToken: server.ServerCancellationToken = {
|
||||
isCancellationRequested: () => false,
|
||||
setRequest: requestId => {
|
||||
if (expectedRequestId === undefined) {
|
||||
assert.isTrue(false, "unexpected call")
|
||||
}
|
||||
assert.equal(requestId, expectedRequestId);
|
||||
},
|
||||
resetRequest: noop
|
||||
}
|
||||
const session = createSession(host, /*typingsInstaller*/ undefined, /*projectServiceEventHandler*/ undefined, cancellationToken);
|
||||
|
||||
expectedRequestId = session.getNextSeq();
|
||||
session.executeCommandSeq(<server.protocol.OpenRequest>{
|
||||
command: "open",
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
|
||||
expectedRequestId = session.getNextSeq();
|
||||
session.executeCommandSeq(<server.protocol.GeterrRequest>{
|
||||
command: "geterr",
|
||||
arguments: { files: [f1.path] }
|
||||
});
|
||||
|
||||
expectedRequestId = session.getNextSeq();
|
||||
session.executeCommandSeq(<server.protocol.OccurrencesRequest>{
|
||||
command: "occurrences",
|
||||
arguments: { file: f1.path, line: 1, offset: 6 }
|
||||
});
|
||||
|
||||
expectedRequestId = 2;
|
||||
host.runQueuedImmediateCallbacks();
|
||||
expectedRequestId = 2;
|
||||
host.runQueuedImmediateCallbacks();
|
||||
});
|
||||
|
||||
it("Geterr is cancellable", () => {
|
||||
const f1 = {
|
||||
path: "/a/app.ts",
|
||||
content: "let x = 1"
|
||||
};
|
||||
const config = {
|
||||
path: "/a/tsconfig.json",
|
||||
content: JSON.stringify({
|
||||
compilerOptions: {}
|
||||
})
|
||||
};
|
||||
|
||||
let requestToCancel = -1;
|
||||
const cancellationToken: server.ServerCancellationToken = (function(){
|
||||
let currentId: number;
|
||||
return <server.ServerCancellationToken>{
|
||||
setRequest(requestId) {
|
||||
currentId = requestId;
|
||||
},
|
||||
resetRequest(requestId) {
|
||||
assert.equal(requestId, currentId, "unexpected request id in cancellation")
|
||||
currentId = undefined;
|
||||
},
|
||||
isCancellationRequested() {
|
||||
return requestToCancel === currentId;
|
||||
}
|
||||
}
|
||||
})();
|
||||
const host = createServerHost([f1, config]);
|
||||
const session = createSession(host, /*typingsInstaller*/ undefined, () => {}, cancellationToken);
|
||||
{
|
||||
session.executeCommandSeq(<protocol.OpenRequest>{
|
||||
command: "open",
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
// send geterr for missing file
|
||||
session.executeCommandSeq(<protocol.GeterrRequest>{
|
||||
command: "geterr",
|
||||
arguments: { files: ["/a/missing"] }
|
||||
});
|
||||
// no files - expect 'completed' event
|
||||
assert.equal(host.getOutput().length, 1, "expect 1 message");
|
||||
verifyRequestCompleted(session.getSeq(), 0);
|
||||
}
|
||||
{
|
||||
const getErrId = session.getNextSeq();
|
||||
// send geterr for a valid file
|
||||
session.executeCommandSeq(<protocol.GeterrRequest>{
|
||||
command: "geterr",
|
||||
arguments: { files: [f1.path] }
|
||||
});
|
||||
|
||||
assert.equal(host.getOutput().length, 0, "expect 0 messages");
|
||||
|
||||
// run new request
|
||||
session.executeCommandSeq(<protocol.ProjectInfoRequest>{
|
||||
command: "projectInfo",
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
host.clearOutput();
|
||||
|
||||
// cancel previously issued Geterr
|
||||
requestToCancel = getErrId;
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
assert.equal(host.getOutput().length, 1, "expect 1 message");
|
||||
verifyRequestCompleted(getErrId, 0);
|
||||
|
||||
requestToCancel = -1;
|
||||
}
|
||||
{
|
||||
const getErrId = session.getNextSeq();
|
||||
session.executeCommandSeq(<protocol.GeterrRequest>{
|
||||
command: "geterr",
|
||||
arguments: { files: [f1.path] }
|
||||
});
|
||||
assert.equal(host.getOutput().length, 0, "expect 0 messages");
|
||||
|
||||
// run first step
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
assert.equal(host.getOutput().length, 1, "expect 1 messages");
|
||||
const e1 = <protocol.Event>getMessage(0);
|
||||
assert.equal(e1.event, "syntaxDiag");
|
||||
host.clearOutput();
|
||||
|
||||
requestToCancel = getErrId;
|
||||
host.runQueuedImmediateCallbacks();
|
||||
assert.equal(host.getOutput().length, 1, "expect 1 message");
|
||||
verifyRequestCompleted(getErrId, 0);
|
||||
|
||||
requestToCancel = -1;
|
||||
}
|
||||
{
|
||||
const getErrId = session.getNextSeq();
|
||||
session.executeCommandSeq(<protocol.GeterrRequest>{
|
||||
command: "geterr",
|
||||
arguments: { files: [f1.path] }
|
||||
});
|
||||
assert.equal(host.getOutput().length, 0, "expect 0 messages");
|
||||
|
||||
// run first step
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
assert.equal(host.getOutput().length, 1, "expect 1 messages");
|
||||
const e1 = <protocol.Event>getMessage(0);
|
||||
assert.equal(e1.event, "syntaxDiag");
|
||||
host.clearOutput();
|
||||
|
||||
host.runQueuedImmediateCallbacks();
|
||||
assert.equal(host.getOutput().length, 2, "expect 2 messages");
|
||||
const e2 = <protocol.Event>getMessage(0);
|
||||
assert.equal(e2.event, "semanticDiag");
|
||||
verifyRequestCompleted(getErrId, 1);
|
||||
|
||||
requestToCancel = -1;
|
||||
}
|
||||
{
|
||||
const getErr1 = session.getNextSeq();
|
||||
session.executeCommandSeq(<protocol.GeterrRequest>{
|
||||
command: "geterr",
|
||||
arguments: { files: [f1.path] }
|
||||
});
|
||||
assert.equal(host.getOutput().length, 0, "expect 0 messages");
|
||||
// run first step
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
assert.equal(host.getOutput().length, 1, "expect 1 messages");
|
||||
const e1 = <protocol.Event>getMessage(0);
|
||||
assert.equal(e1.event, "syntaxDiag");
|
||||
host.clearOutput();
|
||||
|
||||
session.executeCommandSeq(<protocol.GeterrRequest>{
|
||||
command: "geterr",
|
||||
arguments: { files: [f1.path] }
|
||||
});
|
||||
// make sure that getErr1 is completed
|
||||
verifyRequestCompleted(getErr1, 0);
|
||||
}
|
||||
|
||||
function verifyRequestCompleted(expectedSeq: number, n: number) {
|
||||
const event = <protocol.RequestCompletedEvent>getMessage(n);
|
||||
assert.equal(event.event, "requestCompleted");
|
||||
assert.equal(event.body.request_seq, expectedSeq, "expectedSeq");
|
||||
host.clearOutput();
|
||||
}
|
||||
|
||||
function getMessage(n: number) {
|
||||
return JSON.parse(server.extractMessage(host.getOutput()[n]));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("maxNodeModuleJsDepth for inferred projects", () => {
|
||||
it("should be set to 2 if the project has js root files", () => {
|
||||
const file1: FileOrFolder = {
|
||||
@@ -3067,7 +3481,7 @@ namespace ts.projectSystem {
|
||||
let options = project.getCompilerOptions();
|
||||
assert.isTrue(options.maxNodeModuleJsDepth === 2);
|
||||
|
||||
// Assert the option sticks
|
||||
// Assert the option sticks
|
||||
projectService.setCompilerOptionsForInferredProjects({ target: ScriptTarget.ES2016 });
|
||||
project = projectService.inferredProjects[0];
|
||||
options = project.getCompilerOptions();
|
||||
@@ -3101,5 +3515,4 @@ namespace ts.projectSystem {
|
||||
assert.isUndefined(project.getCompilerOptions().maxNodeModuleJsDepth);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
@@ -44,6 +44,47 @@ namespace ts.projectSystem {
|
||||
});
|
||||
}
|
||||
|
||||
import typingsName = server.typingsInstaller.typingsName;
|
||||
|
||||
describe("local module", () => {
|
||||
it("should not be picked up", () => {
|
||||
const f1 = {
|
||||
path: "/a/app.js",
|
||||
content: "const c = require('./config');"
|
||||
};
|
||||
const f2 = {
|
||||
path: "/a/config.js",
|
||||
content: "export let x = 1"
|
||||
};
|
||||
const typesCache = "/cache"
|
||||
const typesConfig = {
|
||||
path: typesCache + "/node_modules/@types/config/index.d.ts",
|
||||
content: "export let y: number;"
|
||||
};
|
||||
const config = {
|
||||
path: "/a/jsconfig.json",
|
||||
content: JSON.stringify({
|
||||
compilerOptions: { moduleResolution: "commonjs" },
|
||||
typeAcquisition: { enable: true }
|
||||
})
|
||||
};
|
||||
const host = createServerHost([f1, f2, config, typesConfig]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { typesRegistry: createTypesRegistry("config"), globalTypingsCacheLocation: typesCache });
|
||||
}
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, _cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
assert(false, "should not be called")
|
||||
}
|
||||
})();
|
||||
const service = createProjectService(host, { typingsInstaller: installer });
|
||||
service.openClientFile(f1.path);
|
||||
service.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
checkProjectActualFiles(service.configuredProjects[0], [f1.path, f2.path]);
|
||||
installer.installAll(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("typingsInstaller", () => {
|
||||
it("configured projects (typings installed) 1", () => {
|
||||
const file1 = {
|
||||
@@ -519,32 +560,32 @@ namespace ts.projectSystem {
|
||||
const commander = {
|
||||
path: "/a/data/node_modules/@types/commander/index.d.ts",
|
||||
content: "declare const commander: { x: number }",
|
||||
typings: "@types/commander"
|
||||
typings: typingsName("commander")
|
||||
};
|
||||
const jquery = {
|
||||
path: "/a/data/node_modules/@types/jquery/index.d.ts",
|
||||
content: "declare const jquery: { x: number }",
|
||||
typings: "@types/jquery"
|
||||
typings: typingsName("jquery")
|
||||
};
|
||||
const lodash = {
|
||||
path: "/a/data/node_modules/@types/lodash/index.d.ts",
|
||||
content: "declare const lodash: { x: number }",
|
||||
typings: "@types/lodash"
|
||||
typings: typingsName("lodash")
|
||||
};
|
||||
const cordova = {
|
||||
path: "/a/data/node_modules/@types/cordova/index.d.ts",
|
||||
content: "declare const cordova: { x: number }",
|
||||
typings: "@types/cordova"
|
||||
typings: typingsName("cordova")
|
||||
};
|
||||
const grunt = {
|
||||
path: "/a/data/node_modules/@types/grunt/index.d.ts",
|
||||
content: "declare const grunt: { x: number }",
|
||||
typings: "@types/grunt"
|
||||
typings: typingsName("grunt")
|
||||
};
|
||||
const gulp = {
|
||||
path: "/a/data/node_modules/@types/gulp/index.d.ts",
|
||||
content: "declare const gulp: { x: number }",
|
||||
typings: "@types/gulp"
|
||||
typings: typingsName("gulp")
|
||||
};
|
||||
|
||||
const host = createServerHost([lodashJs, commanderJs, file3]);
|
||||
@@ -554,7 +595,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
installWorker(_requestId: number, args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
let typingFiles: (FileOrFolder & { typings: string })[] = [];
|
||||
if (args.indexOf("@types/commander") >= 0) {
|
||||
if (args.indexOf(typingsName("commander")) >= 0) {
|
||||
typingFiles = [commander, jquery, lodash, cordova];
|
||||
}
|
||||
else {
|
||||
@@ -982,7 +1023,7 @@ namespace ts.projectSystem {
|
||||
return;
|
||||
}
|
||||
if (response.kind === server.EventEndInstallTypes) {
|
||||
assert.deepEqual(response.packagesToInstall, ["@types/commander"]);
|
||||
assert.deepEqual(response.packagesToInstall, [typingsName("commander")]);
|
||||
seenTelemetryEvent = true;
|
||||
return;
|
||||
}
|
||||
|
||||
Vendored
+1583
-384
File diff suppressed because it is too large
Load Diff
Vendored
-50
@@ -1,53 +1,3 @@
|
||||
/**
|
||||
* Represents the completion of an asynchronous operation
|
||||
*/
|
||||
interface Promise<T> {
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then(onfulfilled?: ((value: T) => T | PromiseLike<T>) | undefined | null, onrejected?: ((reason: any) => T | PromiseLike<T>) | undefined | null): Promise<T>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(onfulfilled: ((value: T) => T | PromiseLike<T>) | undefined | null, onrejected: (reason: any) => TResult | PromiseLike<TResult>): Promise<T | TResult>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(onfulfilled: (value: T) => TResult | PromiseLike<TResult>, onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<TResult>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult1, TResult2>(onfulfilled: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected: (reason: any) => TResult2 | PromiseLike<TResult2>): Promise<TResult1 | TResult2>;
|
||||
|
||||
/**
|
||||
* Attaches a callback for only the rejection of the Promise.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of the callback.
|
||||
*/
|
||||
catch(onrejected?: ((reason: any) => T | PromiseLike<T>) | undefined | null): Promise<T>;
|
||||
|
||||
/**
|
||||
* Attaches a callback for only the rejection of the Promise.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of the callback.
|
||||
*/
|
||||
catch<TResult>(onrejected: (reason: any) => TResult | PromiseLike<TResult>): Promise<T | TResult>;
|
||||
}
|
||||
|
||||
interface PromiseConstructor {
|
||||
/**
|
||||
|
||||
Vendored
+56
-11
@@ -137,16 +137,10 @@ interface ObjectConstructor {
|
||||
getOwnPropertyNames(o: any): string[];
|
||||
|
||||
/**
|
||||
* Creates an object that has null prototype.
|
||||
* @param o Object to use as a prototype. May be null
|
||||
* Creates an object that has the specified prototype or that has null prototype.
|
||||
* @param o Object to use as a prototype. May be null.
|
||||
*/
|
||||
create(o: null): any;
|
||||
|
||||
/**
|
||||
* Creates an object that has the specified prototype, and that optionally contains specified properties.
|
||||
* @param o Object to use as a prototype. May be null
|
||||
*/
|
||||
create<T extends object>(o: T): T;
|
||||
create<T extends object>(o: T | null): T | object;
|
||||
|
||||
/**
|
||||
* Creates an object that has the specified prototype, and that optionally contains specified properties.
|
||||
@@ -341,14 +335,14 @@ interface String {
|
||||
|
||||
/**
|
||||
* Replaces text in a string, using a regular expression or search string.
|
||||
* @param searchValue A string that represents the regular expression.
|
||||
* @param searchValue A string to search for.
|
||||
* @param replaceValue A string containing the text to replace for every successful match of searchValue in this string.
|
||||
*/
|
||||
replace(searchValue: string, replaceValue: string): string;
|
||||
|
||||
/**
|
||||
* Replaces text in a string, using a regular expression or search string.
|
||||
* @param searchValue A string that represents the regular expression.
|
||||
* @param searchValue A string to search for.
|
||||
* @param replacer A function that returns the replacement text.
|
||||
*/
|
||||
replace(searchValue: string, replacer: (substring: string, ...args: any[]) => string): string;
|
||||
@@ -1351,6 +1345,57 @@ interface PromiseLike<T> {
|
||||
onrejected: (reason: any) => TResult2 | PromiseLike<TResult2>): PromiseLike<TResult1 | TResult2>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the completion of an asynchronous operation
|
||||
*/
|
||||
interface Promise<T> {
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then(onfulfilled?: ((value: T) => T | PromiseLike<T>) | undefined | null, onrejected?: ((reason: any) => T | PromiseLike<T>) | undefined | null): Promise<T>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(onfulfilled: ((value: T) => T | PromiseLike<T>) | undefined | null, onrejected: (reason: any) => TResult | PromiseLike<TResult>): Promise<T | TResult>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(onfulfilled: (value: T) => TResult | PromiseLike<TResult>, onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<TResult>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult1, TResult2>(onfulfilled: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected: (reason: any) => TResult2 | PromiseLike<TResult2>): Promise<TResult1 | TResult2>;
|
||||
|
||||
/**
|
||||
* Attaches a callback for only the rejection of the Promise.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of the callback.
|
||||
*/
|
||||
catch(onrejected?: ((reason: any) => T | PromiseLike<T>) | undefined | null): Promise<T>;
|
||||
|
||||
/**
|
||||
* Attaches a callback for only the rejection of the Promise.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of the callback.
|
||||
*/
|
||||
catch<TResult>(onrejected: (reason: any) => TResult | PromiseLike<TResult>): Promise<T | TResult>;
|
||||
}
|
||||
|
||||
interface ArrayLike<T> {
|
||||
readonly length: number;
|
||||
readonly [n: number]: T;
|
||||
|
||||
Vendored
+636
-161
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,24 @@
|
||||
/// <reference types="node" />
|
||||
|
||||
|
||||
// TODO: extract services types
|
||||
interface HostCancellationToken {
|
||||
isCancellationRequested(): boolean;
|
||||
}
|
||||
/// <reference types="node"/>
|
||||
|
||||
import fs = require("fs");
|
||||
|
||||
function createCancellationToken(args: string[]): HostCancellationToken {
|
||||
interface ServerCancellationToken {
|
||||
isCancellationRequested(): boolean;
|
||||
setRequest(requestId: number): void;
|
||||
resetRequest(requestId: number): void;
|
||||
}
|
||||
|
||||
function pipeExists(name: string): boolean {
|
||||
try {
|
||||
fs.statSync(name);
|
||||
return true;
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function createCancellationToken(args: string[]): ServerCancellationToken {
|
||||
let cancellationPipeName: string;
|
||||
for (let i = 0; i < args.length - 1; i++) {
|
||||
if (args[i] === "--cancellationPipeName") {
|
||||
@@ -17,18 +27,44 @@ function createCancellationToken(args: string[]): HostCancellationToken {
|
||||
}
|
||||
}
|
||||
if (!cancellationPipeName) {
|
||||
return { isCancellationRequested: () => false };
|
||||
return {
|
||||
isCancellationRequested: () => false,
|
||||
setRequest: (_requestId: number): void => void 0,
|
||||
resetRequest: (_requestId: number): void => void 0
|
||||
};
|
||||
}
|
||||
return {
|
||||
isCancellationRequested() {
|
||||
try {
|
||||
fs.statSync(cancellationPipeName);
|
||||
return true;
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
// cancellationPipeName is a string without '*' inside that can optionally end with '*'
|
||||
// when client wants to signal cancellation it should create a named pipe with name=<cancellationPipeName>
|
||||
// server will synchronously check the presence of the pipe and treat its existance as indicator that current request should be canceled.
|
||||
// in case if client prefers to use more fine-grained schema than one name for all request it can add '*' to the end of cancelellationPipeName.
|
||||
// in this case pipe name will be build dynamically as <cancellationPipeName><request_seq>.
|
||||
if (cancellationPipeName.charAt(cancellationPipeName.length - 1) === "*") {
|
||||
const namePrefix = cancellationPipeName.slice(0, -1);
|
||||
if (namePrefix.length === 0 || namePrefix.indexOf("*") >= 0) {
|
||||
throw new Error("Invalid name for template cancellation pipe: it should have length greater than 2 characters and contain only one '*'.");
|
||||
}
|
||||
};
|
||||
let perRequestPipeName: string;
|
||||
let currentRequestId: number;
|
||||
return {
|
||||
isCancellationRequested: () => perRequestPipeName !== undefined && pipeExists(perRequestPipeName),
|
||||
setRequest(requestId: number) {
|
||||
currentRequestId = currentRequestId;
|
||||
perRequestPipeName = namePrefix + requestId;
|
||||
},
|
||||
resetRequest(requestId: number) {
|
||||
if (currentRequestId !== requestId) {
|
||||
throw new Error(`Mismatched request id, expected ${currentRequestId}, actual ${requestId}`);
|
||||
}
|
||||
perRequestPipeName = undefined;
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
isCancellationRequested: () => pipeExists(cancellationPipeName),
|
||||
setRequest: (_requestId: number): void => void 0,
|
||||
resetRequest: (_requestId: number): void => void 0
|
||||
};
|
||||
}
|
||||
}
|
||||
export = createCancellationToken;
|
||||
+20
-19
@@ -13,6 +13,25 @@ namespace ts.server {
|
||||
findInComments: boolean;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function extractMessage(message: string) {
|
||||
// Read the content length
|
||||
const contentLengthPrefix = "Content-Length: ";
|
||||
const lines = message.split(/\r?\n/);
|
||||
Debug.assert(lines.length >= 2, "Malformed response: Expected 3 lines in the response.");
|
||||
|
||||
const contentLengthText = lines[0];
|
||||
Debug.assert(contentLengthText.indexOf(contentLengthPrefix) === 0, "Malformed response: Response text did not contain content-length header.");
|
||||
const contentLength = parseInt(contentLengthText.substring(contentLengthPrefix.length));
|
||||
|
||||
// Read the body
|
||||
const responseBody = lines[2];
|
||||
|
||||
// Verify content length
|
||||
Debug.assert(responseBody.length + 1 === contentLength, "Malformed response: Content length did not match the response's body length.");
|
||||
return responseBody;
|
||||
}
|
||||
|
||||
export class SessionClient implements LanguageService {
|
||||
private sequence: number = 0;
|
||||
private lineMaps: ts.Map<number[]> = ts.createMap<number[]>();
|
||||
@@ -84,7 +103,7 @@ namespace ts.server {
|
||||
while (!foundResponseMessage) {
|
||||
lastMessage = this.messages.shift();
|
||||
Debug.assert(!!lastMessage, "Did not receive any responses.");
|
||||
const responseBody = processMessage(lastMessage);
|
||||
const responseBody = extractMessage(lastMessage);
|
||||
try {
|
||||
response = JSON.parse(responseBody);
|
||||
// the server may emit events before emitting the response. We
|
||||
@@ -109,24 +128,6 @@ namespace ts.server {
|
||||
Debug.assert(!!response.body, "Malformed response: Unexpected empty response body.");
|
||||
|
||||
return response;
|
||||
|
||||
function processMessage(message: string) {
|
||||
// Read the content length
|
||||
const contentLengthPrefix = "Content-Length: ";
|
||||
const lines = message.split("\r\n");
|
||||
Debug.assert(lines.length >= 2, "Malformed response: Expected 3 lines in the response.");
|
||||
|
||||
const contentLengthText = lines[0];
|
||||
Debug.assert(contentLengthText.indexOf(contentLengthPrefix) === 0, "Malformed response: Response text did not contain content-length header.");
|
||||
const contentLength = parseInt(contentLengthText.substring(contentLengthPrefix.length));
|
||||
|
||||
// Read the body
|
||||
const responseBody = lines[2];
|
||||
|
||||
// Verify content length
|
||||
Debug.assert(responseBody.length + 1 === contentLength, "Malformed response: Content length did not match the response's body length.");
|
||||
return responseBody;
|
||||
}
|
||||
}
|
||||
|
||||
openFile(fileName: string, content?: string, scriptKindName?: "TS" | "JS" | "TSX" | "JSX"): void {
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace ts.server {
|
||||
export interface HostConfiguration {
|
||||
formatCodeOptions: FormatCodeSettings;
|
||||
hostInfo: string;
|
||||
extraFileExtensions?: FileExtensionInfo[];
|
||||
extraFileExtensions?: JsFileExtensionInfo[];
|
||||
}
|
||||
|
||||
interface ConfigFileConversionResult {
|
||||
@@ -132,7 +132,7 @@ namespace ts.server {
|
||||
interface FilePropertyReader<T> {
|
||||
getFileName(f: T): string;
|
||||
getScriptKind(f: T): ScriptKind;
|
||||
hasMixedContent(f: T, extraFileExtensions: FileExtensionInfo[]): boolean;
|
||||
hasMixedContent(f: T, extraFileExtensions: JsFileExtensionInfo[]): boolean;
|
||||
}
|
||||
|
||||
const fileNamePropertyReader: FilePropertyReader<string> = {
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace ts.server {
|
||||
: undefined;
|
||||
const primaryResult = resolveModuleName(moduleName, containingFile, compilerOptions, host);
|
||||
// return result immediately only if it is .ts, .tsx or .d.ts
|
||||
if (!(primaryResult.resolvedModule && extensionIsTypeScript(primaryResult.resolvedModule.extension)) && globalCache !== undefined) {
|
||||
if (moduleHasNonRelativeName(moduleName) && !(primaryResult.resolvedModule && extensionIsTypeScript(primaryResult.resolvedModule.extension)) && globalCache !== undefined) {
|
||||
// otherwise try to load typings from @types
|
||||
|
||||
// create different collection of failed lookup locations for second pass
|
||||
|
||||
+108
-5
@@ -91,19 +91,38 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
export interface PluginCreateInfo {
|
||||
project: Project;
|
||||
languageService: LanguageService;
|
||||
languageServiceHost: LanguageServiceHost;
|
||||
serverHost: ServerHost;
|
||||
config: any;
|
||||
}
|
||||
|
||||
export interface PluginModule {
|
||||
create(createInfo: PluginCreateInfo): LanguageService;
|
||||
getExternalFiles?(proj: Project): string[];
|
||||
}
|
||||
|
||||
export interface PluginModuleFactory {
|
||||
(mod: { typescript: typeof ts }): PluginModule;
|
||||
}
|
||||
|
||||
export abstract class Project {
|
||||
private rootFiles: ScriptInfo[] = [];
|
||||
private rootFilesMap: FileMap<ScriptInfo> = createFileMap<ScriptInfo>();
|
||||
private lsHost: LSHost;
|
||||
private program: ts.Program;
|
||||
|
||||
private cachedUnresolvedImportsPerFile = new UnresolvedImportsMap();
|
||||
private lastCachedUnresolvedImportsList: SortedReadonlyArray<string>;
|
||||
|
||||
private readonly languageService: LanguageService;
|
||||
// wrapper over the real language service that will suppress all semantic operations
|
||||
protected languageService: LanguageService;
|
||||
|
||||
public languageServiceEnabled = true;
|
||||
|
||||
protected readonly lsHost: LSHost;
|
||||
|
||||
builder: Builder;
|
||||
/**
|
||||
* Set of files names that were updated since the last call to getChangesSinceVersion.
|
||||
@@ -150,6 +169,17 @@ namespace ts.server {
|
||||
return this.cachedUnresolvedImportsPerFile;
|
||||
}
|
||||
|
||||
public static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {} {
|
||||
const resolvedPath = normalizeSlashes(host.resolvePath(combinePaths(initialDir, "node_modules")));
|
||||
log(`Loading ${moduleName} from ${initialDir} (resolved to ${resolvedPath})`);
|
||||
const result = host.require(resolvedPath, moduleName);
|
||||
if (result.error) {
|
||||
log(`Failed to load module: ${JSON.stringify(result.error)}`);
|
||||
return undefined;
|
||||
}
|
||||
return result.module;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly projectName: string,
|
||||
readonly projectKind: ProjectKind,
|
||||
@@ -165,8 +195,8 @@ namespace ts.server {
|
||||
this.compilerOptions.allowNonTsExtensions = true;
|
||||
this.compilerOptions.allowJs = true;
|
||||
}
|
||||
else if (hasExplicitListOfFiles) {
|
||||
// If files are listed explicitly, allow all extensions
|
||||
else if (hasExplicitListOfFiles || this.compilerOptions.allowJs) {
|
||||
// If files are listed explicitly or allowJs is specified, allow all extensions
|
||||
this.compilerOptions.allowNonTsExtensions = true;
|
||||
}
|
||||
|
||||
@@ -237,6 +267,10 @@ namespace ts.server {
|
||||
abstract getProjectRootPath(): string | undefined;
|
||||
abstract getTypeAcquisition(): TypeAcquisition;
|
||||
|
||||
getExternalFiles(): string[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
getSourceFile(path: Path) {
|
||||
if (!this.program) {
|
||||
return undefined;
|
||||
@@ -804,10 +838,12 @@ namespace ts.server {
|
||||
private typeRootsWatchers: FileWatcher[];
|
||||
readonly canonicalConfigFilePath: NormalizedPath;
|
||||
|
||||
private plugins: PluginModule[] = [];
|
||||
|
||||
/** Used for configured projects which may have multiple open roots */
|
||||
openRefCount = 0;
|
||||
|
||||
constructor(configFileName: NormalizedPath,
|
||||
constructor(private configFileName: NormalizedPath,
|
||||
projectService: ProjectService,
|
||||
documentRegistry: ts.DocumentRegistry,
|
||||
hasExplicitListOfFiles: boolean,
|
||||
@@ -817,12 +853,64 @@ namespace ts.server {
|
||||
public compileOnSaveEnabled: boolean) {
|
||||
super(configFileName, ProjectKind.Configured, projectService, documentRegistry, hasExplicitListOfFiles, languageServiceEnabled, compilerOptions, compileOnSaveEnabled);
|
||||
this.canonicalConfigFilePath = asNormalizedPath(projectService.toCanonicalFileName(configFileName));
|
||||
this.enablePlugins();
|
||||
}
|
||||
|
||||
getConfigFilePath() {
|
||||
return this.getProjectName();
|
||||
}
|
||||
|
||||
enablePlugins() {
|
||||
const host = this.projectService.host;
|
||||
const options = this.getCompilerOptions();
|
||||
const log = (message: string) => {
|
||||
this.projectService.logger.info(message);
|
||||
};
|
||||
|
||||
if (!(options.plugins && options.plugins.length)) {
|
||||
this.projectService.logger.info("No plugins exist");
|
||||
// No plugins
|
||||
return;
|
||||
}
|
||||
|
||||
if (!host.require) {
|
||||
this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded");
|
||||
return;
|
||||
}
|
||||
|
||||
for (const pluginConfigEntry of options.plugins) {
|
||||
const searchPath = getDirectoryPath(this.configFileName);
|
||||
const resolvedModule = <PluginModuleFactory>Project.resolveModule(pluginConfigEntry.name, searchPath, host, log);
|
||||
if (resolvedModule) {
|
||||
this.enableProxy(resolvedModule, pluginConfigEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enableProxy(pluginModuleFactory: PluginModuleFactory, configEntry: PluginImport) {
|
||||
try {
|
||||
if (typeof pluginModuleFactory !== "function") {
|
||||
this.projectService.logger.info(`Skipped loading plugin ${configEntry.name} because it did expose a proper factory function`);
|
||||
return;
|
||||
}
|
||||
|
||||
const info: PluginCreateInfo = {
|
||||
config: configEntry,
|
||||
project: this,
|
||||
languageService: this.languageService,
|
||||
languageServiceHost: this.lsHost,
|
||||
serverHost: this.projectService.host
|
||||
};
|
||||
|
||||
const pluginModule = pluginModuleFactory({ typescript: ts });
|
||||
this.languageService = pluginModule.create(info);
|
||||
this.plugins.push(pluginModule);
|
||||
}
|
||||
catch (e) {
|
||||
this.projectService.logger.info(`Plugin activation failed: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
getProjectRootPath() {
|
||||
return getDirectoryPath(this.getConfigFilePath());
|
||||
}
|
||||
@@ -839,6 +927,21 @@ namespace ts.server {
|
||||
return this.typeAcquisition;
|
||||
}
|
||||
|
||||
getExternalFiles(): string[] {
|
||||
const items: string[] = [];
|
||||
for (const plugin of this.plugins) {
|
||||
if (typeof plugin.getExternalFiles === "function") {
|
||||
try {
|
||||
items.push(...plugin.getExternalFiles(this));
|
||||
}
|
||||
catch (e) {
|
||||
this.projectService.logger.info(`A plugin threw an exception in getExternalFiles: ${e}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
watchConfigFile(callback: (project: ConfiguredProject) => void) {
|
||||
this.projectFileWatcher = this.projectService.host.watchFile(this.getConfigFilePath(), _ => callback(this));
|
||||
}
|
||||
|
||||
+22
-2
@@ -1001,9 +1001,9 @@ namespace ts.server.protocol {
|
||||
formatOptions?: FormatCodeSettings;
|
||||
|
||||
/**
|
||||
* The host's additional supported file extensions
|
||||
* The host's additional supported .js file extensions
|
||||
*/
|
||||
extraFileExtensions?: FileExtensionInfo[];
|
||||
extraFileExtensions?: JsFileExtensionInfo[];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1239,6 +1239,11 @@ namespace ts.server.protocol {
|
||||
* List of files names that should be recompiled
|
||||
*/
|
||||
fileNames: string[];
|
||||
|
||||
/**
|
||||
* true if project uses outFile or out compiler option
|
||||
*/
|
||||
projectUsesOutFile: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1761,6 +1766,20 @@ namespace ts.server.protocol {
|
||||
arguments: GeterrRequestArgs;
|
||||
}
|
||||
|
||||
export type RequestCompletedEventName = "requestCompleted";
|
||||
|
||||
/**
|
||||
* Event that is sent when server have finished processing request with specified id.
|
||||
*/
|
||||
export interface RequestCompletedEvent extends Event {
|
||||
event: RequestCompletedEventName;
|
||||
body: RequestCompletedEventBody;
|
||||
}
|
||||
|
||||
export interface RequestCompletedEventBody {
|
||||
request_seq: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Item of diagnostic information found in a DiagnosticEvent message.
|
||||
*/
|
||||
@@ -2248,6 +2267,7 @@ namespace ts.server.protocol {
|
||||
outDir?: string;
|
||||
outFile?: string;
|
||||
paths?: MapLike<string[]>;
|
||||
plugins?: PluginImport[];
|
||||
preserveConstEnums?: boolean;
|
||||
project?: string;
|
||||
reactNamespace?: string;
|
||||
|
||||
+15
-5
@@ -99,6 +99,8 @@ namespace ts.server {
|
||||
birthtime: Date;
|
||||
}
|
||||
|
||||
type RequireResult = { module: {}, error: undefined } | { module: undefined, error: {} };
|
||||
|
||||
const readline: {
|
||||
createInterface(options: ReadLineOptions): NodeJS.EventEmitter;
|
||||
} = require("readline");
|
||||
@@ -354,7 +356,7 @@ namespace ts.server {
|
||||
class IOSession extends Session {
|
||||
constructor(
|
||||
host: ServerHost,
|
||||
cancellationToken: HostCancellationToken,
|
||||
cancellationToken: ServerCancellationToken,
|
||||
installerEventPort: number,
|
||||
canUseEvents: boolean,
|
||||
useSingleInferredProject: boolean,
|
||||
@@ -593,15 +595,23 @@ namespace ts.server {
|
||||
sys.gc = () => global.gc();
|
||||
}
|
||||
|
||||
let cancellationToken: HostCancellationToken;
|
||||
sys.require = (initialDir: string, moduleName: string): RequireResult => {
|
||||
const result = nodeModuleNameResolverWorker(moduleName, initialDir + "/program.ts", { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, sys, undefined, /*jsOnly*/ true);
|
||||
try {
|
||||
return { module: require(result.resolvedModule.resolvedFileName), error: undefined };
|
||||
}
|
||||
catch (e) {
|
||||
return { module: undefined, error: e };
|
||||
}
|
||||
};
|
||||
|
||||
let cancellationToken: ServerCancellationToken;
|
||||
try {
|
||||
const factory = require("./cancellationToken");
|
||||
cancellationToken = factory(sys.args);
|
||||
}
|
||||
catch (e) {
|
||||
cancellationToken = {
|
||||
isCancellationRequested: () => false
|
||||
};
|
||||
cancellationToken = nullCancellationToken;
|
||||
};
|
||||
|
||||
let eventPort: number;
|
||||
|
||||
+192
-34
@@ -8,6 +8,17 @@ namespace ts.server {
|
||||
stack?: string;
|
||||
}
|
||||
|
||||
export interface ServerCancellationToken extends HostCancellationToken {
|
||||
setRequest(requestId: number): void;
|
||||
resetRequest(requestId: number): void;
|
||||
}
|
||||
|
||||
export const nullCancellationToken: ServerCancellationToken = {
|
||||
isCancellationRequested: () => false,
|
||||
setRequest: () => void 0,
|
||||
resetRequest: () => void 0
|
||||
};
|
||||
|
||||
function hrTimeToMilliseconds(time: number[]): number {
|
||||
const seconds = time[0];
|
||||
const nanoseconds = time[1];
|
||||
@@ -193,18 +204,134 @@ namespace ts.server {
|
||||
return `Content-Length: ${1 + len}\r\n\r\n${json}${newLine}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to schedule next step in multistep operation
|
||||
*/
|
||||
interface NextStep {
|
||||
immediate(action: () => void): void;
|
||||
delay(ms: number, action: () => void): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* External capabilities used by multistep operation
|
||||
*/
|
||||
interface MultistepOperationHost {
|
||||
getCurrentRequestId(): number;
|
||||
sendRequestCompletedEvent(requestId: number): void;
|
||||
getServerHost(): ServerHost;
|
||||
isCancellationRequested(): boolean;
|
||||
executeWithRequestId(requestId: number, action: () => void): void;
|
||||
logError(error: Error, message: string): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents operation that can schedule its next step to be executed later.
|
||||
* Scheduling is done via instance of NextStep. If on current step subsequent step was not scheduled - operation is assumed to be completed.
|
||||
*/
|
||||
class MultistepOperation {
|
||||
private requestId: number;
|
||||
private timerHandle: any;
|
||||
private immediateId: any;
|
||||
private completed = true;
|
||||
private readonly next: NextStep;
|
||||
|
||||
constructor(private readonly operationHost: MultistepOperationHost) {
|
||||
this.next = {
|
||||
immediate: action => this.immediate(action),
|
||||
delay: (ms, action) => this.delay(ms, action)
|
||||
}
|
||||
}
|
||||
|
||||
public startNew(action: (next: NextStep) => void) {
|
||||
this.complete();
|
||||
this.requestId = this.operationHost.getCurrentRequestId();
|
||||
this.completed = false;
|
||||
this.executeAction(action);
|
||||
}
|
||||
|
||||
private complete() {
|
||||
if (!this.completed) {
|
||||
if (this.requestId) {
|
||||
this.operationHost.sendRequestCompletedEvent(this.requestId);
|
||||
}
|
||||
this.completed = true;
|
||||
}
|
||||
this.setTimerHandle(undefined);
|
||||
this.setImmediateId(undefined);
|
||||
}
|
||||
|
||||
private immediate(action: () => void) {
|
||||
const requestId = this.requestId;
|
||||
Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "immediate: incorrect request id")
|
||||
this.setImmediateId(this.operationHost.getServerHost().setImmediate(() => {
|
||||
this.immediateId = undefined;
|
||||
this.operationHost.executeWithRequestId(requestId, () => this.executeAction(action));
|
||||
}));
|
||||
}
|
||||
|
||||
private delay(ms: number, action: () => void) {
|
||||
const requestId = this.requestId;
|
||||
Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "delay: incorrect request id")
|
||||
this.setTimerHandle(this.operationHost.getServerHost().setTimeout(() => {
|
||||
this.timerHandle = undefined;
|
||||
this.operationHost.executeWithRequestId(requestId, () => this.executeAction(action));
|
||||
}, ms));
|
||||
}
|
||||
|
||||
private executeAction(action: (next: NextStep) => void) {
|
||||
let stop = false;
|
||||
try {
|
||||
if (this.operationHost.isCancellationRequested()) {
|
||||
stop = true;
|
||||
}
|
||||
else {
|
||||
action(this.next);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
stop = true;
|
||||
// ignore cancellation request
|
||||
if (!(e instanceof OperationCanceledException)) {
|
||||
this.operationHost.logError(e, `delayed processing of request ${this.requestId}`);
|
||||
}
|
||||
}
|
||||
if (stop || !this.hasPendingWork()) {
|
||||
this.complete();
|
||||
}
|
||||
}
|
||||
|
||||
private setTimerHandle(timerHandle: any) {;
|
||||
if (this.timerHandle !== undefined) {
|
||||
this.operationHost.getServerHost().clearTimeout(this.timerHandle);
|
||||
}
|
||||
this.timerHandle = timerHandle;
|
||||
}
|
||||
|
||||
private setImmediateId(immediateId: number) {
|
||||
if (this.immediateId !== undefined) {
|
||||
this.operationHost.getServerHost().clearImmediate(this.immediateId);
|
||||
}
|
||||
this.immediateId = immediateId;
|
||||
}
|
||||
|
||||
private hasPendingWork() {
|
||||
return !!this.timerHandle || !!this.immediateId;
|
||||
}
|
||||
}
|
||||
|
||||
export class Session implements EventSender {
|
||||
private readonly gcTimer: GcTimer;
|
||||
protected projectService: ProjectService;
|
||||
private errorTimer: any; /*NodeJS.Timer | number*/
|
||||
private immediateId: any;
|
||||
private changeSeq = 0;
|
||||
|
||||
private currentRequestId: number;
|
||||
private errorCheck: MultistepOperation;
|
||||
|
||||
private eventHander: ProjectServiceEventHandler;
|
||||
|
||||
constructor(
|
||||
private host: ServerHost,
|
||||
cancellationToken: HostCancellationToken,
|
||||
private readonly cancellationToken: ServerCancellationToken,
|
||||
useSingleInferredProject: boolean,
|
||||
protected readonly typingsInstaller: ITypingsInstaller,
|
||||
private byteLength: (buf: string, encoding?: string) => number,
|
||||
@@ -217,17 +344,35 @@ namespace ts.server {
|
||||
? eventHandler || (event => this.defaultEventHandler(event))
|
||||
: undefined;
|
||||
|
||||
const multistepOperationHost: MultistepOperationHost = {
|
||||
executeWithRequestId: (requestId, action) => this.executeWithRequestId(requestId, action),
|
||||
getCurrentRequestId: () => this.currentRequestId,
|
||||
getServerHost: () => this.host,
|
||||
logError: (err, cmd) => this.logError(err, cmd),
|
||||
sendRequestCompletedEvent: requestId => this.sendRequestCompletedEvent(requestId),
|
||||
isCancellationRequested: () => cancellationToken.isCancellationRequested()
|
||||
}
|
||||
this.errorCheck = new MultistepOperation(multistepOperationHost);
|
||||
this.projectService = new ProjectService(host, logger, cancellationToken, useSingleInferredProject, typingsInstaller, this.eventHander);
|
||||
this.gcTimer = new GcTimer(host, /*delay*/ 7000, logger);
|
||||
}
|
||||
|
||||
private sendRequestCompletedEvent(requestId: number): void {
|
||||
const event: protocol.RequestCompletedEvent = {
|
||||
seq: 0,
|
||||
type: "event",
|
||||
event: "requestCompleted",
|
||||
body: { request_seq: requestId }
|
||||
};
|
||||
this.send(event);
|
||||
}
|
||||
|
||||
private defaultEventHandler(event: ProjectServiceEvent) {
|
||||
switch (event.eventName) {
|
||||
case ContextEvent:
|
||||
const { project, fileName } = event.data;
|
||||
this.projectService.logger.info(`got context event, updating diagnostics for ${fileName}`);
|
||||
this.updateErrorCheck([{ fileName, project }], this.changeSeq,
|
||||
(n) => n === this.changeSeq, 100);
|
||||
this.errorCheck.startNew(next => this.updateErrorCheck(next, [{ fileName, project }], this.changeSeq, (n) => n === this.changeSeq, 100));
|
||||
break;
|
||||
case ConfigFileDiagEvent:
|
||||
const { triggerFile, configFileName, diagnostics } = event.data;
|
||||
@@ -284,7 +429,7 @@ namespace ts.server {
|
||||
seq: 0,
|
||||
type: "event",
|
||||
event: eventName,
|
||||
body: info,
|
||||
body: info
|
||||
};
|
||||
this.send(ev);
|
||||
}
|
||||
@@ -342,18 +487,11 @@ namespace ts.server {
|
||||
}, ms);
|
||||
}
|
||||
|
||||
private updateErrorCheck(checkList: PendingErrorCheck[], seq: number,
|
||||
matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200, requireOpen = true) {
|
||||
private updateErrorCheck(next: NextStep, checkList: PendingErrorCheck[], seq: number, matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200, requireOpen = true) {
|
||||
if (followMs > ms) {
|
||||
followMs = ms;
|
||||
}
|
||||
if (this.errorTimer) {
|
||||
this.host.clearTimeout(this.errorTimer);
|
||||
}
|
||||
if (this.immediateId) {
|
||||
this.host.clearImmediate(this.immediateId);
|
||||
this.immediateId = undefined;
|
||||
}
|
||||
|
||||
let index = 0;
|
||||
const checkOne = () => {
|
||||
if (matchSeq(seq)) {
|
||||
@@ -361,21 +499,18 @@ namespace ts.server {
|
||||
index++;
|
||||
if (checkSpec.project.containsFile(checkSpec.fileName, requireOpen)) {
|
||||
this.syntacticCheck(checkSpec.fileName, checkSpec.project);
|
||||
this.immediateId = this.host.setImmediate(() => {
|
||||
next.immediate(() => {
|
||||
this.semanticCheck(checkSpec.fileName, checkSpec.project);
|
||||
this.immediateId = undefined;
|
||||
if (checkList.length > index) {
|
||||
this.errorTimer = this.host.setTimeout(checkOne, followMs);
|
||||
}
|
||||
else {
|
||||
this.errorTimer = undefined;
|
||||
next.delay(followMs, checkOne);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if ((checkList.length > index) && (matchSeq(seq))) {
|
||||
this.errorTimer = this.host.setTimeout(checkOne, ms);
|
||||
next.delay(ms, checkOne);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1040,7 +1175,8 @@ namespace ts.server {
|
||||
if (project.compileOnSaveEnabled && project.languageServiceEnabled) {
|
||||
result.push({
|
||||
projectFileName: project.getProjectName(),
|
||||
fileNames: project.getCompileOnSaveAffectedFileList(info)
|
||||
fileNames: project.getCompileOnSaveAffectedFileList(info),
|
||||
projectUsesOutFile: !!project.getCompilerOptions().outFile || !!project.getCompilerOptions().out
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1086,7 +1222,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private getDiagnostics(delay: number, fileNames: string[]) {
|
||||
private getDiagnostics(next: NextStep, delay: number, fileNames: string[]): void {
|
||||
const checkList = fileNames.reduce((accum: PendingErrorCheck[], uncheckedFileName: string) => {
|
||||
const fileName = toNormalizedPath(uncheckedFileName);
|
||||
const project = this.projectService.getDefaultProjectForFile(fileName, /*refreshInferredProjects*/ true);
|
||||
@@ -1097,7 +1233,7 @@ namespace ts.server {
|
||||
}, []);
|
||||
|
||||
if (checkList.length > 0) {
|
||||
this.updateErrorCheck(checkList, this.changeSeq, (n) => n === this.changeSeq, delay);
|
||||
this.updateErrorCheck(next, checkList, this.changeSeq, (n) => n === this.changeSeq, delay);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1334,7 +1470,7 @@ namespace ts.server {
|
||||
: spans;
|
||||
}
|
||||
|
||||
getDiagnosticsForProject(delay: number, fileName: string) {
|
||||
private getDiagnosticsForProject(next: NextStep, delay: number, fileName: string): void {
|
||||
const { fileNames, languageServiceDisabled } = this.getProjectInfoWorker(fileName, /*projectFileName*/ undefined, /*needFileNameList*/ true);
|
||||
if (languageServiceDisabled) {
|
||||
return;
|
||||
@@ -1372,7 +1508,7 @@ namespace ts.server {
|
||||
const checkList = fileNamesInProject.map(fileName => ({ fileName, project }));
|
||||
// Project level error analysis runs on background files too, therefore
|
||||
// doesn't require the file to be opened
|
||||
this.updateErrorCheck(checkList, this.changeSeq, (n) => n == this.changeSeq, delay, 200, /*requireOpen*/ false);
|
||||
this.updateErrorCheck(next, checkList, this.changeSeq, (n) => n == this.changeSeq, delay, 200, /*requireOpen*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1549,13 +1685,13 @@ namespace ts.server {
|
||||
[CommandNames.SyntacticDiagnosticsSync]: (request: protocol.SyntacticDiagnosticsSyncRequest) => {
|
||||
return this.requiredResponse(this.getSyntacticDiagnosticsSync(request.arguments));
|
||||
},
|
||||
[CommandNames.Geterr]: (request: protocol.Request) => {
|
||||
const geterrArgs = <protocol.GeterrRequestArgs>request.arguments;
|
||||
return { response: this.getDiagnostics(geterrArgs.delay, geterrArgs.files), responseRequired: false };
|
||||
[CommandNames.Geterr]: (request: protocol.GeterrRequest) => {
|
||||
this.errorCheck.startNew(next => this.getDiagnostics(next, request.arguments.delay, request.arguments.files));
|
||||
return this.notRequired();
|
||||
},
|
||||
[CommandNames.GeterrForProject]: (request: protocol.Request) => {
|
||||
const { file, delay } = <protocol.GeterrForProjectRequestArgs>request.arguments;
|
||||
return { response: this.getDiagnosticsForProject(delay, file), responseRequired: false };
|
||||
[CommandNames.GeterrForProject]: (request: protocol.GeterrForProjectRequest) => {
|
||||
this.errorCheck.startNew(next => this.getDiagnosticsForProject(next, request.arguments.delay, request.arguments.file));
|
||||
return this.notRequired();
|
||||
},
|
||||
[CommandNames.Change]: (request: protocol.ChangeRequest) => {
|
||||
this.change(request.arguments);
|
||||
@@ -1642,10 +1778,32 @@ namespace ts.server {
|
||||
this.handlers.set(command, handler);
|
||||
}
|
||||
|
||||
private setCurrentRequest(requestId: number): void {
|
||||
Debug.assert(this.currentRequestId === undefined);
|
||||
this.currentRequestId = requestId;
|
||||
this.cancellationToken.setRequest(requestId);
|
||||
}
|
||||
|
||||
private resetCurrentRequest(requestId: number): void {
|
||||
Debug.assert(this.currentRequestId === requestId);
|
||||
this.currentRequestId = undefined;
|
||||
this.cancellationToken.resetRequest(requestId);
|
||||
}
|
||||
|
||||
public executeWithRequestId<T>(requestId: number, f: () => T) {
|
||||
try {
|
||||
this.setCurrentRequest(requestId);
|
||||
return f();
|
||||
}
|
||||
finally {
|
||||
this.resetCurrentRequest(requestId);
|
||||
}
|
||||
}
|
||||
|
||||
public executeCommand(request: protocol.Request): { response?: any, responseRequired?: boolean } {
|
||||
const handler = this.handlers.get(request.command);
|
||||
if (handler) {
|
||||
return handler(request);
|
||||
return this.executeWithRequestId(request.seq, () => handler(request));
|
||||
}
|
||||
else {
|
||||
this.logger.msg(`Unrecognized JSON command: ${JSON.stringify(request)}`, Msg.Err);
|
||||
|
||||
@@ -9,6 +9,7 @@ declare namespace ts.server {
|
||||
data: any;
|
||||
}
|
||||
|
||||
type RequireResult = { module: {}, error: undefined } | { module: undefined, error: {} };
|
||||
export interface ServerHost extends System {
|
||||
setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
clearTimeout(timeoutId: any): void;
|
||||
@@ -16,6 +17,7 @@ declare namespace ts.server {
|
||||
clearImmediate(timeoutId: any): void;
|
||||
gc?(): void;
|
||||
trace?(s: string): void;
|
||||
require?(initialPath: string, moduleName: string): RequireResult;
|
||||
}
|
||||
|
||||
export interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
|
||||
|
||||
@@ -295,8 +295,7 @@ namespace ts.server.typingsInstaller {
|
||||
this.log.writeLine(`Installing typings ${JSON.stringify(typingsToInstall)}`);
|
||||
}
|
||||
const filteredTypings = this.filterTypings(typingsToInstall);
|
||||
const scopedTypings = filteredTypings.map(x => `@types/${x}`);
|
||||
if (scopedTypings.length === 0) {
|
||||
if (filteredTypings.length === 0) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`All typings are known to be missing or invalid - no need to go any further`);
|
||||
}
|
||||
@@ -316,6 +315,7 @@ namespace ts.server.typingsInstaller {
|
||||
projectName: req.projectName
|
||||
});
|
||||
|
||||
const scopedTypings = filteredTypings.map(typingsName);
|
||||
this.installTypingsAsync(requestId, scopedTypings, cachePath, ok => {
|
||||
try {
|
||||
if (!ok) {
|
||||
@@ -429,4 +429,10 @@ namespace ts.server.typingsInstaller {
|
||||
protected abstract installWorker(requestId: number, args: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void;
|
||||
protected abstract sendResponse(response: SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes): void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function typingsName(packageName: string): string {
|
||||
return `@types/${packageName}@ts${versionMajorMinor}`;
|
||||
}
|
||||
const versionMajorMinor = version.split(".").slice(0, 2).join(".");
|
||||
}
|
||||
@@ -115,6 +115,7 @@ namespace ts.codefix {
|
||||
registerCodeFix({
|
||||
errorCodes: [
|
||||
Diagnostics.Cannot_find_name_0.code,
|
||||
Diagnostics.Cannot_find_namespace_0.code,
|
||||
Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code
|
||||
],
|
||||
getCodeActions: (context: CodeFixContext) => {
|
||||
@@ -416,8 +417,8 @@ namespace ts.codefix {
|
||||
);
|
||||
|
||||
function getModuleSpecifierForNewImport() {
|
||||
const fileName = sourceFile.path;
|
||||
const moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().path;
|
||||
const fileName = sourceFile.fileName;
|
||||
const moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().fileName;
|
||||
const sourceDirectory = getDirectoryPath(fileName);
|
||||
const options = context.program.getCompilerOptions();
|
||||
|
||||
@@ -439,8 +440,7 @@ namespace ts.codefix {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const normalizedBaseUrl = toPath(options.baseUrl, getDirectoryPath(options.baseUrl), getCanonicalFileName);
|
||||
let relativeName = tryRemoveParentDirectoryName(moduleFileName, normalizedBaseUrl);
|
||||
let relativeName = getRelativePathIfInDirectory(moduleFileName, options.baseUrl);
|
||||
if (!relativeName) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -477,9 +477,8 @@ namespace ts.codefix {
|
||||
|
||||
function tryGetModuleNameFromRootDirs() {
|
||||
if (options.rootDirs) {
|
||||
const normalizedRootDirs = map(options.rootDirs, rootDir => toPath(rootDir, /*basePath*/ undefined, getCanonicalFileName));
|
||||
const normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, normalizedRootDirs);
|
||||
const normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, normalizedRootDirs);
|
||||
const normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, options.rootDirs);
|
||||
const normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, options.rootDirs);
|
||||
if (normalizedTargetPath !== undefined) {
|
||||
const relativePath = normalizedSourcePath !== undefined ? getRelativePath(normalizedTargetPath, normalizedSourcePath) : normalizedTargetPath;
|
||||
return removeFileExtension(relativePath);
|
||||
@@ -546,9 +545,9 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
|
||||
function getPathRelativeToRootDirs(path: Path, rootDirs: Path[]) {
|
||||
function getPathRelativeToRootDirs(path: string, rootDirs: string[]) {
|
||||
for (const rootDir of rootDirs) {
|
||||
const relativeName = tryRemoveParentDirectoryName(path, rootDir);
|
||||
const relativeName = getRelativePathIfInDirectory(path, rootDir);
|
||||
if (relativeName !== undefined) {
|
||||
return relativeName;
|
||||
}
|
||||
@@ -564,20 +563,15 @@ namespace ts.codefix {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
function getRelativePathIfInDirectory(path: string, directoryPath: string) {
|
||||
const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, false);
|
||||
return isRootedDiskPath(relativePath) || startsWith(relativePath, "..") ? undefined : relativePath;
|
||||
}
|
||||
|
||||
function getRelativePath(path: string, directoryPath: string) {
|
||||
const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, false);
|
||||
return moduleHasNonRelativeName(relativePath) ? "./" + relativePath : relativePath;
|
||||
}
|
||||
|
||||
function tryRemoveParentDirectoryName(path: Path, parentDirectory: Path) {
|
||||
const index = path.indexOf(parentDirectory);
|
||||
if (index === 0) {
|
||||
return endsWith(parentDirectory, directorySeparator)
|
||||
? path.substring(parentDirectory.length)
|
||||
: path.substring(parentDirectory.length + 1);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace ts.codefix {
|
||||
const forStatement = <ForStatement>token.parent.parent.parent;
|
||||
const forInitializer = <VariableDeclarationList>forStatement.initializer;
|
||||
if (forInitializer.declarations.length === 1) {
|
||||
return createCodeFix("", forInitializer.pos, forInitializer.end - forInitializer.pos);
|
||||
return createCodeFixToRemoveNode(forInitializer);
|
||||
}
|
||||
else {
|
||||
return removeSingleItem(forInitializer.declarations, token);
|
||||
@@ -35,7 +35,7 @@ namespace ts.codefix {
|
||||
const forOfStatement = <ForOfStatement>token.parent.parent.parent;
|
||||
if (forOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList) {
|
||||
const forOfInitializer = <VariableDeclarationList>forOfStatement.initializer;
|
||||
return createCodeFix("{}", forOfInitializer.declarations[0].pos, forOfInitializer.declarations[0].end - forOfInitializer.declarations[0].pos);
|
||||
return createCodeFix("{}", forOfInitializer.declarations[0].getStart(), forOfInitializer.declarations[0].getWidth());
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -47,12 +47,12 @@ namespace ts.codefix {
|
||||
case SyntaxKind.CatchClause:
|
||||
const catchClause = <CatchClause>token.parent.parent;
|
||||
const parameter = catchClause.variableDeclaration.getChildren()[0];
|
||||
return createCodeFix("", parameter.pos, parameter.end - parameter.pos);
|
||||
return createCodeFixToRemoveNode(parameter);
|
||||
|
||||
default:
|
||||
const variableStatement = <VariableStatement>token.parent.parent.parent;
|
||||
if (variableStatement.declarationList.declarations.length === 1) {
|
||||
return createCodeFix("", variableStatement.pos, variableStatement.end - variableStatement.pos);
|
||||
return createCodeFixToRemoveNode(variableStatement);
|
||||
}
|
||||
else {
|
||||
const declarations = variableStatement.declarationList.declarations;
|
||||
@@ -72,7 +72,7 @@ namespace ts.codefix {
|
||||
case ts.SyntaxKind.Parameter:
|
||||
const functionDeclaration = <FunctionDeclaration>token.parent.parent;
|
||||
if (functionDeclaration.parameters.length === 1) {
|
||||
return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos);
|
||||
return createCodeFixToRemoveNode(token.parent);
|
||||
}
|
||||
else {
|
||||
return removeSingleItem(functionDeclaration.parameters, token);
|
||||
@@ -81,36 +81,43 @@ namespace ts.codefix {
|
||||
// handle case where 'import a = A;'
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
const importEquals = findImportDeclaration(token);
|
||||
return createCodeFix("", importEquals.pos, importEquals.end - importEquals.pos);
|
||||
return createCodeFixToRemoveNode(importEquals);
|
||||
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
const namedImports = <NamedImports>token.parent.parent;
|
||||
if (namedImports.elements.length === 1) {
|
||||
// Only 1 import and it is unused. So the entire declaration should be removed.
|
||||
const importSpec = findImportDeclaration(token);
|
||||
return createCodeFix("", importSpec.pos, importSpec.end - importSpec.pos);
|
||||
return createCodeFixToRemoveNode(importSpec);
|
||||
}
|
||||
else {
|
||||
return removeSingleItem(namedImports.elements, token);
|
||||
}
|
||||
|
||||
// handle case where "import d, * as ns from './file'"
|
||||
// handle case where "import d, * as ns from './file'"
|
||||
// or "'import {a, b as ns} from './file'"
|
||||
case SyntaxKind.ImportClause: // this covers both 'import |d|' and 'import |d,| *'
|
||||
case SyntaxKind.ImportClause: // this covers both 'import |d|' and 'import |d,| *'
|
||||
const importClause = <ImportClause>token.parent;
|
||||
if (!importClause.namedBindings) { // |import d from './file'| or |import * as ns from './file'|
|
||||
const importDecl = findImportDeclaration(importClause);
|
||||
return createCodeFix("", importDecl.pos, importDecl.end - importDecl.pos);
|
||||
return createCodeFixToRemoveNode(importDecl);
|
||||
}
|
||||
else { // import |d,| * as ns from './file'
|
||||
return createCodeFix("", importClause.name.pos, importClause.namedBindings.pos - importClause.name.pos);
|
||||
else {
|
||||
// import |d,| * as ns from './file'
|
||||
const start = importClause.name.getStart();
|
||||
let end = findFirstNonSpaceCharPosStarting(importClause.name.end);
|
||||
if (sourceFile.text.charCodeAt(end) === CharacterCodes.comma) {
|
||||
end = findFirstNonSpaceCharPosStarting(end + 1);
|
||||
}
|
||||
|
||||
return createCodeFix("", start, end - start);
|
||||
}
|
||||
|
||||
case SyntaxKind.NamespaceImport:
|
||||
const namespaceImport = <NamespaceImport>token.parent;
|
||||
if (namespaceImport.name == token && !(<ImportClause>namespaceImport.parent).name) {
|
||||
const importDecl = findImportDeclaration(namespaceImport);
|
||||
return createCodeFix("", importDecl.pos, importDecl.end - importDecl.pos);
|
||||
return createCodeFixToRemoveNode(importDecl);
|
||||
}
|
||||
else {
|
||||
const start = (<ImportClause>namespaceImport.parent).name.end;
|
||||
@@ -120,16 +127,14 @@ namespace ts.codefix {
|
||||
break;
|
||||
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos);
|
||||
|
||||
case SyntaxKind.NamespaceImport:
|
||||
return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos);
|
||||
return createCodeFixToRemoveNode(token.parent);
|
||||
}
|
||||
if (isDeclarationName(token)) {
|
||||
return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos);
|
||||
return createCodeFixToRemoveNode(token.parent);
|
||||
}
|
||||
else if (isLiteralComputedPropertyDeclarationName(token)) {
|
||||
return createCodeFix("", token.parent.parent.pos, token.parent.parent.end - token.parent.parent.pos);
|
||||
return createCodeFixToRemoveNode(token.parent.parent);
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
@@ -144,6 +149,30 @@ namespace ts.codefix {
|
||||
return importDecl;
|
||||
}
|
||||
|
||||
function createCodeFixToRemoveNode(node: Node) {
|
||||
let end = node.getEnd();
|
||||
const endCharCode = sourceFile.text.charCodeAt(end);
|
||||
const afterEndCharCode = sourceFile.text.charCodeAt(end + 1);
|
||||
if (isLineBreak(endCharCode)) {
|
||||
end += 1;
|
||||
}
|
||||
// in the case of CR LF, you could have two consecutive new line characters for one new line.
|
||||
// this needs to be differenciated from two LF LF chars that actually mean two new lines.
|
||||
if (isLineBreak(afterEndCharCode) && endCharCode !== afterEndCharCode) {
|
||||
end += 1;
|
||||
}
|
||||
|
||||
const start = node.getStart();
|
||||
return createCodeFix("", start, end - start);
|
||||
}
|
||||
|
||||
function findFirstNonSpaceCharPosStarting(start: number) {
|
||||
while (isWhiteSpace(sourceFile.text.charCodeAt(start))) {
|
||||
start += 1;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
function createCodeFix(newText: string, start: number, length: number): CodeAction[] {
|
||||
return [{
|
||||
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Remove_declaration_for_Colon_0), { 0: token.getText() }),
|
||||
|
||||
+48
-10
@@ -173,6 +173,18 @@ namespace ts.Completions {
|
||||
// var y = require("/*completion position*/");
|
||||
return getStringLiteralCompletionEntriesFromModuleNames(<StringLiteral>node, compilerOptions, host, typeChecker);
|
||||
}
|
||||
else if (isEqualityExpression(node.parent)) {
|
||||
// Get completions from the type of the other operand
|
||||
// i.e. switch (a) {
|
||||
// case '/*completion position*/'
|
||||
// }
|
||||
return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation(node.parent.left === node ? node.parent.right : node.parent.left), typeChecker);
|
||||
}
|
||||
else if (isCaseOrDefaultClause(node.parent)) {
|
||||
// Get completions from the type of the switch expression
|
||||
// i.e. x === '/*completion position'
|
||||
return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation((<SwitchStatement>node.parent.parent.parent).expression), typeChecker);
|
||||
}
|
||||
else {
|
||||
const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile);
|
||||
if (argumentInfo) {
|
||||
@@ -184,7 +196,7 @@ namespace ts.Completions {
|
||||
|
||||
// Get completion for string literal from string literal type
|
||||
// i.e. var x: "hi" | "hello" = "/*completion position*/"
|
||||
return getStringLiteralCompletionEntriesFromContextualType(<StringLiteral>node, typeChecker);
|
||||
return getStringLiteralCompletionEntriesFromType(typeChecker.getContextualType(<StringLiteral>node), typeChecker);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,8 +240,7 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getStringLiteralCompletionEntriesFromContextualType(node: StringLiteral, typeChecker: TypeChecker): CompletionInfo | undefined {
|
||||
const type = typeChecker.getContextualType(node);
|
||||
function getStringLiteralCompletionEntriesFromType(type: Type, typeChecker: TypeChecker): CompletionInfo | undefined {
|
||||
if (type) {
|
||||
const entries: CompletionEntry[] = [];
|
||||
addStringLiteralCompletionsFromType(type, entries, typeChecker);
|
||||
@@ -904,13 +915,29 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
else if (sourceFile.languageVariant === LanguageVariant.JSX) {
|
||||
if (kind === SyntaxKind.LessThanToken) {
|
||||
isRightOfOpenTag = true;
|
||||
location = contextToken;
|
||||
}
|
||||
else if (kind === SyntaxKind.SlashToken && contextToken.parent.kind === SyntaxKind.JsxClosingElement) {
|
||||
isStartingCloseTag = true;
|
||||
location = contextToken;
|
||||
switch (contextToken.parent.kind) {
|
||||
case SyntaxKind.JsxClosingElement:
|
||||
if (kind === SyntaxKind.SlashToken) {
|
||||
isStartingCloseTag = true;
|
||||
location = contextToken;
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.BinaryExpression:
|
||||
if (!((contextToken.parent as BinaryExpression).left.flags & NodeFlags.ThisNodeHasError)) {
|
||||
// It has a left-hand side, so we're not in an opening JSX tag.
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxElement:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
if (kind === SyntaxKind.LessThanToken) {
|
||||
isRightOfOpenTag = true;
|
||||
location = contextToken;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1773,4 +1800,15 @@ namespace ts.Completions {
|
||||
catch (e) {}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isEqualityExpression(node: Node): node is BinaryExpression {
|
||||
return isBinaryExpression(node) && isEqualityOperatorKind(node.operatorToken.kind);
|
||||
}
|
||||
|
||||
function isEqualityOperatorKind(kind: SyntaxKind) {
|
||||
return kind == SyntaxKind.EqualsEqualsToken ||
|
||||
kind === SyntaxKind.ExclamationEqualsToken ||
|
||||
kind === SyntaxKind.EqualsEqualsEqualsToken ||
|
||||
kind === SyntaxKind.ExclamationEqualsEqualsToken;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@ namespace ts.FindAllReferences {
|
||||
return getReferencedSymbolsForNode(typeChecker, cancellationToken, node, sourceFiles, findInStrings, findInComments, isForRename);
|
||||
}
|
||||
|
||||
export function convertReferences(referenceSymbols: ReferencedSymbol[]): ReferenceEntry[] {
|
||||
return referenceSymbols && flatMap(referenceSymbols, r => r.references);
|
||||
}
|
||||
|
||||
export function getReferencedSymbolsForNode(typeChecker: TypeChecker, cancellationToken: CancellationToken, node: Node, sourceFiles: SourceFile[], findInStrings?: boolean, findInComments?: boolean, isForRename?: boolean, implementations?: boolean): ReferencedSymbol[] | undefined {
|
||||
if (!implementations) {
|
||||
const special = getReferencedSymbolsSpecial(node, sourceFiles, typeChecker, cancellationToken);
|
||||
@@ -277,7 +281,7 @@ namespace ts.FindAllReferences {
|
||||
|
||||
// if this symbol is visible from its parent container, e.g. exported, then bail out
|
||||
// if symbol correspond to the union property - bail out
|
||||
if (symbol.parent || (symbol.flags & SymbolFlags.SyntheticProperty)) {
|
||||
if (symbol.parent || (symbol.flags & SymbolFlags.Transient && (<TransientSymbol>symbol).checkFlags & CheckFlags.SyntheticProperty)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -402,22 +406,24 @@ namespace ts.FindAllReferences {
|
||||
|
||||
function getAllReferencesForKeyword(sourceFiles: SourceFile[], keywordKind: ts.SyntaxKind, cancellationToken: CancellationToken): ReferencedSymbol[] {
|
||||
const name = tokenToString(keywordKind);
|
||||
const definition: ReferencedSymbolDefinitionInfo = {
|
||||
containerKind: "",
|
||||
containerName: "",
|
||||
fileName: "",
|
||||
kind: ScriptElementKind.keyword,
|
||||
name,
|
||||
textSpan: createTextSpan(0, 1),
|
||||
displayParts: [{ text: name, kind: ScriptElementKind.keyword }]
|
||||
}
|
||||
|
||||
const references: ReferenceEntry[] = [];
|
||||
for (const sourceFile of sourceFiles) {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
addReferencesForKeywordInFile(sourceFile, keywordKind, name, cancellationToken, references);
|
||||
}
|
||||
|
||||
if (!references.length) return undefined;
|
||||
|
||||
const definition: ReferencedSymbolDefinitionInfo = {
|
||||
containerKind: "",
|
||||
containerName: "",
|
||||
fileName: references[0].fileName,
|
||||
kind: ScriptElementKind.keyword,
|
||||
name,
|
||||
textSpan: references[0].textSpan,
|
||||
displayParts: [{ text: name, kind: ScriptElementKind.keyword }]
|
||||
}
|
||||
|
||||
return [{ definition, references }];
|
||||
}
|
||||
|
||||
@@ -1316,20 +1322,6 @@ namespace ts.FindAllReferences {
|
||||
return meaning;
|
||||
}
|
||||
|
||||
export function convertReferences(referenceSymbols: ReferencedSymbol[]): ReferenceEntry[] {
|
||||
if (!referenceSymbols) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const referenceEntries: ReferenceEntry[] = [];
|
||||
|
||||
for (const referenceSymbol of referenceSymbols) {
|
||||
addRange(referenceEntries, referenceSymbol.references);
|
||||
}
|
||||
|
||||
return referenceEntries;
|
||||
}
|
||||
|
||||
function isImplementation(node: Node): boolean {
|
||||
if (!node) {
|
||||
return false;
|
||||
|
||||
@@ -1415,7 +1415,6 @@ namespace ts {
|
||||
|
||||
function findReferences(fileName: string, position: number): ReferencedSymbol[] {
|
||||
const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false, /*isForRename*/false);
|
||||
|
||||
// Only include referenced symbols that have a valid definition.
|
||||
return filter(referencedSymbols, rs => !!rs.definition);
|
||||
}
|
||||
@@ -1689,7 +1688,7 @@ namespace ts {
|
||||
|
||||
let allFixes: CodeAction[] = [];
|
||||
|
||||
forEach(errorCodes, error => {
|
||||
forEach(deduplicate(errorCodes), error => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
const context = {
|
||||
@@ -2075,9 +2074,5 @@ namespace ts {
|
||||
throw new Error("getDefaultLibFilePath is only supported when consumed as a node module. ");
|
||||
}
|
||||
|
||||
function initializeServices() {
|
||||
objectAllocator = getServicesObjectAllocator();
|
||||
}
|
||||
|
||||
initializeServices();
|
||||
objectAllocator = getServicesObjectAllocator();
|
||||
}
|
||||
|
||||
@@ -1269,4 +1269,4 @@ namespace TypeScript.Services {
|
||||
// TODO: it should be moved into a namespace though.
|
||||
|
||||
/* @internal */
|
||||
const toolsVersion = "2.2";
|
||||
const toolsVersion = "2.3";
|
||||
@@ -51,7 +51,7 @@ namespace ts.SymbolDisplay {
|
||||
if (flags & SymbolFlags.Constructor) return ScriptElementKind.constructorImplementationElement;
|
||||
|
||||
if (flags & SymbolFlags.Property) {
|
||||
if (flags & SymbolFlags.SyntheticProperty) {
|
||||
if (flags & SymbolFlags.Transient && (<TransientSymbol>symbol).checkFlags & CheckFlags.SyntheticProperty) {
|
||||
// If union property is result of union of non method (property/accessors/variables), it is labeled as property
|
||||
const unionPropertyKind = forEach(typeChecker.getRootSymbols(symbol), rootSymbol => {
|
||||
const rootSymbolFlags = rootSymbol.getFlags();
|
||||
|
||||
@@ -41,6 +41,7 @@ compile(process.argv.slice(2), {
|
||||
* Please log a "breaking change" issue for any API breaking change affecting this issue
|
||||
*/
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var ts = require("typescript");
|
||||
function compile(fileNames, options) {
|
||||
var program = ts.createProgram(fileNames, options);
|
||||
|
||||
@@ -71,6 +71,7 @@ fileNames.forEach(fileName => {
|
||||
* Please log a "breaking change" issue for any API breaking change affecting this issue
|
||||
*/
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var ts = require("typescript");
|
||||
function delint(sourceFile) {
|
||||
delintNode(sourceFile);
|
||||
|
||||
@@ -43,6 +43,7 @@ export function createProgram(rootFiles: string[], compilerOptionsJson: string):
|
||||
* Please log a "breaking change" issue for any API breaking change affecting this issue
|
||||
*/
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var ts = require("typescript");
|
||||
function printError(error) {
|
||||
if (!error) {
|
||||
|
||||
@@ -23,6 +23,7 @@ console.log(JSON.stringify(result));
|
||||
* Please log a "breaking change" issue for any API breaking change affecting this issue
|
||||
*/
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var ts = require("typescript");
|
||||
var source = "let x: string = 'string'";
|
||||
var result = ts.transpile(source, { module: ts.ModuleKind.CommonJS });
|
||||
|
||||
@@ -116,6 +116,7 @@ watch(currentDirectoryFiles, { module: ts.ModuleKind.CommonJS });
|
||||
* Please log a "breaking change" issue for any API breaking change affecting this issue
|
||||
*/
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var ts = require("typescript");
|
||||
function watch(rootFileNames, options) {
|
||||
var files = {};
|
||||
|
||||
+2
@@ -31,6 +31,7 @@ export module A {
|
||||
|
||||
//// [part1.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var A;
|
||||
(function (A) {
|
||||
var Utils;
|
||||
@@ -44,6 +45,7 @@ var A;
|
||||
})(A = exports.A || (exports.A = {}));
|
||||
//// [part2.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var A;
|
||||
(function (A) {
|
||||
// collision with 'Origin' var in other part of merged module
|
||||
|
||||
@@ -12,7 +12,7 @@ function f1(x: Color | string) {
|
||||
|
||||
if (typeof x === "number") {
|
||||
>typeof x === "number" : boolean
|
||||
>typeof x : string
|
||||
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : string | Color
|
||||
>"number" : "number"
|
||||
|
||||
@@ -41,7 +41,7 @@ function f2(x: Color | string | string[]) {
|
||||
|
||||
if (typeof x === "object") {
|
||||
>typeof x === "object" : boolean
|
||||
>typeof x : string
|
||||
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : string | Color | string[]
|
||||
>"object" : "object"
|
||||
|
||||
@@ -54,7 +54,7 @@ function f2(x: Color | string | string[]) {
|
||||
}
|
||||
if (typeof x === "number") {
|
||||
>typeof x === "number" : boolean
|
||||
>typeof x : string
|
||||
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : string | Color | string[]
|
||||
>"number" : "number"
|
||||
|
||||
@@ -76,7 +76,7 @@ function f2(x: Color | string | string[]) {
|
||||
}
|
||||
if (typeof x === "string") {
|
||||
>typeof x === "string" : boolean
|
||||
>typeof x : string
|
||||
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>x : string | Color | string[]
|
||||
>"string" : "string"
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ y = moduleA; // should be error
|
||||
|
||||
//// [aliasAssignments_moduleA.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var someClass = (function () {
|
||||
function someClass() {
|
||||
}
|
||||
@@ -23,6 +24,7 @@ var someClass = (function () {
|
||||
exports.someClass = someClass;
|
||||
//// [aliasAssignments_1.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var moduleA = require("./aliasAssignments_moduleA");
|
||||
var x = moduleA;
|
||||
x = 1; // Should be error
|
||||
|
||||
@@ -24,6 +24,7 @@ var x: foo.A = foo.bar("hello"); // foo.A should be ok but foo.bar should be err
|
||||
//// [aliasOnMergedModuleInterface_0.js]
|
||||
//// [aliasOnMergedModuleInterface_1.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var z;
|
||||
z.bar("hello"); // This should be ok
|
||||
var x = foo.bar("hello"); // foo.A should be ok but foo.bar should be error
|
||||
|
||||
@@ -29,6 +29,7 @@ class C2 {
|
||||
|
||||
//// [aliasUsage1_backbone.js]
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -47,6 +48,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var Backbone = require("./aliasUsage1_backbone");
|
||||
var VisualizationModel = (function (_super) {
|
||||
__extends(VisualizationModel, _super);
|
||||
@@ -58,6 +60,7 @@ var VisualizationModel = (function (_super) {
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsage1_main.js]
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var moduleA = require("./aliasUsage1_moduleA");
|
||||
var C2 = (function () {
|
||||
function C2() {
|
||||
|
||||
@@ -23,6 +23,7 @@ var xs2: typeof moduleA[] = [moduleA];
|
||||
|
||||
//// [aliasUsageInArray_backbone.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -41,6 +42,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var Backbone = require("./aliasUsageInArray_backbone");
|
||||
var VisualizationModel = (function (_super) {
|
||||
__extends(VisualizationModel, _super);
|
||||
@@ -52,6 +54,7 @@ var VisualizationModel = (function (_super) {
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsageInArray_main.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var moduleA = require("./aliasUsageInArray_moduleA");
|
||||
var xs = [moduleA];
|
||||
var xs2 = [moduleA];
|
||||
|
||||
@@ -22,6 +22,7 @@ f = (x) => moduleA;
|
||||
|
||||
//// [aliasUsageInFunctionExpression_backbone.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -40,6 +41,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var Backbone = require("./aliasUsageInFunctionExpression_backbone");
|
||||
var VisualizationModel = (function (_super) {
|
||||
__extends(VisualizationModel, _super);
|
||||
@@ -51,6 +53,7 @@ var VisualizationModel = (function (_super) {
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsageInFunctionExpression_main.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var moduleA = require("./aliasUsageInFunctionExpression_moduleA");
|
||||
var f = function (x) { return x; };
|
||||
f = function (x) { return moduleA; };
|
||||
|
||||
@@ -26,6 +26,7 @@ var r2 = foo({ a: <IHasVisualizationModel>null });
|
||||
|
||||
//// [aliasUsageInGenericFunction_backbone.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -44,6 +45,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var Backbone = require("./aliasUsageInGenericFunction_backbone");
|
||||
var VisualizationModel = (function (_super) {
|
||||
__extends(VisualizationModel, _super);
|
||||
@@ -55,6 +57,7 @@ var VisualizationModel = (function (_super) {
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsageInGenericFunction_main.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var moduleA = require("./aliasUsageInGenericFunction_moduleA");
|
||||
function foo(x) {
|
||||
return x;
|
||||
|
||||
@@ -28,6 +28,7 @@ class N2 {
|
||||
|
||||
//// [aliasUsageInIndexerOfClass_backbone.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -46,6 +47,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var Backbone = require("./aliasUsageInIndexerOfClass_backbone");
|
||||
var VisualizationModel = (function (_super) {
|
||||
__extends(VisualizationModel, _super);
|
||||
@@ -57,6 +59,7 @@ var VisualizationModel = (function (_super) {
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsageInIndexerOfClass_main.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var moduleA = require("./aliasUsageInIndexerOfClass_moduleA");
|
||||
var N = (function () {
|
||||
function N() {
|
||||
|
||||
@@ -23,6 +23,7 @@ var c: { y: { z: IHasVisualizationModel } } = { y: { z: moduleA } };
|
||||
|
||||
//// [aliasUsageInObjectLiteral_backbone.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -41,6 +42,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var Backbone = require("./aliasUsageInObjectLiteral_backbone");
|
||||
var VisualizationModel = (function (_super) {
|
||||
__extends(VisualizationModel, _super);
|
||||
@@ -52,6 +54,7 @@ var VisualizationModel = (function (_super) {
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsageInObjectLiteral_main.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var moduleA = require("./aliasUsageInObjectLiteral_moduleA");
|
||||
var a = { x: moduleA };
|
||||
var b = { x: moduleA };
|
||||
|
||||
@@ -26,6 +26,7 @@ var f: { x: IHasVisualizationModel } = <{ x: IHasVisualizationModel }>null ? { x
|
||||
|
||||
//// [aliasUsageInOrExpression_backbone.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -44,6 +45,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var Backbone = require("./aliasUsageInOrExpression_backbone");
|
||||
var VisualizationModel = (function (_super) {
|
||||
__extends(VisualizationModel, _super);
|
||||
@@ -55,6 +57,7 @@ var VisualizationModel = (function (_super) {
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsageInOrExpression_main.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var moduleA = require("./aliasUsageInOrExpression_moduleA");
|
||||
var i;
|
||||
var d1 = i || moduleA;
|
||||
|
||||
@@ -26,6 +26,7 @@ class D extends C<IHasVisualizationModel> {
|
||||
|
||||
//// [aliasUsageInTypeArgumentOfExtendsClause_backbone.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -44,6 +45,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var Backbone = require("./aliasUsageInTypeArgumentOfExtendsClause_backbone");
|
||||
var VisualizationModel = (function (_super) {
|
||||
__extends(VisualizationModel, _super);
|
||||
@@ -65,6 +67,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var moduleA = require("./aliasUsageInTypeArgumentOfExtendsClause_moduleA");
|
||||
var C = (function () {
|
||||
function C() {
|
||||
|
||||
@@ -22,6 +22,7 @@ var m: typeof moduleA = i;
|
||||
|
||||
//// [aliasUsageInVarAssignment_backbone.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var Model = (function () {
|
||||
function Model() {
|
||||
}
|
||||
@@ -40,6 +41,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var Backbone = require("./aliasUsageInVarAssignment_backbone");
|
||||
var VisualizationModel = (function (_super) {
|
||||
__extends(VisualizationModel, _super);
|
||||
@@ -51,5 +53,6 @@ var VisualizationModel = (function (_super) {
|
||||
exports.VisualizationModel = VisualizationModel;
|
||||
//// [aliasUsageInVarAssignment_main.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var i;
|
||||
var m = i;
|
||||
|
||||
@@ -20,12 +20,15 @@ export var a = function () {
|
||||
|
||||
//// [aliasUsedAsNameValue_0.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
//// [aliasUsedAsNameValue_1.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
function b(a) { return null; }
|
||||
exports.b = b;
|
||||
//// [aliasUsedAsNameValue_2.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
///<reference path='aliasUsedAsNameValue_0.ts' />
|
||||
///<reference path='aliasUsedAsNameValue_1.ts' />
|
||||
var mod = require("./aliasUsedAsNameValue_0");
|
||||
|
||||
@@ -12,6 +12,8 @@ var d = b.q3;
|
||||
|
||||
//// [aliasWithInterfaceExportAssignmentUsedInVarInitializer_0.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
//// [aliasWithInterfaceExportAssignmentUsedInVarInitializer_1.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var d = b.q3;
|
||||
|
||||
@@ -12,6 +12,7 @@ export class Foo {
|
||||
|
||||
//// [b.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var Foo = (function () {
|
||||
function Foo() {
|
||||
}
|
||||
@@ -20,5 +21,6 @@ var Foo = (function () {
|
||||
exports.Foo = Foo;
|
||||
//// [a.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var b_1 = require("./b");
|
||||
exports.x = new b_1["default"].Foo();
|
||||
|
||||
@@ -12,6 +12,7 @@ Foo.default.default.foo();
|
||||
|
||||
//// [a.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var Foo = require("./b");
|
||||
Foo["default"].bar();
|
||||
Foo["default"]["default"].foo();
|
||||
|
||||
@@ -13,5 +13,6 @@ export var x = new Foo();
|
||||
|
||||
//// [a.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var b_1 = require("./b");
|
||||
exports.x = new b_1["default"]();
|
||||
|
||||
@@ -12,6 +12,7 @@ Foo.foo();
|
||||
|
||||
//// [a.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var b_1 = require("./b");
|
||||
b_1["default"].bar();
|
||||
b_1["default"].foo();
|
||||
|
||||
@@ -5,5 +5,6 @@ export const a = 1
|
||||
|
||||
//// [alwaysStrictModule4.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
// Module commonjs
|
||||
exports.a = 1;
|
||||
|
||||
@@ -5,5 +5,6 @@ export const a = 1;
|
||||
|
||||
//// [alwaysStrictModule6.js]
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
// Targeting ES5
|
||||
exports.a = 1;
|
||||
|
||||
@@ -28,6 +28,7 @@ var n: number;
|
||||
// Ambient external import declaration referencing ambient external module using top level module name
|
||||
//// [consumer.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
// Ambient external module members are always exported with or without export keyword when module lacks export assignment
|
||||
var imp3 = require("equ2");
|
||||
var n = imp3.x;
|
||||
|
||||
@@ -34,6 +34,7 @@ foo(fileText);
|
||||
|
||||
//// [user.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
///<reference path="declarations.d.ts" />
|
||||
var foobarbaz_1 = require("foobarbaz");
|
||||
foobarbaz_1.foo(foobarbaz_1.baz);
|
||||
|
||||
@@ -4,4 +4,5 @@ export declare module "M" { }
|
||||
//// [ambientExternalModuleInsideNonAmbientExternalModule.js]
|
||||
define(["require", "exports"], function (require, exports) {
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
});
|
||||
|
||||
@@ -19,6 +19,7 @@ declare module "M" {
|
||||
//// [ambientExternalModuleMerging_use.js]
|
||||
define(["require", "exports", "M"], function (require, exports, M) {
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
// Should be strings
|
||||
var x = M.x;
|
||||
var y = M.y;
|
||||
|
||||
@@ -22,5 +22,6 @@ var c = new A();
|
||||
//// [ambientExternalModuleWithInternalImportDeclaration_1.js]
|
||||
define(["require", "exports", "M"], function (require, exports, A) {
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var c = new A();
|
||||
});
|
||||
|
||||
@@ -21,5 +21,6 @@ var c = new A();
|
||||
//// [ambientExternalModuleWithoutInternalImportDeclaration_1.js]
|
||||
define(["require", "exports", "M"], function (require, exports, A) {
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var c = new A();
|
||||
});
|
||||
|
||||
@@ -8,4 +8,5 @@ export declare module M { }
|
||||
//// [ambientInsideNonAmbientExternalModule.js]
|
||||
define(["require", "exports"], function (require, exports) {
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
});
|
||||
|
||||
@@ -6,3 +6,4 @@ export declare namespace Foo {
|
||||
|
||||
//// [ambientNameRestrictions.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
|
||||
@@ -15,6 +15,7 @@ foo(bar, baz, boom);
|
||||
|
||||
//// [user.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
///<reference path="declarations.d.ts"/>
|
||||
var jquery_1 = require("jquery");
|
||||
var baz = require("fs");
|
||||
|
||||
@@ -14,3 +14,4 @@ import foo from "foo";
|
||||
|
||||
//// [user.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
|
||||
@@ -16,3 +16,4 @@ import foo, {bar} from "foo";
|
||||
|
||||
//// [user.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user