mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-12 11:36:43 -06:00
Merge branch 'master' into common_source_directory
This commit is contained in:
commit
b65729e5b2
43
.mailmap
43
.mailmap
@ -1,32 +1,38 @@
|
||||
|
||||
Alexander <alexander@kuvaev.me># Alexander Kuvaev
|
||||
AbubakerB <abubaker_bashir@hotmail.com> # Abubaker Bashir
|
||||
Alexander <alexander@kuvaev.me># Alexander Kuvaev
|
||||
Adam Freidin <adam.freidin@gmail.com> Adam Freidin <afreidin@adobe.com>
|
||||
Adi Dahiya <adahiya@palantir.com> Adi Dahiya <adi.dahiya14@gmail.com>
|
||||
Ahmad Farid <ahfarid@microsoft.com> ahmad-farid <ahfarid@microsoft.com>
|
||||
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>
|
||||
Andrej Baran <andrej.baran@gmail.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>
|
||||
Arnavion <arnavion@gmail.com> # Arnav Singh
|
||||
Arthur Ozga <aozgaa@umich.edu> Arthur Ozga <t-arthoz@microsoft.com>
|
||||
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>
|
||||
Schmavery <avery.schmavery@gmail.com> # Avery Morin
|
||||
Basarat Ali Syed <basaratali@gmail.com> Basarat Syed <basaratali@gmail.com> basarat <basaratali@gmail.com>
|
||||
Bill Ticehurst <billti@hotmail.com> Bill Ticehurst <billti@microsoft.com>
|
||||
Ben Duffield <jebavarde@gmail.com>
|
||||
Ben Mosher <me@benmosher.com>
|
||||
Blake Embrey <hello@blakeembrey.com>
|
||||
Bowden Kelly <wilkelly@microsoft.com>
|
||||
Brett Mayen <bmayen@midnightsnacks.net>
|
||||
Bryan Forbes <bryan@reigndropsfall.net>
|
||||
Caitlin Potter <caitpotter88@gmail.com>
|
||||
ChrisBubernak <chris.bubernak@gmail.com> unknown <chrbub@chrbub1.redmond.corp.microsoft.com> # Chris Bubernak
|
||||
Christophe Vidal <kriss@krizalys.com>
|
||||
Chuck Jazdzewski <chuckj@google.com>
|
||||
Colby Russell <mr@colbyrussell.com>
|
||||
Colin Snover <github.com@zetafleet.com>
|
||||
Cyrus Najmabadi <cyrusn@microsoft.com> CyrusNajmabadi <cyrusn@microsoft.com> unknown <cyrusn@cylap.ntdev.corp.microsoft.com>
|
||||
Dafrok <o.o@mug.dog> # Dafrok Zhang
|
||||
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>
|
||||
@ -36,17 +42,22 @@ Denis Nedelyaev <denvned@gmail.com>
|
||||
Dick van den Brink <d_vandenbrink@outlook.com> unknown <d_vandenbrink@outlook.com> unknown <d_vandenbrink@live.com>
|
||||
Dirk Baeumer <dirkb@microsoft.com> Dirk Bäumer <dirkb@microsoft.com> # Dirk Bäumer
|
||||
Dirk Holtwick <dirk.holtwick@gmail.com>
|
||||
Dom Chen <domchen@users.noreply.github.com>
|
||||
Doug Ilijev <dilijev@users.noreply.github.com>
|
||||
Erik Edrosa <erik.edrosa@gmail.com>
|
||||
erictsangx <erictsangx@gmail.com> # Eric Tsang
|
||||
Ethan Rubio <ethanrubio@users.noreply.github.com>
|
||||
Evan Martin <martine@danga.com>
|
||||
Evan Sebastian <evanlhoini@gmail.com>
|
||||
Eyas <eyas.sharaiha@gmail.com> # Eyas Sharaiha
|
||||
Fabian Cook <faybecook@gmail.com>
|
||||
falsandtru <falsandtru@users.noreply.github.com> # @falsandtru
|
||||
Frank Wallis <fwallis@outlook.com>
|
||||
František Žiačik <fziacik@gratex.com> František Žiačik <ziacik@gmail.com>
|
||||
František Žiacik <fziacik@gratex.com> František Žiacik <ziacik@gmail.com>
|
||||
Gabe Moothart <gmoothart@gmail.com>
|
||||
Gabriel Isenberg <gisenberg@gmail.com>
|
||||
Gilad Peleg <giladp007@gmail.com>
|
||||
Godfrey Chan <godfreykfc@gmail.com>
|
||||
Graeme Wicksted <graeme.wicksted@gmail.com>
|
||||
Guillaume Salles <guillaume.salles@me.com>
|
||||
Guy Bedford <guybedford@gmail.com> guybedford <guybedford@gmail.com>
|
||||
@ -55,6 +66,7 @@ Iain Monro <iain.monro@softwire.com>
|
||||
Ingvar Stepanyan <me@rreverser.com>
|
||||
impinball <impinball@gmail.com> # Isiah Meadows
|
||||
Ivo Gabe de Wolff <ivogabe@ivogabe.nl>
|
||||
Jakub Młokosiewicz <hckr@users.noreply.github.com>
|
||||
James Whitney <james@whitney.io>
|
||||
Jason Freeman <jfreeman@microsoft.com> Jason Freeman <JsonFreeman@users.noreply.github.com>
|
||||
Jason Killian <jkillian@palantir.com>
|
||||
@ -69,11 +81,14 @@ 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>
|
||||
Josh Abernathy <joshaber@gmail.com> joshaber <joshaber@gmail.com>
|
||||
Josh Kalderimis <josh.kalderimis@gmail.com>
|
||||
Josh Soref <jsoref@users.noreply.github.com>
|
||||
Juan Luis Boya García <ntrrgc@gmail.com>
|
||||
Julian Williams <julianjw92@gmail.com>
|
||||
Herrington Darkholme <nonamesheep1@gmail.com>
|
||||
Justin Bay <justin.bay@outlook.com>
|
||||
Justin Johansson <thebabellion@gmail.com>
|
||||
Herrington Darkholme <nonamesheep1@gmail.com> (´·?·`) <HerringtonDarkholme@users.noreply.github.com> # Herrington Darkholme
|
||||
Kagami Sascha Rosylight <saschanaz@outlook.com> SaschaNaz <saschanaz@outlook.com>
|
||||
Kanchalai Tanglertsampan <yuisu@microsoft.com> Yui <yuit@users.noreply.github.com>
|
||||
Kanchalai Tanglertsampan <yuisu@microsoft.com> Yui T <yuisu@microsoft.com>
|
||||
@ -82,23 +97,29 @@ Kanchalai Tanglertsampan <yuisu@microsoft.com> Yui <yuisu@microsoft.com>
|
||||
Kanchalai Tanglertsampan <yuisu@microsoft.com> yui T <yuisu@microsoft.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
|
||||
Kyle Kelley <rgbkrk@gmail.com>
|
||||
Lorant Pinter <lorant.pinter@prezi.com>
|
||||
Lucien Greathouse <me@lpghatguy.com>
|
||||
Lukas Elmer <lukas.elmer@gmail.com> Lukas Elmer <lukas.elmer@renuo.ch>
|
||||
Martin Vseticka <vseticka.martin@gmail.com> Martin Všeticka <vseticka.martin@gmail.com> MartyIX <vseticka.martin@gmail.com>
|
||||
gcnew <gcnew@abv.bg> # Marin Marinov
|
||||
vvakame <vvakame+dev@gmail.com> # Masahiro Wakame
|
||||
Matt McCutchen <rmccutch@mit.edu>
|
||||
Max Deepfield <maxdeepfield@absolutefreakout.com>
|
||||
Micah Zoltu <micah@zoltu.net>
|
||||
Michael <maykelchiche@gmail.com>
|
||||
Mohamed Hegazy <mhegazy@microsoft.com>
|
||||
Nathan Shively-Sanders <nathansa@microsoft.com>
|
||||
Nathan Yee <ny.nathan.yee@gmail.com>
|
||||
Nima Zahedi <nima.zahedee@gmail.com>
|
||||
Noah Chen <nchen@palantir.com>
|
||||
Noj Vek <nojvek@gmail.com>
|
||||
mihailik <mihailik@gmail.com> # Oleg Mihailik
|
||||
Oleksandr Chekhovskyi <oleksandr.chekhovskyi@hansoft.com>
|
||||
Paul van Brenk <paul.van.brenk@microsoft.com> Paul van Brenk <paul.van.brenk@outlook.com> unknown <paul.van.brenk@microsoft.com> unknown <paul.van.brenk@microsoft.com> unknown <pvanbren@pvbvsproai.redmond.corp.microsoft.com>
|
||||
Omer Sheikh <ojsheikh@gmail.com>
|
||||
Oskar Segersva¨rd <oskar.segersvard@widespace.com>
|
||||
pcan <piero.cangianiello@gmail.com> # Piero Cangianiello
|
||||
pcbro <2bux89+dk3zspjmuh16o@sharklasers.com> # @pcbro
|
||||
@ -109,21 +130,26 @@ progre <djyayutto@gmail.com> # @progre
|
||||
Prayag Verma <prayag.verma@gmail.com>
|
||||
Punya Biswal <pbiswal@palantir.com>
|
||||
Rado Kirov <radokirov@google.com>
|
||||
Ron Buckton <rbuckton@microsoft.com> Ron Buckton <ron.buckton@microsoft.com>
|
||||
Ron Buckton <rbuckton@microsoft.com> Ron Buckton <ron.buckton@microsoft.com> rbuckton <rbuckton@chronicles.org>
|
||||
Rostislav Galimsky <rostgal@gmail.com>
|
||||
Richard Knoll <riknoll@users.noreply.github.com> Richard Knoll <riknoll@microsoft.com>
|
||||
Rowan Wyborn <rwyborn@internode.on.net>
|
||||
Ryan Cavanaugh <RyanCavanaugh@users.noreply.github.com> Ryan Cavanaugh <ryan.cavanaugh@microsoft.com> Ryan Cavanaugh <ryanca@microsoft.com>
|
||||
Ryohei Ikegami <iofg2100@gmail.com>
|
||||
Sarangan Rajamanickam <sarajama@microsoft.com>
|
||||
Sébastien Arod <sebastien.arod@gmail.com>
|
||||
Sergey Shandar <sergey-shandar@users.noreply.github.com>
|
||||
Sheetal Nandi <shkamat@microsoft.com>
|
||||
Shengping Zhong <zhongsp@users.noreply.github.com>
|
||||
shyyko.serhiy@gmail.com <shyyko.serhiy@gmail.com> # Shyyko Serhiy
|
||||
Sam El-Husseini <samelh@microsoft.com>
|
||||
Simon Hürlimann <simon.huerlimann@cyt.ch>
|
||||
Slawomir Sadziak <slsadzia@microsoft.com>
|
||||
Solal Pirelli <solal.pirelli@gmail.com>
|
||||
Stan Thomas <stmsdn@norvil.net>
|
||||
Stanislav Sysoev <d4rkr00t@gmail.com>
|
||||
Steve Lucco <steveluc@users.noreply.github.com> steveluc <steveluc@microsoft.com>
|
||||
Sudheesh Singanamalla <sudheesh1995@outlook.com>
|
||||
Tarik <tarik@pushmote.com> # Tarik Ozket
|
||||
Tetsuharu OHZEKI <saneyuki.snyk@gmail.com> # Tetsuharu Ohzeki
|
||||
Tien Nguyen <tihoanh@microsoft.com> tien <hoanhtien@users.noreply.github.com> unknown <tihoanh@microsoft.com> #Tien Hoanhtien
|
||||
@ -133,6 +159,7 @@ Tingan Ho <tingan87@gmail.com>
|
||||
togru <v3nomzxgt8@gmail.com> # togru
|
||||
Tomas Grubliauskas <tgrubliauskas@gmail.com>
|
||||
ToddThomson <achilles@telus.net> # Todd Thomson
|
||||
Torben Fitschen <torben.fitschen@mayflower.de>
|
||||
TruongSinh Tran-Nguyen <i@truongsinh.pro>
|
||||
vilicvane <i@vilic.info> # Vilic Vane
|
||||
Vladimir Matveev <vladima@microsoft.com> vladima <vladima@microsoft.com> v2m <desco.by@gmail.com>
|
||||
@ -140,7 +167,9 @@ Wesley Wigham <t-weswig@microsoft.com> Wesley Wigham <wwigham@gmail.com>
|
||||
York Yao <plantain-00@users.noreply.github.com> york yao <yaoao12306@outlook.com> yaoyao <yaoyao12306@163.com>
|
||||
Yuichi Nukiyama <oscar.wilde84@hotmail.co.jp> YuichiNukiyama <oscar.wilde84@hotmail.co.jp>
|
||||
Zev Spitz <shivisi@etrog.net.il>
|
||||
Zhengbo Li <zhengbli@microsoft.com> zhengbli <zhengbli@microsoft.com> Zhengbo Li <Zhengbo Li> Zhengbo Li <zhengbli@mirosoft.com> tinza123 <li.zhengbo@outlook.com> unknown <zhengbli@zhengblit430.redmond.corp.microsoft.com> Zhengbo Li <Zhengbo Li>
|
||||
Zhengbo Li <zhengbli@microsoft.com> zhengbli <zhengbli@microsoft.com> Zhengbo Li <Zhengbo Li> Zhengbo Li <zhengbli@mirosoft.com> tinza123 <li.zhengbo@outlook.com> unknown <zhengbli@zhengblit430.redmond.corp.microsoft.com> Zhengbo Li <Zhengbo Li> zhengbli <zhengli@microsoft.com>
|
||||
zhongsp <patrick.zhongsp@gmail.com> # Patrick Zhong
|
||||
T18970237136 <T18970237136@users.noreply.github.com> # @T18970237136
|
||||
JBerger <JBerger@melco.com>
|
||||
JBerger <JBerger@melco.com>
|
||||
bootstraponline <code@bootstraponline.com> # @bootstraponline
|
||||
yortus <yortus@gmail.com> # @yortus
|
||||
32
AUTHORS.md
32
AUTHORS.md
@ -5,7 +5,10 @@ TypeScript is authored by:
|
||||
* Ahmad Farid
|
||||
* Alex Eagle
|
||||
* Alexander Kuvaev
|
||||
* Alexander Rusakov
|
||||
* Anatoly Ressin
|
||||
* Anders Hejlsberg
|
||||
* Andrej Baran
|
||||
* Andrew Z Allen
|
||||
* Andy Hanson
|
||||
* Anil Anar
|
||||
@ -16,17 +19,21 @@ TypeScript is authored by:
|
||||
* Avery Morin
|
||||
* Basarat Ali Syed
|
||||
* Ben Duffield
|
||||
* Ben Mosher
|
||||
* Bill Ticehurst
|
||||
* Blake Embrey
|
||||
* @bootstraponline
|
||||
* Bowden Kelly
|
||||
* Brett Mayen
|
||||
* Bryan Forbes
|
||||
* Caitlin Potter
|
||||
* Chris Bubernak
|
||||
* Christophe Vidal
|
||||
* Chuck Jazdzewski
|
||||
* Colby Russell
|
||||
* Colin Snover
|
||||
* Cyrus Najmabadi
|
||||
* Dafrok Zhang
|
||||
* Dan Corder
|
||||
* Dan Quirk
|
||||
* Daniel Rosenwasser
|
||||
@ -36,17 +43,22 @@ TypeScript is authored by:
|
||||
* Dick van den Brink
|
||||
* Dirk Bäumer
|
||||
* Dirk Holtwick
|
||||
* Dom Chen
|
||||
* Doug Ilijev
|
||||
* Eric Tsang
|
||||
* Erik Edrosa
|
||||
* Ethan Rubio
|
||||
* Evan Martin
|
||||
* Evan Sebastian
|
||||
* Eyas Sharaiha
|
||||
* Fabian Cook
|
||||
* @falsandtru
|
||||
* Frank Wallis
|
||||
* František Žiačik
|
||||
* František Žiacik
|
||||
* Gabe Moothart
|
||||
* Gabriel Isenberg
|
||||
* Gilad Peleg
|
||||
* Godfrey Chan
|
||||
* Graeme Wicksted
|
||||
* Guillaume Salles
|
||||
* Guy Bedford
|
||||
@ -56,6 +68,7 @@ TypeScript is authored by:
|
||||
* Ingvar Stepanyan
|
||||
* Isiah Meadows
|
||||
* Ivo Gabe de Wolff
|
||||
* Jakub Młokosiewicz
|
||||
* James Whitney
|
||||
* Jason Freeman
|
||||
* Jason Killian
|
||||
@ -71,30 +84,39 @@ TypeScript is authored by:
|
||||
* Jonathan Park
|
||||
* Jonathan Toland
|
||||
* Jonathan Turner
|
||||
* Josh Abernathy
|
||||
* Josh Kalderimis
|
||||
* Josh Soref
|
||||
* Juan Luis Boya García
|
||||
* Julian Williams
|
||||
* Justin Bay
|
||||
* Justin Johansson
|
||||
* Kagami Sascha Rosylight
|
||||
* Kanchalai Tanglertsampan
|
||||
* Keith Mashinter
|
||||
* Ken Howard
|
||||
* Kenji Imamula
|
||||
* Kevin Lang
|
||||
* Kyle Kelley
|
||||
* Lorant Pinter
|
||||
* Lucien Greathouse
|
||||
* Lukas Elmer
|
||||
* Marin Marinov
|
||||
* Martin Vseticka
|
||||
* Masahiro Wakame
|
||||
* Matt McCutchen
|
||||
* Max Deepfield
|
||||
* Micah Zoltu
|
||||
* Michael
|
||||
* Mohamed Hegazy
|
||||
* Nathan Shively-Sanders
|
||||
* Nathan Yee
|
||||
* Nima Zahedi
|
||||
* Noah Chen
|
||||
* Noj Vek
|
||||
* Oleg Mihailik
|
||||
* Oleksandr Chekhovskyi
|
||||
* Omer Sheikh
|
||||
* Oskar Segersva¨rd
|
||||
* Patrick Zhong
|
||||
* Paul van Brenk
|
||||
@ -109,21 +131,27 @@ TypeScript is authored by:
|
||||
* Rado Kirov
|
||||
* Richard Knoll
|
||||
* Ron Buckton
|
||||
* Rostislav Galimsky
|
||||
* Rowan Wyborn
|
||||
* Ryan Cavanaugh
|
||||
* Ryohei Ikegami
|
||||
* Sam El-Husseini
|
||||
* Sarangan Rajamanickam
|
||||
* Sergey Shandar
|
||||
* Sheetal Nandi
|
||||
* Shengping Zhong
|
||||
* Shyyko Serhiy
|
||||
* Simon Hürlimann
|
||||
* Slawomir Sadziak
|
||||
* Solal Pirelli
|
||||
* Stan Thomas
|
||||
* Stanislav Sysoev
|
||||
* Steve Lucco
|
||||
* Sudheesh Singanamalla
|
||||
* Sébastien Arod
|
||||
* @T18970237136
|
||||
* Tarik Ozket
|
||||
* Tetsuharu Ohzeki
|
||||
* Tien Hoanhtien
|
||||
* Tim Perry
|
||||
* Tim Viiding-Spader
|
||||
@ -131,11 +159,13 @@ TypeScript is authored by:
|
||||
* Todd Thomson
|
||||
* togru
|
||||
* Tomas Grubliauskas
|
||||
* Torben Fitschen
|
||||
* TruongSinh Tran-Nguyen
|
||||
* Vilic Vane
|
||||
* Vladimir Matveev
|
||||
* Wesley Wigham
|
||||
* York Yao
|
||||
* @yortus
|
||||
* Yuichi Nukiyama
|
||||
* Zev Spitz
|
||||
* Zhengbo Li
|
||||
@ -128,7 +128,8 @@ const es2016LibrarySourceMap = es2016LibrarySource.map(function(source) {
|
||||
|
||||
const es2017LibrarySource = [
|
||||
"es2017.object.d.ts",
|
||||
"es2017.sharedmemory.d.ts"
|
||||
"es2017.sharedmemory.d.ts",
|
||||
"es2017.string.d.ts",
|
||||
];
|
||||
|
||||
const es2017LibrarySourceMap = es2017LibrarySource.map(function(source) {
|
||||
|
||||
@ -71,6 +71,7 @@ var compilerSources = [
|
||||
"transformers/destructuring.ts",
|
||||
"transformers/ts.ts",
|
||||
"transformers/jsx.ts",
|
||||
"transformers/esnext.ts",
|
||||
"transformers/es2017.ts",
|
||||
"transformers/es2016.ts",
|
||||
"transformers/es2015.ts",
|
||||
@ -107,6 +108,7 @@ var servicesSources = [
|
||||
"transformers/destructuring.ts",
|
||||
"transformers/ts.ts",
|
||||
"transformers/jsx.ts",
|
||||
"transformers/esnext.ts",
|
||||
"transformers/es2017.ts",
|
||||
"transformers/es2016.ts",
|
||||
"transformers/es2015.ts",
|
||||
@ -171,6 +173,7 @@ var servicesSources = [
|
||||
|
||||
var serverCoreSources = [
|
||||
"types.d.ts",
|
||||
"shared.ts",
|
||||
"utilities.ts",
|
||||
"scriptVersionCache.ts",
|
||||
"typingsCache.ts",
|
||||
@ -193,6 +196,7 @@ var cancellationTokenSources = [
|
||||
|
||||
var typingsInstallerSources = [
|
||||
"../types.d.ts",
|
||||
"../shared.ts",
|
||||
"typingsInstaller.ts",
|
||||
"nodeTypingsInstaller.ts"
|
||||
].map(function (f) {
|
||||
@ -299,7 +303,8 @@ var es2016LibrarySourceMap = es2016LibrarySource.map(function (source) {
|
||||
|
||||
var es2017LibrarySource = [
|
||||
"es2017.object.d.ts",
|
||||
"es2017.sharedmemory.d.ts"
|
||||
"es2017.sharedmemory.d.ts",
|
||||
"es2017.string.d.ts",
|
||||
];
|
||||
|
||||
var es2017LibrarySourceMap = es2017LibrarySource.map(function (source) {
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"name": "typescript",
|
||||
"author": "Microsoft Corp.",
|
||||
"homepage": "http://typescriptlang.org/",
|
||||
"version": "2.1.0",
|
||||
"version": "2.2.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "TypeScript is a language for application scale JavaScript development",
|
||||
"keywords": [
|
||||
@ -76,7 +76,7 @@
|
||||
"travis-fold": "latest",
|
||||
"ts-node": "latest",
|
||||
"tsd": "latest",
|
||||
"tslint": "next",
|
||||
"tslint": "4.0.0-dev.0",
|
||||
"typescript": "next"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@ -560,6 +560,7 @@ namespace ts {
|
||||
skipTransformFlagAggregation = true;
|
||||
bindChildrenWorker(node);
|
||||
skipTransformFlagAggregation = false;
|
||||
subtreeTransformFlags |= node.transformFlags & ~getTransformFlagsSubtreeExclusions(node.kind);
|
||||
}
|
||||
else {
|
||||
const savedSubtreeTransformFlags = subtreeTransformFlags;
|
||||
@ -895,8 +896,8 @@ namespace ts {
|
||||
const enclosingLabeledStatement = node.parent.kind === SyntaxKind.LabeledStatement
|
||||
? lastOrUndefined(activeLabels)
|
||||
: undefined;
|
||||
// if do statement is wrapped in labeled statement then target labels for break/continue with or without
|
||||
// label should be the same
|
||||
// if do statement is wrapped in labeled statement then target labels for break/continue with or without
|
||||
// label should be the same
|
||||
const preConditionLabel = enclosingLabeledStatement ? enclosingLabeledStatement.continueTarget : createBranchLabel();
|
||||
const postDoLabel = enclosingLabeledStatement ? enclosingLabeledStatement.breakTarget : createBranchLabel();
|
||||
addAntecedent(preDoLabel, currentFlow);
|
||||
@ -1138,8 +1139,8 @@ namespace ts {
|
||||
}
|
||||
else if (node.kind === SyntaxKind.ArrayLiteralExpression) {
|
||||
for (const e of (<ArrayLiteralExpression>node).elements) {
|
||||
if (e.kind === SyntaxKind.SpreadElementExpression) {
|
||||
bindAssignmentTargetFlow((<SpreadElementExpression>e).expression);
|
||||
if (e.kind === SyntaxKind.SpreadElement) {
|
||||
bindAssignmentTargetFlow((<SpreadElement>e).expression);
|
||||
}
|
||||
else {
|
||||
bindDestructuringTargetFlow(e);
|
||||
@ -1154,6 +1155,9 @@ namespace ts {
|
||||
else if (p.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
bindAssignmentTargetFlow((<ShorthandPropertyAssignment>p).name);
|
||||
}
|
||||
else if (p.kind === SyntaxKind.SpreadAssignment) {
|
||||
bindAssignmentTargetFlow((<SpreadAssignment>p).expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1234,9 +1238,11 @@ namespace ts {
|
||||
const postExpressionLabel = createBranchLabel();
|
||||
bindCondition(node.condition, trueLabel, falseLabel);
|
||||
currentFlow = finishFlowLabel(trueLabel);
|
||||
bind(node.questionToken);
|
||||
bind(node.whenTrue);
|
||||
addAntecedent(postExpressionLabel, currentFlow);
|
||||
currentFlow = finishFlowLabel(falseLabel);
|
||||
bind(node.colonToken);
|
||||
bind(node.whenFalse);
|
||||
addAntecedent(postExpressionLabel, currentFlow);
|
||||
currentFlow = finishFlowLabel(postExpressionLabel);
|
||||
@ -1547,7 +1553,7 @@ namespace ts {
|
||||
const seen = createMap<ElementKind>();
|
||||
|
||||
for (const prop of node.properties) {
|
||||
if (prop.name.kind !== SyntaxKind.Identifier) {
|
||||
if (prop.kind === SyntaxKind.SpreadAssignment || prop.name.kind !== SyntaxKind.Identifier) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1913,6 +1919,9 @@ namespace ts {
|
||||
return bindParameter(<ParameterDeclaration>node);
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
case SyntaxKind.BindingElement:
|
||||
if ((node as BindingElement).dotDotDotToken && node.parent.kind === SyntaxKind.ObjectBindingPattern) {
|
||||
emitFlags |= NodeFlags.HasRestAttribute;
|
||||
}
|
||||
return bindVariableDeclarationOrBindingElement(<VariableDeclaration | BindingElement>node);
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
@ -1926,8 +1935,21 @@ namespace ts {
|
||||
case SyntaxKind.EnumMember:
|
||||
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes);
|
||||
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
emitFlags |= NodeFlags.HasJsxSpreadAttributes;
|
||||
let root = container;
|
||||
let hasRest = false;
|
||||
while (root.parent) {
|
||||
if (root.kind === SyntaxKind.ObjectLiteralExpression &&
|
||||
root.parent.kind === SyntaxKind.BinaryExpression &&
|
||||
(root.parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken &&
|
||||
(root.parent as BinaryExpression).left === root) {
|
||||
hasRest = true;
|
||||
break;
|
||||
}
|
||||
root = root.parent;
|
||||
}
|
||||
emitFlags |= hasRest ? NodeFlags.HasRestAttribute : NodeFlags.HasSpreadAttribute;
|
||||
return;
|
||||
|
||||
case SyntaxKind.CallSignature:
|
||||
@ -2492,9 +2514,9 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression
|
||||
|| isSuperOrSuperProperty(expression, expressionKind)) {
|
||||
// If the this node contains a SpreadElementExpression, or is a super call, then it is an ES6
|
||||
// If the this node contains a SpreadExpression, or is a super call, then it is an ES6
|
||||
// node.
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
@ -2523,7 +2545,7 @@ namespace ts {
|
||||
if (node.typeArguments) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression) {
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
// If the this node contains a SpreadElementExpression then it is an ES6
|
||||
// node.
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
@ -2538,10 +2560,13 @@ namespace ts {
|
||||
const operatorTokenKind = node.operatorToken.kind;
|
||||
const leftKind = node.left.kind;
|
||||
|
||||
if (operatorTokenKind === SyntaxKind.EqualsToken
|
||||
&& (leftKind === SyntaxKind.ObjectLiteralExpression
|
||||
|| leftKind === SyntaxKind.ArrayLiteralExpression)) {
|
||||
// Destructuring assignments are ES6 syntax.
|
||||
if (operatorTokenKind === SyntaxKind.EqualsToken && leftKind === SyntaxKind.ObjectLiteralExpression) {
|
||||
// Destructuring object assignments with are ES2015 syntax
|
||||
// and possibly ESNext if they contain rest
|
||||
transformFlags |= TransformFlags.AssertESNext | TransformFlags.AssertES2015 | TransformFlags.AssertDestructuringAssignment;
|
||||
}
|
||||
else if (operatorTokenKind === SyntaxKind.EqualsToken && leftKind === SyntaxKind.ArrayLiteralExpression) {
|
||||
// Destructuring assignments are ES2015 syntax.
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.AssertDestructuringAssignment;
|
||||
}
|
||||
else if (operatorTokenKind === SyntaxKind.AsteriskAsteriskToken
|
||||
@ -2575,6 +2600,11 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.ContainsParameterPropertyAssignments;
|
||||
}
|
||||
|
||||
// parameters with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
// If a parameter has an initializer, a binding pattern or a dotDotDot token, then
|
||||
// it is ES6 syntax and its container must emit default value assignments or parameter destructuring downlevel.
|
||||
if (subtreeFlags & TransformFlags.ContainsBindingPattern || initializer || dotDotDotToken) {
|
||||
@ -2808,6 +2838,11 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
// If a FunctionDeclaration's subtree has marked the container as needing to capture the
|
||||
// lexical this, or the function contains parameters with initializers, then this node is
|
||||
// ES6 syntax.
|
||||
@ -2845,6 +2880,12 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
}
|
||||
|
||||
// function expressions with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
|
||||
// If a FunctionExpression's subtree has marked the container as needing to capture the
|
||||
// lexical this, or the function contains parameters with initializers, then this node is
|
||||
// ES6 syntax.
|
||||
@ -2882,6 +2923,11 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
}
|
||||
|
||||
// arrow functions with object rest destructuring are ES Next syntax
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
// If an ArrowFunction contains a lexical this, its container must capture the lexical this.
|
||||
if (subtreeFlags & TransformFlags.ContainsLexicalThis) {
|
||||
transformFlags |= TransformFlags.ContainsCapturedLexicalThis;
|
||||
@ -2910,8 +2956,13 @@ namespace ts {
|
||||
let transformFlags = subtreeFlags;
|
||||
const nameKind = node.name.kind;
|
||||
|
||||
// A VariableDeclaration with a binding pattern is ES6 syntax.
|
||||
if (nameKind === SyntaxKind.ObjectBindingPattern || nameKind === SyntaxKind.ArrayBindingPattern) {
|
||||
// A VariableDeclaration with an object binding pattern is ES2015 syntax
|
||||
// and possibly ESNext syntax if it contains an object binding pattern
|
||||
if (nameKind === SyntaxKind.ObjectBindingPattern) {
|
||||
transformFlags |= TransformFlags.AssertESNext | TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
|
||||
}
|
||||
// A VariableDeclaration with an object binding pattern is ES2015 syntax.
|
||||
else if (nameKind === SyntaxKind.ArrayBindingPattern) {
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
|
||||
}
|
||||
|
||||
@ -3052,6 +3103,10 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.AssertJsx;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ForOfStatement:
|
||||
// for-of might be ESNext if it has a rest destructuring
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
// FALLTHROUGH
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.TemplateHead:
|
||||
case SyntaxKind.TemplateMiddle:
|
||||
@ -3059,7 +3114,6 @@ namespace ts {
|
||||
case SyntaxKind.TemplateExpression:
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
case SyntaxKind.StaticKeyword:
|
||||
// These nodes are ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
@ -3123,11 +3177,18 @@ namespace ts {
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
// This node is ES6 syntax, but is handled by a containing node.
|
||||
transformFlags |= TransformFlags.ContainsSpreadElementExpression;
|
||||
case SyntaxKind.SpreadElement:
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
// This node is ES6 or ES next syntax, but is handled by a containing node.
|
||||
transformFlags |= TransformFlags.ContainsSpreadExpression;
|
||||
break;
|
||||
|
||||
case SyntaxKind.BindingElement:
|
||||
if ((node as BindingElement).dotDotDotToken) {
|
||||
// this node is ES2015 or ES next syntax, but is handled by a containing node.
|
||||
transformFlags |= TransformFlags.ContainsSpreadExpression;
|
||||
}
|
||||
|
||||
case SyntaxKind.SuperKeyword:
|
||||
// This node is ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
@ -3140,8 +3201,13 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
// These nodes are ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
|
||||
// These nodes are ES2015 or ES Next syntax.
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
transformFlags |= TransformFlags.AssertESNext | TransformFlags.ContainsBindingPattern;
|
||||
}
|
||||
else {
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern;
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.Decorator:
|
||||
@ -3163,13 +3229,19 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.ContainsLexicalThis;
|
||||
}
|
||||
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
// If an ObjectLiteralExpression contains a spread element, then it
|
||||
// is an ES next node.
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
excludeFlags = TransformFlags.ArrayLiteralOrCallOrNewExcludes;
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression) {
|
||||
// If the this node contains a SpreadElementExpression, then it is an ES6
|
||||
if (subtreeFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
// If the this node contains a SpreadExpression, then it is an ES6
|
||||
// node.
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
@ -3204,4 +3276,65 @@ namespace ts {
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
return transformFlags & ~excludeFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the transform flags to exclude when unioning the transform flags of a subtree.
|
||||
*
|
||||
* NOTE: This needs to be kept up-to-date with the exclusions used in `computeTransformFlagsForNode`.
|
||||
* For performance reasons, `computeTransformFlagsForNode` uses local constant values rather
|
||||
* than calling this function.
|
||||
*/
|
||||
/* @internal */
|
||||
export function getTransformFlagsSubtreeExclusions(kind: SyntaxKind) {
|
||||
if (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode) {
|
||||
return TransformFlags.TypeExcludes;
|
||||
}
|
||||
|
||||
switch (kind) {
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
return TransformFlags.ArrayLiteralOrCallOrNewExcludes;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return TransformFlags.ModuleExcludes;
|
||||
case SyntaxKind.Parameter:
|
||||
return TransformFlags.ParameterExcludes;
|
||||
case SyntaxKind.ArrowFunction:
|
||||
return TransformFlags.ArrowFunctionExcludes;
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
return TransformFlags.FunctionExcludes;
|
||||
case SyntaxKind.VariableDeclarationList:
|
||||
return TransformFlags.VariableDeclarationListExcludes;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.ClassExpression:
|
||||
return TransformFlags.ClassExcludes;
|
||||
case SyntaxKind.Constructor:
|
||||
return TransformFlags.ConstructorExcludes;
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
return TransformFlags.MethodOrAccessorExcludes;
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.VoidKeyword:
|
||||
case SyntaxKind.TypeParameter:
|
||||
case SyntaxKind.PropertySignature:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.IndexSignature:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
return TransformFlags.TypeExcludes;
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return TransformFlags.ObjectLiteralExcludes;
|
||||
default:
|
||||
return TransformFlags.NodeExcludes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -335,6 +335,9 @@ namespace ts {
|
||||
});
|
||||
|
||||
let jsxElementType: Type;
|
||||
let _jsxNamespace: string;
|
||||
let _jsxFactoryEntity: EntityName;
|
||||
|
||||
/** Things we lazy load from the JSX namespace */
|
||||
const jsxTypes = createMap<Type>();
|
||||
const JsxNames = {
|
||||
@ -372,6 +375,22 @@ namespace ts {
|
||||
|
||||
return checker;
|
||||
|
||||
function getJsxNamespace(): string {
|
||||
if (_jsxNamespace === undefined) {
|
||||
_jsxNamespace = "React";
|
||||
if (compilerOptions.jsxFactory) {
|
||||
_jsxFactoryEntity = parseIsolatedEntityName(compilerOptions.jsxFactory, languageVersion);
|
||||
if (_jsxFactoryEntity) {
|
||||
_jsxNamespace = getFirstIdentifier(_jsxFactoryEntity).text;
|
||||
}
|
||||
}
|
||||
else if (compilerOptions.reactNamespace) {
|
||||
_jsxNamespace = compilerOptions.reactNamespace;
|
||||
}
|
||||
}
|
||||
return _jsxNamespace;
|
||||
}
|
||||
|
||||
function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken) {
|
||||
// Ensure we have all the type information in place for this file so that all the
|
||||
// emitter questions of this resolver will return the right information.
|
||||
@ -2229,14 +2248,8 @@ namespace ts {
|
||||
// The specified symbol flags need to be reinterpreted as type flags
|
||||
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
|
||||
}
|
||||
else if (!(flags & TypeFormatFlags.InTypeAlias) && ((getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target) || type.flags & TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
|
||||
else if (!(flags & TypeFormatFlags.InTypeAlias) && (getObjectFlags(type) & ObjectFlags.Anonymous || type.flags & TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
|
||||
isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
|
||||
// We emit inferred type as type-alias at the current localtion if all the following is true
|
||||
// the input type is has alias symbol that is accessible
|
||||
// the input type is a union, intersection or anonymous type that is fully instantiated (if not we want to keep dive into)
|
||||
// e.g.: export type Bar<X, Y> = () => [X, Y];
|
||||
// export type Foo<Y> = Bar<any, Y>;
|
||||
// export const y = (x: Foo<string>) => 1 // we want to emit as ...x: () => [any, string])
|
||||
const typeArguments = type.aliasTypeArguments;
|
||||
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags);
|
||||
}
|
||||
@ -2500,6 +2513,13 @@ namespace ts {
|
||||
writePunctuation(writer, SyntaxKind.OpenBraceToken);
|
||||
writer.writeLine();
|
||||
writer.increaseIndent();
|
||||
writeObjectLiteralType(resolved);
|
||||
writer.decreaseIndent();
|
||||
writePunctuation(writer, SyntaxKind.CloseBraceToken);
|
||||
inObjectTypeLiteral = saveInObjectTypeLiteral;
|
||||
}
|
||||
|
||||
function writeObjectLiteralType(resolved: ResolvedType) {
|
||||
for (const signature of resolved.callSignatures) {
|
||||
buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, /*kind*/ undefined, symbolStack);
|
||||
writePunctuation(writer, SyntaxKind.SemicolonToken);
|
||||
@ -2532,11 +2552,8 @@ namespace ts {
|
||||
writer.writeLine();
|
||||
}
|
||||
}
|
||||
writer.decreaseIndent();
|
||||
writePunctuation(writer, SyntaxKind.CloseBraceToken);
|
||||
inObjectTypeLiteral = saveInObjectTypeLiteral;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags) {
|
||||
const targetSymbol = getTargetSymbol(symbol);
|
||||
@ -2978,26 +2995,31 @@ namespace ts {
|
||||
return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node, /*includeOptionality*/ false);
|
||||
}
|
||||
|
||||
function getTextOfPropertyName(name: PropertyName): string {
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return (<Identifier>name).text;
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return (<LiteralExpression>name).text;
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
if (isStringOrNumericLiteral((<ComputedPropertyName>name).expression.kind)) {
|
||||
return (<LiteralExpression>(<ComputedPropertyName>name).expression).text;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isComputedNonLiteralName(name: PropertyName): boolean {
|
||||
return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteral((<ComputedPropertyName>name).expression.kind);
|
||||
}
|
||||
|
||||
function getRestType(source: Type, properties: PropertyName[], symbol: Symbol): Type {
|
||||
Debug.assert(!!(source.flags & TypeFlags.Object), "Rest types only support object types right now.");
|
||||
const members = createMap<Symbol>();
|
||||
const names = createMap<true>();
|
||||
for (const name of properties) {
|
||||
names[getTextOfPropertyName(name)] = true;
|
||||
}
|
||||
for (const prop of getPropertiesOfType(source)) {
|
||||
const inNamesToRemove = prop.name in names;
|
||||
const isPrivate = getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected);
|
||||
const isMethod = prop.flags & SymbolFlags.Method;
|
||||
const isSetOnlyAccessor = prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor);
|
||||
if (!inNamesToRemove && !isPrivate && !isMethod && !isSetOnlyAccessor) {
|
||||
members[prop.name] = prop;
|
||||
}
|
||||
}
|
||||
const stringIndexInfo = getIndexInfoOfType(source, IndexKind.String);
|
||||
const numberIndexInfo = getIndexInfoOfType(source, IndexKind.Number);
|
||||
return createAnonymousType(symbol, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
|
||||
}
|
||||
|
||||
/** Return the inferred type for a binding element */
|
||||
function getTypeForBindingElement(declaration: BindingElement): Type {
|
||||
const pattern = <BindingPattern>declaration.parent;
|
||||
@ -3018,26 +3040,41 @@ namespace ts {
|
||||
|
||||
let type: Type;
|
||||
if (pattern.kind === SyntaxKind.ObjectBindingPattern) {
|
||||
// Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
|
||||
const name = declaration.propertyName || <Identifier>declaration.name;
|
||||
if (isComputedNonLiteralName(name)) {
|
||||
// computed properties with non-literal names are treated as 'any'
|
||||
return anyType;
|
||||
}
|
||||
if (declaration.initializer) {
|
||||
getContextualType(declaration.initializer);
|
||||
if (declaration.dotDotDotToken) {
|
||||
if (!(parentType.flags & TypeFlags.Object)) {
|
||||
error(declaration, Diagnostics.Rest_types_may_only_be_created_from_object_types);
|
||||
return unknownType;
|
||||
}
|
||||
const literalMembers: PropertyName[] = [];
|
||||
for (const element of pattern.elements) {
|
||||
if (element.kind !== SyntaxKind.OmittedExpression && !(element as BindingElement).dotDotDotToken) {
|
||||
literalMembers.push(element.propertyName || element.name as Identifier);
|
||||
}
|
||||
}
|
||||
type = getRestType(parentType, literalMembers, declaration.symbol);
|
||||
}
|
||||
else {
|
||||
// Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
|
||||
const name = declaration.propertyName || <Identifier>declaration.name;
|
||||
if (isComputedNonLiteralName(name)) {
|
||||
// computed properties with non-literal names are treated as 'any'
|
||||
return anyType;
|
||||
}
|
||||
if (declaration.initializer) {
|
||||
getContextualType(declaration.initializer);
|
||||
}
|
||||
|
||||
// Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature,
|
||||
// or otherwise the type of the string index signature.
|
||||
const text = getTextOfPropertyName(name);
|
||||
// Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature,
|
||||
// or otherwise the type of the string index signature.
|
||||
const text = getTextOfPropertyName(name);
|
||||
|
||||
type = getTypeOfPropertyOfType(parentType, text) ||
|
||||
isNumericLiteralName(text) && getIndexTypeOfType(parentType, IndexKind.Number) ||
|
||||
getIndexTypeOfType(parentType, IndexKind.String);
|
||||
if (!type) {
|
||||
error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), declarationNameToString(name));
|
||||
return unknownType;
|
||||
type = getTypeOfPropertyOfType(parentType, text) ||
|
||||
isNumericLiteralName(text) && getIndexTypeOfType(parentType, IndexKind.Number) ||
|
||||
getIndexTypeOfType(parentType, IndexKind.String);
|
||||
if (!type) {
|
||||
error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), declarationNameToString(name));
|
||||
return unknownType;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -3045,7 +3082,11 @@ namespace ts {
|
||||
// present (aka the tuple element property). This call also checks that the parentType is in
|
||||
// fact an iterable or array (depending on target language).
|
||||
const elementType = checkIteratedTypeOrElementType(parentType, pattern, /*allowStringInput*/ false);
|
||||
if (!declaration.dotDotDotToken) {
|
||||
if (declaration.dotDotDotToken) {
|
||||
// Rest element has an array type with the same element type as the parent type
|
||||
type = createArrayType(elementType);
|
||||
}
|
||||
else {
|
||||
// Use specific property type when parent is a tuple or numeric index type when parent is an array
|
||||
const propName = "" + indexOf(pattern.elements, declaration);
|
||||
type = isTupleLikeType(parentType)
|
||||
@ -3061,10 +3102,6 @@ namespace ts {
|
||||
return unknownType;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Rest element has an array type with the same element type as the parent type
|
||||
type = createArrayType(elementType);
|
||||
}
|
||||
}
|
||||
// In strict null checking mode, if a default value of a non-undefined type is specified, remove
|
||||
// undefined from the final type.
|
||||
@ -3245,8 +3282,8 @@ namespace ts {
|
||||
let hasComputedProperties = false;
|
||||
forEach(pattern.elements, e => {
|
||||
const name = e.propertyName || <Identifier>e.name;
|
||||
if (isComputedNonLiteralName(name)) {
|
||||
// do not include computed properties in the implied type
|
||||
if (isComputedNonLiteralName(name) || e.dotDotDotToken) {
|
||||
// do not include computed properties or rests in the implied type
|
||||
hasComputedProperties = true;
|
||||
return;
|
||||
}
|
||||
@ -4164,8 +4201,8 @@ namespace ts {
|
||||
else {
|
||||
mapper = createTypeMapper(typeParameters, typeArguments);
|
||||
members = createInstantiatedSymbolTable(source.declaredProperties, mapper, /*mappingThisOnly*/ typeParameters.length === 1);
|
||||
callSignatures = instantiateList(source.declaredCallSignatures, mapper, instantiateSignature);
|
||||
constructSignatures = instantiateList(source.declaredConstructSignatures, mapper, instantiateSignature);
|
||||
callSignatures = instantiateSignatures(source.declaredCallSignatures, mapper);
|
||||
constructSignatures = instantiateSignatures(source.declaredConstructSignatures, mapper);
|
||||
stringIndexInfo = instantiateIndexInfo(source.declaredStringIndexInfo, mapper);
|
||||
numberIndexInfo = instantiateIndexInfo(source.declaredNumberIndexInfo, mapper);
|
||||
}
|
||||
@ -4232,7 +4269,7 @@ namespace ts {
|
||||
for (const baseSig of baseSignatures) {
|
||||
const typeParamCount = baseSig.typeParameters ? baseSig.typeParameters.length : 0;
|
||||
if (typeParamCount === typeArgCount) {
|
||||
const sig = typeParamCount ? getSignatureInstantiation(baseSig, typeArguments) : cloneSignature(baseSig);
|
||||
const sig = typeParamCount ? createSignatureInstantiation(baseSig, typeArguments) : cloneSignature(baseSig);
|
||||
sig.typeParameters = classType.localTypeParameters;
|
||||
sig.resolvedReturnType = classType;
|
||||
result.push(sig);
|
||||
@ -4343,6 +4380,11 @@ namespace ts {
|
||||
getIntersectionType([info1.type, info2.type]), info1.isReadonly && info2.isReadonly);
|
||||
}
|
||||
|
||||
function unionSpreadIndexInfos(info1: IndexInfo, info2: IndexInfo): IndexInfo {
|
||||
return info1 && info2 && createIndexInfo(
|
||||
getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly);
|
||||
}
|
||||
|
||||
function resolveIntersectionTypeMembers(type: IntersectionType) {
|
||||
// The members and properties collections are empty for intersection types. To get all properties of an
|
||||
// intersection type use getPropertiesOfType (only the language service uses this).
|
||||
@ -4363,8 +4405,8 @@ namespace ts {
|
||||
const symbol = type.symbol;
|
||||
if (type.target) {
|
||||
const members = createInstantiatedSymbolTable(getPropertiesOfObjectType(type.target), type.mapper, /*mappingThisOnly*/ false);
|
||||
const callSignatures = instantiateList(getSignaturesOfType(type.target, SignatureKind.Call), type.mapper, instantiateSignature);
|
||||
const constructSignatures = instantiateList(getSignaturesOfType(type.target, SignatureKind.Construct), type.mapper, instantiateSignature);
|
||||
const callSignatures = instantiateSignatures(getSignaturesOfType(type.target, SignatureKind.Call), type.mapper);
|
||||
const constructSignatures = instantiateSignatures(getSignaturesOfType(type.target, SignatureKind.Construct), type.mapper);
|
||||
const stringIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, IndexKind.String), type.mapper);
|
||||
const numberIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, IndexKind.Number), type.mapper);
|
||||
setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
|
||||
@ -4479,7 +4521,9 @@ namespace ts {
|
||||
|
||||
function getPropertiesOfType(type: Type): Symbol[] {
|
||||
type = getApparentType(type);
|
||||
return type.flags & TypeFlags.UnionOrIntersection ? getPropertiesOfUnionOrIntersectionType(<UnionType>type) : getPropertiesOfObjectType(type);
|
||||
return type.flags & TypeFlags.UnionOrIntersection ?
|
||||
getPropertiesOfUnionOrIntersectionType(<UnionType>type) :
|
||||
getPropertiesOfObjectType(type);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4534,6 +4578,7 @@ namespace ts {
|
||||
if (isReadonlySymbol(prop)) {
|
||||
isReadonly = true;
|
||||
}
|
||||
|
||||
}
|
||||
else if (containingType.flags & TypeFlags.Union) {
|
||||
isPartial = true;
|
||||
@ -4982,6 +5027,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getSignatureInstantiation(signature: Signature, typeArguments: Type[]): Signature {
|
||||
const instantiations = signature.instantiations || (signature.instantiations = createMap<Signature>());
|
||||
const id = getTypeListId(typeArguments);
|
||||
return instantiations[id] || (instantiations[id] = createSignatureInstantiation(signature, typeArguments));
|
||||
}
|
||||
|
||||
function createSignatureInstantiation(signature: Signature, typeArguments: Type[]): Signature {
|
||||
return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), /*eraseTypeParameters*/ true);
|
||||
}
|
||||
|
||||
@ -5860,6 +5911,68 @@ namespace ts {
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Since the source of spread types are object literals, which are not binary,
|
||||
* this function should be called in a left folding style, with left = previous result of getSpreadType
|
||||
* and right = the new element to be spread.
|
||||
*/
|
||||
function getSpreadType(left: Type, right: Type, isFromObjectLiteral: boolean): ResolvedType | IntrinsicType {
|
||||
Debug.assert(!!(left.flags & (TypeFlags.Object | TypeFlags.Any)) && !!(right.flags & (TypeFlags.Object | TypeFlags.Any)), "Only object types may be spread.");
|
||||
if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) {
|
||||
return anyType;
|
||||
}
|
||||
const members = createMap<Symbol>();
|
||||
const skippedPrivateMembers = createMap<boolean>();
|
||||
let stringIndexInfo: IndexInfo;
|
||||
let numberIndexInfo: IndexInfo;
|
||||
if (left === emptyObjectType) {
|
||||
// for the first spread element, left === emptyObjectType, so take the right's string indexer
|
||||
stringIndexInfo = getIndexInfoOfType(right, IndexKind.String);
|
||||
numberIndexInfo = getIndexInfoOfType(right, IndexKind.Number);
|
||||
}
|
||||
else {
|
||||
stringIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, IndexKind.String), getIndexInfoOfType(right, IndexKind.String));
|
||||
numberIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, IndexKind.Number), getIndexInfoOfType(right, IndexKind.Number));
|
||||
}
|
||||
|
||||
for (const rightProp of getPropertiesOfType(right)) {
|
||||
// we approximate own properties as non-methods plus methods that are inside the object literal
|
||||
const isOwnProperty = !(rightProp.flags & SymbolFlags.Method) || isFromObjectLiteral;
|
||||
const isSetterWithoutGetter = rightProp.flags & SymbolFlags.SetAccessor && !(rightProp.flags & SymbolFlags.GetAccessor);
|
||||
if (getDeclarationModifierFlagsFromSymbol(rightProp) & (ModifierFlags.Private | ModifierFlags.Protected)) {
|
||||
skippedPrivateMembers[rightProp.name] = true;
|
||||
}
|
||||
else if (isOwnProperty && !isSetterWithoutGetter) {
|
||||
members[rightProp.name] = rightProp;
|
||||
}
|
||||
}
|
||||
for (const leftProp of getPropertiesOfType(left)) {
|
||||
if (leftProp.flags & SymbolFlags.SetAccessor && !(leftProp.flags & SymbolFlags.GetAccessor)
|
||||
|| leftProp.name in skippedPrivateMembers) {
|
||||
continue;
|
||||
}
|
||||
if (leftProp.name in members) {
|
||||
const rightProp = members[leftProp.name];
|
||||
const rightType = getTypeOfSymbol(rightProp);
|
||||
if (maybeTypeOfKind(rightType, TypeFlags.Undefined) || rightProp.flags & SymbolFlags.Optional) {
|
||||
const declarations: Declaration[] = concatenate(leftProp.declarations, rightProp.declarations);
|
||||
const flags = SymbolFlags.Property | SymbolFlags.Transient | (leftProp.flags & SymbolFlags.Optional);
|
||||
const result = <TransientSymbol>createSymbol(flags, leftProp.name);
|
||||
result.type = getUnionType([getTypeOfSymbol(leftProp), getTypeWithFacts(rightType, TypeFacts.NEUndefined)]);
|
||||
result.leftSpread = leftProp;
|
||||
result.rightSpread = rightProp;
|
||||
result.declarations = declarations;
|
||||
result.isReadonly = isReadonlySymbol(leftProp) || isReadonlySymbol(rightProp);
|
||||
members[leftProp.name] = result;
|
||||
}
|
||||
}
|
||||
else {
|
||||
members[leftProp.name] = leftProp;
|
||||
}
|
||||
}
|
||||
return createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
|
||||
}
|
||||
|
||||
function createLiteralType(flags: TypeFlags, text: string) {
|
||||
const type = <LiteralType>createType(flags);
|
||||
type.text = text;
|
||||
@ -6037,6 +6150,14 @@ namespace ts {
|
||||
return items;
|
||||
}
|
||||
|
||||
function instantiateTypes(types: Type[], mapper: TypeMapper) {
|
||||
return instantiateList(types, mapper, instantiateType);
|
||||
}
|
||||
|
||||
function instantiateSignatures(signatures: Signature[], mapper: TypeMapper) {
|
||||
return instantiateList(signatures, mapper, instantiateSignature);
|
||||
}
|
||||
|
||||
function createUnaryTypeMapper(source: Type, target: Type): TypeMapper {
|
||||
return t => t === source ? target : t;
|
||||
}
|
||||
@ -6063,7 +6184,6 @@ namespace ts {
|
||||
count == 2 ? createBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) :
|
||||
createArrayTypeMapper(sources, targets);
|
||||
mapper.mappedTypes = sources;
|
||||
mapper.targetTypes = targets;
|
||||
return mapper;
|
||||
}
|
||||
|
||||
@ -6190,7 +6310,7 @@ namespace ts {
|
||||
result.target = type;
|
||||
result.mapper = mapper;
|
||||
result.aliasSymbol = type.aliasSymbol;
|
||||
result.aliasTypeArguments = mapper.targetTypes;
|
||||
result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper);
|
||||
mapper.instantiations[type.id] = result;
|
||||
return result;
|
||||
}
|
||||
@ -6266,14 +6386,14 @@ namespace ts {
|
||||
instantiateAnonymousType(<AnonymousType>type, mapper) : type;
|
||||
}
|
||||
if ((<ObjectType>type).objectFlags & ObjectFlags.Reference) {
|
||||
return createTypeReference((<TypeReference>type).target, instantiateList((<TypeReference>type).typeArguments, mapper, instantiateType));
|
||||
return createTypeReference((<TypeReference>type).target, instantiateTypes((<TypeReference>type).typeArguments, mapper));
|
||||
}
|
||||
}
|
||||
if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Primitive)) {
|
||||
return getUnionType(instantiateList((<UnionType>type).types, mapper, instantiateType), /*subtypeReduction*/ false, type.aliasSymbol, mapper.targetTypes);
|
||||
return getUnionType(instantiateTypes((<UnionType>type).types, mapper), /*subtypeReduction*/ false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
}
|
||||
if (type.flags & TypeFlags.Intersection) {
|
||||
return getIntersectionType(instantiateList((<IntersectionType>type).types, mapper, instantiateType), type.aliasSymbol, mapper.targetTypes);
|
||||
return getIntersectionType(instantiateTypes((<IntersectionType>type).types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
}
|
||||
if (type.flags & TypeFlags.Index) {
|
||||
return getIndexType(instantiateType((<IndexType>type).type, mapper));
|
||||
@ -6723,9 +6843,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (!message) {
|
||||
message = relation === comparableRelation ?
|
||||
Diagnostics.Type_0_is_not_comparable_to_type_1 :
|
||||
Diagnostics.Type_0_is_not_assignable_to_type_1;
|
||||
if (relation === comparableRelation) {
|
||||
message = Diagnostics.Type_0_is_not_comparable_to_type_1;
|
||||
}
|
||||
else if (sourceType === targetType) {
|
||||
message = Diagnostics.Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated;
|
||||
}
|
||||
else {
|
||||
message = Diagnostics.Type_0_is_not_assignable_to_type_1;
|
||||
}
|
||||
}
|
||||
|
||||
reportError(message, sourceType, targetType);
|
||||
@ -6825,6 +6951,27 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (target.flags & TypeFlags.TypeParameter) {
|
||||
// Given a type parameter K with a constraint keyof T, a type S is
|
||||
// assignable to K if S is assignable to keyof T.
|
||||
const constraint = getConstraintOfTypeParameter(<TypeParameter>target);
|
||||
if (constraint && constraint.flags & TypeFlags.Index) {
|
||||
if (result = isRelatedTo(source, constraint, reportErrors)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (target.flags & TypeFlags.Index) {
|
||||
// Given a type parameter T with a constraint C, a type S is assignable to
|
||||
// keyof T if S is assignable to keyof C.
|
||||
const constraint = getConstraintOfTypeParameter((<IndexType>target).type);
|
||||
if (constraint) {
|
||||
if (result = isRelatedTo(source, getIndexType(constraint), reportErrors)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (source.flags & TypeFlags.TypeParameter) {
|
||||
let constraint = getConstraintOfTypeParameter(<TypeParameter>source);
|
||||
|
||||
@ -8543,7 +8690,7 @@ namespace ts {
|
||||
unknownType;
|
||||
}
|
||||
|
||||
function getTypeOfDestructuredSpreadElement(type: Type) {
|
||||
function getTypeOfDestructuredSpreadExpression(type: Type) {
|
||||
return createArrayType(checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false) || unknownType);
|
||||
}
|
||||
|
||||
@ -8557,8 +8704,8 @@ namespace ts {
|
||||
return getTypeOfDestructuredArrayElement(getAssignedType(node), indexOf(node.elements, element));
|
||||
}
|
||||
|
||||
function getAssignedTypeOfSpreadElement(node: SpreadElementExpression): Type {
|
||||
return getTypeOfDestructuredSpreadElement(getAssignedType(<ArrayLiteralExpression>node.parent));
|
||||
function getAssignedTypeOfSpreadExpression(node: SpreadElement): Type {
|
||||
return getTypeOfDestructuredSpreadExpression(getAssignedType(<ArrayLiteralExpression>node.parent));
|
||||
}
|
||||
|
||||
function getAssignedTypeOfPropertyAssignment(node: PropertyAssignment | ShorthandPropertyAssignment): Type {
|
||||
@ -8582,8 +8729,8 @@ namespace ts {
|
||||
return undefinedType;
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
return getAssignedTypeOfArrayLiteralElement(<ArrayLiteralExpression>parent, node);
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
return getAssignedTypeOfSpreadElement(<SpreadElementExpression>parent);
|
||||
case SyntaxKind.SpreadElement:
|
||||
return getAssignedTypeOfSpreadExpression(<SpreadElement>parent);
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
return getAssignedTypeOfPropertyAssignment(<PropertyAssignment>parent);
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
@ -8599,7 +8746,7 @@ namespace ts {
|
||||
getTypeOfDestructuredProperty(parentType, node.propertyName || <Identifier>node.name) :
|
||||
!node.dotDotDotToken ?
|
||||
getTypeOfDestructuredArrayElement(parentType, indexOf(pattern.elements, node)) :
|
||||
getTypeOfDestructuredSpreadElement(parentType);
|
||||
getTypeOfDestructuredSpreadExpression(parentType);
|
||||
return getTypeWithDefault(type, node.initializer);
|
||||
}
|
||||
|
||||
@ -10614,7 +10761,7 @@ namespace ts {
|
||||
return mapper && mapper.context;
|
||||
}
|
||||
|
||||
function checkSpreadElementExpression(node: SpreadElementExpression, contextualMapper?: TypeMapper): Type {
|
||||
function checkSpreadExpression(node: SpreadElement, contextualMapper?: TypeMapper): Type {
|
||||
// It is usually not safe to call checkExpressionCached if we can be contextually typing.
|
||||
// You can tell that we are contextually typing because of the contextualMapper parameter.
|
||||
// While it is true that a spread element can have a contextual type, it does not do anything
|
||||
@ -10636,7 +10783,7 @@ namespace ts {
|
||||
const elementTypes: Type[] = [];
|
||||
const inDestructuringPattern = isAssignmentTarget(node);
|
||||
for (const e of elements) {
|
||||
if (inDestructuringPattern && e.kind === SyntaxKind.SpreadElementExpression) {
|
||||
if (inDestructuringPattern && e.kind === SyntaxKind.SpreadElement) {
|
||||
// Given the following situation:
|
||||
// var c: {};
|
||||
// [...c] = ["", 0];
|
||||
@ -10649,7 +10796,7 @@ namespace ts {
|
||||
// get the contextual element type from it. So we do something similar to
|
||||
// getContextualTypeForElementExpression, which will crucially not error
|
||||
// if there is no index type / iterated type.
|
||||
const restArrayType = checkExpression((<SpreadElementExpression>e).expression, contextualMapper);
|
||||
const restArrayType = checkExpression((<SpreadElement>e).expression, contextualMapper);
|
||||
const restElementType = getIndexTypeOfType(restArrayType, IndexKind.Number) ||
|
||||
(languageVersion >= ScriptTarget.ES2015 ? getElementTypeOfIterable(restArrayType, /*errorNode*/ undefined) : undefined);
|
||||
if (restElementType) {
|
||||
@ -10660,7 +10807,7 @@ namespace ts {
|
||||
const type = checkExpressionForMutableLocation(e, contextualMapper);
|
||||
elementTypes.push(type);
|
||||
}
|
||||
hasSpreadElement = hasSpreadElement || e.kind === SyntaxKind.SpreadElementExpression;
|
||||
hasSpreadElement = hasSpreadElement || e.kind === SyntaxKind.SpreadElement;
|
||||
}
|
||||
if (!hasSpreadElement) {
|
||||
// If array literal is actually a destructuring pattern, mark it as an implied type. We do this such
|
||||
@ -10777,8 +10924,11 @@ namespace ts {
|
||||
// Grammar checking
|
||||
checkGrammarObjectLiteralExpression(node, inDestructuringPattern);
|
||||
|
||||
const propertiesTable = createMap<Symbol>();
|
||||
const propertiesArray: Symbol[] = [];
|
||||
let propertiesTable = createMap<Symbol>();
|
||||
let propertiesArray: Symbol[] = [];
|
||||
let spread: Type = emptyObjectType;
|
||||
let propagatedFlags: TypeFlags = 0;
|
||||
|
||||
const contextualType = getApparentTypeOfContextualType(node);
|
||||
const contextualTypeHasPattern = contextualType && contextualType.pattern &&
|
||||
(contextualType.pattern.kind === SyntaxKind.ObjectBindingPattern || contextualType.pattern.kind === SyntaxKind.ObjectLiteralExpression);
|
||||
@ -10803,6 +10953,7 @@ namespace ts {
|
||||
Debug.assert(memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment);
|
||||
type = checkExpressionForMutableLocation((<ShorthandPropertyAssignment>memberDecl).name, contextualMapper);
|
||||
}
|
||||
|
||||
typeFlags |= type.flags;
|
||||
const prop = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.name);
|
||||
if (inDestructuringPattern) {
|
||||
@ -10840,6 +10991,23 @@ namespace ts {
|
||||
prop.target = member;
|
||||
member = prop;
|
||||
}
|
||||
else if (memberDecl.kind === SyntaxKind.SpreadAssignment) {
|
||||
if (propertiesArray.length > 0) {
|
||||
spread = getSpreadType(spread, createObjectLiteralType(), /*isFromObjectLiteral*/ true);
|
||||
propertiesArray = [];
|
||||
propertiesTable = createMap<Symbol>();
|
||||
hasComputedStringProperty = false;
|
||||
hasComputedNumberProperty = false;
|
||||
typeFlags = 0;
|
||||
}
|
||||
const type = checkExpression((memberDecl as SpreadAssignment).expression);
|
||||
if (!(type.flags & (TypeFlags.Object | TypeFlags.Any))) {
|
||||
error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types);
|
||||
return unknownType;
|
||||
}
|
||||
spread = getSpreadType(spread, type, /*isFromObjectLiteral*/ false);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
// TypeScript 1.0 spec (April 2014)
|
||||
// A get accessor declaration is processed in the same manner as
|
||||
@ -10879,20 +11047,36 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, propertiesArray, IndexKind.String) : undefined;
|
||||
const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, propertiesArray, IndexKind.Number) : undefined;
|
||||
const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
|
||||
const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshLiteral;
|
||||
result.flags |= TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags);
|
||||
result.objectFlags |= ObjectFlags.ObjectLiteral;
|
||||
if (patternWithComputedProperties) {
|
||||
result.objectFlags |= ObjectFlags.ObjectLiteralPatternWithComputedProperties;
|
||||
if (spread !== emptyObjectType) {
|
||||
if (propertiesArray.length > 0) {
|
||||
spread = getSpreadType(spread, createObjectLiteralType(), /*isFromObjectLiteral*/ true);
|
||||
}
|
||||
spread.flags |= propagatedFlags;
|
||||
spread.symbol = node.symbol;
|
||||
return spread;
|
||||
}
|
||||
if (inDestructuringPattern) {
|
||||
result.pattern = node;
|
||||
|
||||
return createObjectLiteralType();
|
||||
|
||||
function createObjectLiteralType() {
|
||||
const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, propertiesArray, IndexKind.String) : undefined;
|
||||
const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, propertiesArray, IndexKind.Number) : undefined;
|
||||
const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
|
||||
const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshLiteral;
|
||||
result.flags |= TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags);
|
||||
result.objectFlags |= ObjectFlags.ObjectLiteral;
|
||||
if (patternWithComputedProperties) {
|
||||
result.objectFlags |= ObjectFlags.ObjectLiteralPatternWithComputedProperties;
|
||||
}
|
||||
if (inDestructuringPattern) {
|
||||
result.pattern = node;
|
||||
}
|
||||
if (!(result.flags & TypeFlags.Nullable)) {
|
||||
propagatedFlags |= (result.flags & TypeFlags.PropagatingFlags);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
function checkJsxSelfClosingElement(node: JsxSelfClosingElement) {
|
||||
checkJsxOpeningLikeElement(node);
|
||||
@ -11309,10 +11493,10 @@ namespace ts {
|
||||
function checkJsxOpeningLikeElement(node: JsxOpeningLikeElement) {
|
||||
checkGrammarJsxElement(node);
|
||||
checkJsxPreconditions(node);
|
||||
// The reactNamespace symbol should be marked as 'used' so we don't incorrectly elide its import. And if there
|
||||
// is no reactNamespace symbol in scope when targeting React emit, we should issue an error.
|
||||
// The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import.
|
||||
// And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error.
|
||||
const reactRefErr = compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined;
|
||||
const reactNamespace = compilerOptions.reactNamespace ? compilerOptions.reactNamespace : "React";
|
||||
const reactNamespace = getJsxNamespace();
|
||||
const reactSym = resolveName(node.tagName, reactNamespace, SymbolFlags.Value, reactRefErr, reactNamespace);
|
||||
if (reactSym) {
|
||||
// Mark local symbol as referenced here because it might not have been marked
|
||||
@ -11513,6 +11697,21 @@ namespace ts {
|
||||
diagnostics.add(createDiagnosticForNodeFromMessageChain(propNode, errorInfo));
|
||||
}
|
||||
|
||||
function markPropertyAsReferenced(prop: Symbol) {
|
||||
if (prop &&
|
||||
noUnusedIdentifiers &&
|
||||
(prop.flags & SymbolFlags.ClassMember) &&
|
||||
prop.valueDeclaration && (getModifierFlags(prop.valueDeclaration) & ModifierFlags.Private)) {
|
||||
if (prop.flags & SymbolFlags.Instantiated) {
|
||||
getSymbolLinks(prop).target.isReferenced = true;
|
||||
|
||||
}
|
||||
else {
|
||||
prop.isReferenced = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) {
|
||||
const type = checkNonNullExpression(left);
|
||||
if (isTypeAny(type) || type === silentNeverType) {
|
||||
@ -11532,17 +11731,7 @@ namespace ts {
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
if (noUnusedIdentifiers &&
|
||||
(prop.flags & SymbolFlags.ClassMember) &&
|
||||
prop.valueDeclaration && (getModifierFlags(prop.valueDeclaration) & ModifierFlags.Private)) {
|
||||
if (prop.flags & SymbolFlags.Instantiated) {
|
||||
getSymbolLinks(prop).target.isReferenced = true;
|
||||
|
||||
}
|
||||
else {
|
||||
prop.isReferenced = true;
|
||||
}
|
||||
}
|
||||
markPropertyAsReferenced(prop);
|
||||
|
||||
getNodeLinks(node).resolvedSymbol = prop;
|
||||
|
||||
@ -11786,7 +11975,7 @@ namespace ts {
|
||||
function getSpreadArgumentIndex(args: Expression[]): number {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const arg = args[i];
|
||||
if (arg && arg.kind === SyntaxKind.SpreadElementExpression) {
|
||||
if (arg && arg.kind === SyntaxKind.SpreadElement) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@ -13752,6 +13941,11 @@ namespace ts {
|
||||
error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(objectLiteralType), declarationNameToString(name));
|
||||
}
|
||||
}
|
||||
else if (property.kind === SyntaxKind.SpreadAssignment) {
|
||||
if (property.expression.kind !== SyntaxKind.Identifier) {
|
||||
error(property.expression, Diagnostics.An_object_rest_element_must_be_an_identifier);
|
||||
}
|
||||
}
|
||||
else {
|
||||
error(property, Diagnostics.Property_assignment_expected);
|
||||
}
|
||||
@ -13774,7 +13968,7 @@ namespace ts {
|
||||
const elements = node.elements;
|
||||
const element = elements[elementIndex];
|
||||
if (element.kind !== SyntaxKind.OmittedExpression) {
|
||||
if (element.kind !== SyntaxKind.SpreadElementExpression) {
|
||||
if (element.kind !== SyntaxKind.SpreadElement) {
|
||||
const propName = "" + elementIndex;
|
||||
const type = isTypeAny(sourceType)
|
||||
? sourceType
|
||||
@ -13798,10 +13992,10 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
if (elementIndex < elements.length - 1) {
|
||||
error(element, Diagnostics.A_rest_element_must_be_last_in_an_array_destructuring_pattern);
|
||||
error(element, Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
|
||||
}
|
||||
else {
|
||||
const restExpression = (<SpreadElementExpression>element).expression;
|
||||
const restExpression = (<SpreadElement>element).expression;
|
||||
if (restExpression.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>restExpression).operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
error((<BinaryExpression>restExpression).operatorToken, Diagnostics.A_rest_element_cannot_have_an_initializer);
|
||||
}
|
||||
@ -14434,8 +14628,8 @@ namespace ts {
|
||||
return checkBinaryExpression(<BinaryExpression>node, contextualMapper);
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
return checkConditionalExpression(<ConditionalExpression>node, contextualMapper);
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
return checkSpreadElementExpression(<SpreadElementExpression>node, contextualMapper);
|
||||
case SyntaxKind.SpreadElement:
|
||||
return checkSpreadExpression(<SpreadElement>node, contextualMapper);
|
||||
case SyntaxKind.OmittedExpression:
|
||||
return undefinedWideningType;
|
||||
case SyntaxKind.YieldExpression:
|
||||
@ -16332,6 +16526,7 @@ namespace ts {
|
||||
const parentType = getTypeForBindingElementParent(parent);
|
||||
const name = node.propertyName || <Identifier>node.name;
|
||||
const property = getPropertyOfType(parentType, getTextOfPropertyName(name));
|
||||
markPropertyAsReferenced(property);
|
||||
if (parent.initializer && property && getParentOfSymbol(property)) {
|
||||
checkClassPropertyAccess(parent, parent.initializer, parentType, property);
|
||||
}
|
||||
@ -16946,6 +17141,7 @@ namespace ts {
|
||||
let hasDuplicateDefaultClause = false;
|
||||
|
||||
const expressionType = checkExpression(node.expression);
|
||||
const expressionIsLiteral = isLiteralType(expressionType);
|
||||
forEach(node.caseBlock.clauses, clause => {
|
||||
// Grammar check for duplicate default clauses, skip if we already report duplicate default clause
|
||||
if (clause.kind === SyntaxKind.DefaultClause && !hasDuplicateDefaultClause) {
|
||||
@ -16966,10 +17162,16 @@ namespace ts {
|
||||
// TypeScript 1.0 spec (April 2014): 5.9
|
||||
// In a 'switch' statement, each 'case' expression must be of a type that is comparable
|
||||
// to or from the type of the 'switch' expression.
|
||||
const caseType = checkExpression(caseClause.expression);
|
||||
if (!isTypeEqualityComparableTo(expressionType, caseType)) {
|
||||
let caseType = checkExpression(caseClause.expression);
|
||||
const caseIsLiteral = isLiteralType(caseType);
|
||||
let comparedExpressionType = expressionType;
|
||||
if (!caseIsLiteral || !expressionIsLiteral) {
|
||||
caseType = caseIsLiteral ? getBaseTypeOfLiteralType(caseType) : caseType;
|
||||
comparedExpressionType = getBaseTypeOfLiteralType(expressionType);
|
||||
}
|
||||
if (!isTypeEqualityComparableTo(comparedExpressionType, caseType)) {
|
||||
// expressionType is not comparable to caseType, try the reversed check and report errors if it fails
|
||||
checkTypeComparableTo(caseType, expressionType, caseClause.expression, /*headMessage*/ undefined);
|
||||
checkTypeComparableTo(caseType, comparedExpressionType, caseClause.expression, /*headMessage*/ undefined);
|
||||
}
|
||||
}
|
||||
forEach(clause.statements, checkSourceElement);
|
||||
@ -19074,6 +19276,10 @@ namespace ts {
|
||||
return symbols;
|
||||
}
|
||||
else if (symbol.flags & SymbolFlags.Transient) {
|
||||
if ((symbol as SymbolLinks).leftSpread) {
|
||||
const links = symbol as SymbolLinks;
|
||||
return [links.leftSpread, links.rightSpread];
|
||||
}
|
||||
let target: Symbol;
|
||||
let next = symbol;
|
||||
while (next = getSymbolLinks(next).target) {
|
||||
@ -19562,7 +19768,8 @@ namespace ts {
|
||||
getTypeReferenceDirectivesForEntityName,
|
||||
getTypeReferenceDirectivesForSymbol,
|
||||
isLiteralConstDeclaration,
|
||||
writeLiteralConstValue
|
||||
writeLiteralConstValue,
|
||||
getJsxFactoryEntity: () => _jsxFactoryEntity
|
||||
};
|
||||
|
||||
// defined here to avoid outer scope pollution
|
||||
@ -19774,9 +19981,13 @@ namespace ts {
|
||||
if (requestedExternalEmitHelpers & NodeFlags.HasClassExtends && languageVersion < ScriptTarget.ES2015) {
|
||||
verifyHelperSymbol(exports, "__extends", SymbolFlags.Value);
|
||||
}
|
||||
if (requestedExternalEmitHelpers & NodeFlags.HasJsxSpreadAttributes && compilerOptions.jsx !== JsxEmit.Preserve) {
|
||||
if (requestedExternalEmitHelpers & NodeFlags.HasSpreadAttribute &&
|
||||
(languageVersion < ScriptTarget.ESNext || compilerOptions.jsx === JsxEmit.React)) {
|
||||
verifyHelperSymbol(exports, "__assign", SymbolFlags.Value);
|
||||
}
|
||||
if (languageVersion < ScriptTarget.ESNext && requestedExternalEmitHelpers & NodeFlags.HasRestAttribute) {
|
||||
verifyHelperSymbol(exports, "__rest", SymbolFlags.Value);
|
||||
}
|
||||
if (requestedExternalEmitHelpers & NodeFlags.HasDecorators) {
|
||||
verifyHelperSymbol(exports, "__decorate", SymbolFlags.Value);
|
||||
if (compilerOptions.emitDecoratorMetadata) {
|
||||
@ -20337,7 +20548,6 @@ namespace ts {
|
||||
checkGrammarHeritageClause(heritageClause);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -20385,6 +20595,9 @@ namespace ts {
|
||||
const GetOrSetAccessor = GetAccessor | SetAccessor;
|
||||
|
||||
for (const prop of node.properties) {
|
||||
if (prop.kind === SyntaxKind.SpreadAssignment) {
|
||||
continue;
|
||||
}
|
||||
const name = prop.name;
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
// If the name is not a ComputedPropertyName, the grammar checking will skip it
|
||||
@ -20688,7 +20901,7 @@ namespace ts {
|
||||
if (node.dotDotDotToken) {
|
||||
const elements = (<BindingPattern>node.parent).elements;
|
||||
if (node !== lastOrUndefined(elements)) {
|
||||
return grammarErrorOnNode(node, Diagnostics.A_rest_element_must_be_last_in_an_array_destructuring_pattern);
|
||||
return grammarErrorOnNode(node, Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
|
||||
}
|
||||
|
||||
if (node.name.kind === SyntaxKind.ArrayBindingPattern || node.name.kind === SyntaxKind.ObjectBindingPattern) {
|
||||
@ -20696,7 +20909,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (node.initializer) {
|
||||
// Error on equals token which immediate precedes the initializer
|
||||
// Error on equals token which immediately precedes the initializer
|
||||
return grammarErrorAtPos(getSourceFileOfNode(node), node.initializer.pos - 1, 1, Diagnostics.A_rest_element_cannot_have_an_initializer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,6 +77,11 @@ namespace ts {
|
||||
type: "string",
|
||||
description: Diagnostics.Specify_the_object_invoked_for_createElement_and_spread_when_targeting_react_JSX_emit
|
||||
},
|
||||
{
|
||||
name: "jsxFactory",
|
||||
type: "string",
|
||||
description: Diagnostics.Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h
|
||||
},
|
||||
{
|
||||
name: "listFiles",
|
||||
type: "boolean",
|
||||
@ -265,6 +270,7 @@ namespace ts {
|
||||
"es2015": ScriptTarget.ES2015,
|
||||
"es2016": ScriptTarget.ES2016,
|
||||
"es2017": ScriptTarget.ES2017,
|
||||
"esnext": ScriptTarget.ESNext,
|
||||
}),
|
||||
description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015,
|
||||
paramType: Diagnostics.VERSION,
|
||||
@ -428,7 +434,8 @@ namespace ts {
|
||||
"es2015.symbol.wellknown": "lib.es2015.symbol.wellknown.d.ts",
|
||||
"es2016.array.include": "lib.es2016.array.include.d.ts",
|
||||
"es2017.object": "lib.es2017.object.d.ts",
|
||||
"es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts"
|
||||
"es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts",
|
||||
"es2017.string": "lib.es2017.string.d.ts",
|
||||
}),
|
||||
},
|
||||
description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon
|
||||
|
||||
@ -1127,6 +1127,18 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function createCompilerDiagnosticFromMessageChain(chain: DiagnosticMessageChain): Diagnostic {
|
||||
return {
|
||||
file: undefined,
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
|
||||
code: chain.code,
|
||||
category: chain.category,
|
||||
messageText: chain.next ? chain : chain.messageText
|
||||
};
|
||||
}
|
||||
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage, ...args: any[]): DiagnosticMessageChain;
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage): DiagnosticMessageChain {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
|
||||
@ -1455,7 +1455,7 @@
|
||||
"category": "Error",
|
||||
"code": 2461
|
||||
},
|
||||
"A rest element must be last in an array destructuring pattern": {
|
||||
"A rest element must be last in a destructuring pattern": {
|
||||
"category": "Error",
|
||||
"code": 2462
|
||||
},
|
||||
@ -1983,6 +1983,18 @@
|
||||
"category": "Error",
|
||||
"code": 2697
|
||||
},
|
||||
"Spread types may only be created from object types.": {
|
||||
"category": "Error",
|
||||
"code": 2698
|
||||
},
|
||||
"Rest types may only be created from object types.": {
|
||||
"category": "Error",
|
||||
"code": 2700
|
||||
},
|
||||
"An object rest element must be an identifier.": {
|
||||
"category": "Error",
|
||||
"code": 2701
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
@ -2381,6 +2393,10 @@
|
||||
"category": "Error",
|
||||
"code": 5066
|
||||
},
|
||||
"Invalid value for 'jsxFactory'. '{0}' is not a valid identifier or qualified-name.": {
|
||||
"category": "Error",
|
||||
"code": 5067
|
||||
},
|
||||
"Concatenate and emit output to single file.": {
|
||||
"category": "Message",
|
||||
"code": 6001
|
||||
@ -2897,6 +2913,10 @@
|
||||
"category": "Message",
|
||||
"code": 6145
|
||||
},
|
||||
"Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'.": {
|
||||
"category": "Message",
|
||||
"code": 6146
|
||||
},
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
"code": 7005
|
||||
@ -3158,5 +3178,13 @@
|
||||
"Implement inherited abstract class": {
|
||||
"category": "Message",
|
||||
"code": 90007
|
||||
},
|
||||
"Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig": {
|
||||
"category": "Error",
|
||||
"code": 90009
|
||||
},
|
||||
"Type '{0}' is not assignable to type '{1}'. Two different types with this name exist, but they are unrelated.": {
|
||||
"category": "Error",
|
||||
"code": 90010
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,6 +42,14 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
return t;
|
||||
};`;
|
||||
|
||||
const restHelper = `
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && !e.indexOf(p))
|
||||
t[p] = s[p];
|
||||
return t;
|
||||
};`;
|
||||
|
||||
// emit output for the __decorate helper function
|
||||
const decorateHelper = `
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
@ -226,6 +234,7 @@ const _super = (function (geti, seti) {
|
||||
let currentFileIdentifiers: Map<string>;
|
||||
let extendsEmitted: boolean;
|
||||
let assignEmitted: boolean;
|
||||
let restEmitted: boolean;
|
||||
let decorateEmitted: boolean;
|
||||
let paramEmitted: boolean;
|
||||
let awaiterEmitted: boolean;
|
||||
@ -732,6 +741,8 @@ const _super = (function (geti, seti) {
|
||||
return emitPropertyAssignment(<PropertyAssignment>node);
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
return emitShorthandPropertyAssignment(<ShorthandPropertyAssignment>node);
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
return emitSpreadAssignment(node as SpreadAssignment);
|
||||
|
||||
// Enum
|
||||
case SyntaxKind.EnumMember:
|
||||
@ -822,8 +833,8 @@ const _super = (function (geti, seti) {
|
||||
return emitTemplateExpression(<TemplateExpression>node);
|
||||
case SyntaxKind.YieldExpression:
|
||||
return emitYieldExpression(<YieldExpression>node);
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
return emitSpreadElementExpression(<SpreadElementExpression>node);
|
||||
case SyntaxKind.SpreadElement:
|
||||
return emitSpreadExpression(<SpreadElement>node);
|
||||
case SyntaxKind.ClassExpression:
|
||||
return emitClassExpression(<ClassExpression>node);
|
||||
case SyntaxKind.OmittedExpression:
|
||||
@ -1374,7 +1385,7 @@ const _super = (function (geti, seti) {
|
||||
emitExpressionWithPrefix(" ", node.expression);
|
||||
}
|
||||
|
||||
function emitSpreadElementExpression(node: SpreadElementExpression) {
|
||||
function emitSpreadExpression(node: SpreadElement) {
|
||||
write("...");
|
||||
emitExpression(node.expression);
|
||||
}
|
||||
@ -2102,6 +2113,13 @@ const _super = (function (geti, seti) {
|
||||
}
|
||||
}
|
||||
|
||||
function emitSpreadAssignment(node: SpreadAssignment) {
|
||||
if (node.expression) {
|
||||
write("...");
|
||||
emitExpression(node.expression);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Enum
|
||||
//
|
||||
@ -2205,11 +2223,19 @@ const _super = (function (geti, seti) {
|
||||
helpersEmitted = true;
|
||||
}
|
||||
|
||||
if (compilerOptions.jsx !== JsxEmit.Preserve && !assignEmitted && (node.flags & NodeFlags.HasJsxSpreadAttributes)) {
|
||||
if ((languageVersion < ScriptTarget.ESNext || currentSourceFile.scriptKind === ScriptKind.JSX || currentSourceFile.scriptKind === ScriptKind.TSX) &&
|
||||
compilerOptions.jsx !== JsxEmit.Preserve &&
|
||||
!assignEmitted &&
|
||||
node.flags & NodeFlags.HasSpreadAttribute) {
|
||||
writeLines(assignHelper);
|
||||
assignEmitted = true;
|
||||
}
|
||||
|
||||
if (languageVersion < ScriptTarget.ESNext && !restEmitted && node.flags & NodeFlags.HasRestAttribute) {
|
||||
writeLines(restHelper);
|
||||
restEmitted = true;
|
||||
}
|
||||
|
||||
if (!decorateEmitted && node.flags & NodeFlags.HasDecorators) {
|
||||
writeLines(decorateHelper);
|
||||
if (compilerOptions.emitDecoratorMetadata) {
|
||||
|
||||
@ -692,12 +692,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function createSpread(expression: Expression, location?: TextRange) {
|
||||
const node = <SpreadElementExpression>createNode(SyntaxKind.SpreadElementExpression, location);
|
||||
const node = <SpreadElement>createNode(SyntaxKind.SpreadElement, location);
|
||||
node.expression = parenthesizeExpressionForList(expression);
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateSpread(node: SpreadElementExpression, expression: Expression) {
|
||||
export function updateSpread(node: SpreadElement, expression: Expression) {
|
||||
if (node.expression !== expression) {
|
||||
return updateNode(createSpread(expression, node), node);
|
||||
}
|
||||
@ -1399,14 +1399,27 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression) {
|
||||
export function createSpreadAssignment(expression: Expression, location?: TextRange) {
|
||||
const node = <SpreadAssignment>createNode(SyntaxKind.SpreadAssignment, location);
|
||||
node.expression = expression !== undefined ? parenthesizeExpressionForList(expression) : undefined;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression) {
|
||||
if (node.name !== name || node.objectAssignmentInitializer !== objectAssignmentInitializer) {
|
||||
return updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer, node), node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// Top-level nodes
|
||||
export function updateSpreadAssignment(node: SpreadAssignment, expression: Expression) {
|
||||
if (node.expression !== expression) {
|
||||
return updateNode(createSpreadAssignment(expression, node), node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// Top-level nodes
|
||||
|
||||
export function updateSourceFileNode(node: SourceFile, statements: Statement[]) {
|
||||
if (node.statements !== statements) {
|
||||
@ -1628,7 +1641,34 @@ namespace ts {
|
||||
return react;
|
||||
}
|
||||
|
||||
export function createReactCreateElement(reactNamespace: string, tagName: Expression, props: Expression, children: Expression[], parentElement: JsxOpeningLikeElement, location: TextRange): LeftHandSideExpression {
|
||||
function createJsxFactoryExpressionFromEntityName(jsxFactory: EntityName, parent: JsxOpeningLikeElement): Expression {
|
||||
if (isQualifiedName(jsxFactory)) {
|
||||
return createPropertyAccess(
|
||||
createJsxFactoryExpressionFromEntityName(
|
||||
jsxFactory.left,
|
||||
parent
|
||||
),
|
||||
setEmitFlags(
|
||||
getMutableClone(jsxFactory.right),
|
||||
EmitFlags.NoSourceMap
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
return createReactNamespace(jsxFactory.text, parent);
|
||||
}
|
||||
}
|
||||
|
||||
function createJsxFactoryExpression(jsxFactoryEntity: EntityName, reactNamespace: string, parent: JsxOpeningLikeElement): Expression {
|
||||
return jsxFactoryEntity ?
|
||||
createJsxFactoryExpressionFromEntityName(jsxFactoryEntity, parent) :
|
||||
createPropertyAccess(
|
||||
createReactNamespace(reactNamespace, parent),
|
||||
"createElement"
|
||||
);
|
||||
}
|
||||
|
||||
export function createExpressionForJsxElement(jsxFactoryEntity: EntityName, reactNamespace: string, tagName: Expression, props: Expression, children: Expression[], parentElement: JsxOpeningLikeElement, location: TextRange): LeftHandSideExpression {
|
||||
const argumentsList = [tagName];
|
||||
if (props) {
|
||||
argumentsList.push(props);
|
||||
@ -1651,10 +1691,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
return createCall(
|
||||
createPropertyAccess(
|
||||
createReactNamespace(reactNamespace, parentElement),
|
||||
"createElement"
|
||||
),
|
||||
createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement),
|
||||
/*typeArguments*/ undefined,
|
||||
argumentsList,
|
||||
location
|
||||
@ -3055,4 +3092,538 @@ namespace ts {
|
||||
function tryGetModuleNameFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration, host: EmitHost, resolver: EmitResolver, compilerOptions: CompilerOptions) {
|
||||
return tryGetModuleNameFromFile(resolver.getExternalModuleFileFromDeclaration(declaration), host, compilerOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the body of a function-like node.
|
||||
*
|
||||
* @param node A function-like node.
|
||||
*/
|
||||
export function transformFunctionBody(node: FunctionLikeDeclaration,
|
||||
visitor: (node: Node) => VisitResult<Node>,
|
||||
currentSourceFile: SourceFile,
|
||||
context: TransformationContext,
|
||||
enableSubstitutionsForCapturedThis: () => void,
|
||||
convertObjectRest?: boolean) {
|
||||
let multiLine = false; // indicates whether the block *must* be emitted as multiple lines
|
||||
let singleLine = false; // indicates whether the block *may* be emitted as a single line
|
||||
let statementsLocation: TextRange;
|
||||
let closeBraceLocation: TextRange;
|
||||
|
||||
const statements: Statement[] = [];
|
||||
const body = node.body;
|
||||
let statementOffset: number;
|
||||
|
||||
context.startLexicalEnvironment();
|
||||
if (isBlock(body)) {
|
||||
// ensureUseStrict is false because no new prologue-directive should be added.
|
||||
// addPrologueDirectives will simply put already-existing directives at the beginning of the target statement-array
|
||||
statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false, visitor);
|
||||
}
|
||||
|
||||
addCaptureThisForNodeIfNeeded(statements, node, enableSubstitutionsForCapturedThis);
|
||||
addDefaultValueAssignmentsIfNeeded(statements, node, visitor, convertObjectRest);
|
||||
addRestParameterIfNeeded(statements, node, /*inConstructorWithSynthesizedSuper*/ false);
|
||||
|
||||
// If we added any generated statements, this must be a multi-line block.
|
||||
if (!multiLine && statements.length > 0) {
|
||||
multiLine = true;
|
||||
}
|
||||
|
||||
if (isBlock(body)) {
|
||||
statementsLocation = body.statements;
|
||||
addRange(statements, visitNodes(body.statements, visitor, isStatement, statementOffset));
|
||||
|
||||
// If the original body was a multi-line block, this must be a multi-line block.
|
||||
if (!multiLine && body.multiLine) {
|
||||
multiLine = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Debug.assert(node.kind === SyntaxKind.ArrowFunction);
|
||||
|
||||
// To align with the old emitter, we use a synthetic end position on the location
|
||||
// for the statement list we synthesize when we down-level an arrow function with
|
||||
// an expression function body. This prevents both comments and source maps from
|
||||
// being emitted for the end position only.
|
||||
statementsLocation = moveRangeEnd(body, -1);
|
||||
|
||||
const equalsGreaterThanToken = (<ArrowFunction>node).equalsGreaterThanToken;
|
||||
if (!nodeIsSynthesized(equalsGreaterThanToken) && !nodeIsSynthesized(body)) {
|
||||
if (rangeEndIsOnSameLineAsRangeStart(equalsGreaterThanToken, body, currentSourceFile)) {
|
||||
singleLine = true;
|
||||
}
|
||||
else {
|
||||
multiLine = true;
|
||||
}
|
||||
}
|
||||
|
||||
const expression = visitNode(body, visitor, isExpression);
|
||||
const returnStatement = createReturn(expression, /*location*/ body);
|
||||
setEmitFlags(returnStatement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTrailingComments);
|
||||
statements.push(returnStatement);
|
||||
|
||||
// To align with the source map emit for the old emitter, we set a custom
|
||||
// source map location for the close brace.
|
||||
closeBraceLocation = body;
|
||||
}
|
||||
|
||||
const lexicalEnvironment = context.endLexicalEnvironment();
|
||||
addRange(statements, lexicalEnvironment);
|
||||
|
||||
// If we added any final generated statements, this must be a multi-line block
|
||||
if (!multiLine && lexicalEnvironment && lexicalEnvironment.length) {
|
||||
multiLine = true;
|
||||
}
|
||||
|
||||
const block = createBlock(createNodeArray(statements, statementsLocation), node.body, multiLine);
|
||||
if (!multiLine && singleLine) {
|
||||
setEmitFlags(block, EmitFlags.SingleLine);
|
||||
}
|
||||
|
||||
if (closeBraceLocation) {
|
||||
setTokenSourceMapRange(block, SyntaxKind.CloseBraceToken, closeBraceLocation);
|
||||
}
|
||||
|
||||
setOriginalNode(block, node.body);
|
||||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a statement to capture the `this` of a function declaration if it is needed.
|
||||
*
|
||||
* @param statements The statements for the new function body.
|
||||
* @param node A node.
|
||||
*/
|
||||
export function addCaptureThisForNodeIfNeeded(statements: Statement[], node: Node, enableSubstitutionsForCapturedThis: () => void): void {
|
||||
if (node.transformFlags & TransformFlags.ContainsCapturedLexicalThis && node.kind !== SyntaxKind.ArrowFunction) {
|
||||
captureThisForNode(statements, node, createThis(), enableSubstitutionsForCapturedThis);
|
||||
}
|
||||
}
|
||||
|
||||
export function captureThisForNode(statements: Statement[], node: Node, initializer: Expression | undefined, enableSubstitutionsForCapturedThis?: () => void, originalStatement?: Statement): void {
|
||||
enableSubstitutionsForCapturedThis();
|
||||
const captureThisStatement = createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
"_this",
|
||||
/*type*/ undefined,
|
||||
initializer
|
||||
)
|
||||
]),
|
||||
originalStatement
|
||||
);
|
||||
|
||||
setEmitFlags(captureThisStatement, EmitFlags.NoComments | EmitFlags.CustomPrologue);
|
||||
setSourceMapRange(captureThisStatement, node);
|
||||
statements.push(captureThisStatement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether we need to add default value assignments for a
|
||||
* function-like node.
|
||||
*
|
||||
* @param node A function-like node.
|
||||
*/
|
||||
function shouldAddDefaultValueAssignments(node: FunctionLikeDeclaration): boolean {
|
||||
return (node.transformFlags & TransformFlags.ContainsDefaultValueAssignments) !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds statements to the body of a function-like node if it contains parameters with
|
||||
* binding patterns or initializers.
|
||||
*
|
||||
* @param statements The statements for the new function body.
|
||||
* @param node A function-like node.
|
||||
*/
|
||||
export function addDefaultValueAssignmentsIfNeeded(statements: Statement[],
|
||||
node: FunctionLikeDeclaration,
|
||||
visitor: (node: Node) => VisitResult<Node>,
|
||||
convertObjectRest: boolean): void {
|
||||
if (!shouldAddDefaultValueAssignments(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const parameter of node.parameters) {
|
||||
const { name, initializer, dotDotDotToken } = parameter;
|
||||
|
||||
// A rest parameter cannot have a binding pattern or an initializer,
|
||||
// so let's just ignore it.
|
||||
if (dotDotDotToken) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isBindingPattern(name)) {
|
||||
addDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer, visitor, convertObjectRest);
|
||||
}
|
||||
else if (initializer) {
|
||||
addDefaultValueAssignmentForInitializer(statements, parameter, name, initializer, visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds statements to the body of a function-like node for parameters with binding patterns
|
||||
*
|
||||
* @param statements The statements for the new function body.
|
||||
* @param parameter The parameter for the function.
|
||||
* @param name The name of the parameter.
|
||||
* @param initializer The initializer for the parameter.
|
||||
*/
|
||||
function addDefaultValueAssignmentForBindingPattern(statements: Statement[],
|
||||
parameter: ParameterDeclaration,
|
||||
name: BindingPattern, initializer: Expression,
|
||||
visitor: (node: Node) => VisitResult<Node>,
|
||||
convertObjectRest: boolean): void {
|
||||
const temp = getGeneratedNameForNode(parameter);
|
||||
|
||||
// In cases where a binding pattern is simply '[]' or '{}',
|
||||
// we usually don't want to emit a var declaration; however, in the presence
|
||||
// of an initializer, we must emit that expression to preserve side effects.
|
||||
if (name.elements.length > 0) {
|
||||
statements.push(
|
||||
setEmitFlags(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(
|
||||
flattenParameterDestructuring(parameter, temp, visitor, convertObjectRest)
|
||||
)
|
||||
),
|
||||
EmitFlags.CustomPrologue
|
||||
)
|
||||
);
|
||||
}
|
||||
else if (initializer) {
|
||||
statements.push(
|
||||
setEmitFlags(
|
||||
createStatement(
|
||||
createAssignment(
|
||||
temp,
|
||||
visitNode(initializer, visitor, isExpression)
|
||||
)
|
||||
),
|
||||
EmitFlags.CustomPrologue
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds statements to the body of a function-like node for parameters with initializers.
|
||||
*
|
||||
* @param statements The statements for the new function body.
|
||||
* @param parameter The parameter for the function.
|
||||
* @param name The name of the parameter.
|
||||
* @param initializer The initializer for the parameter.
|
||||
*/
|
||||
function addDefaultValueAssignmentForInitializer(statements: Statement[],
|
||||
parameter: ParameterDeclaration,
|
||||
name: Identifier,
|
||||
initializer: Expression,
|
||||
visitor: (node: Node) => VisitResult<Node>): void {
|
||||
initializer = visitNode(initializer, visitor, isExpression);
|
||||
const statement = createIf(
|
||||
createStrictEquality(
|
||||
getSynthesizedClone(name),
|
||||
createVoidZero()
|
||||
),
|
||||
setEmitFlags(
|
||||
createBlock([
|
||||
createStatement(
|
||||
createAssignment(
|
||||
setEmitFlags(getMutableClone(name), EmitFlags.NoSourceMap),
|
||||
setEmitFlags(initializer, EmitFlags.NoSourceMap | getEmitFlags(initializer)),
|
||||
/*location*/ parameter
|
||||
)
|
||||
)
|
||||
], /*location*/ parameter),
|
||||
EmitFlags.SingleLine | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTokenSourceMaps
|
||||
),
|
||||
/*elseStatement*/ undefined,
|
||||
/*location*/ parameter
|
||||
);
|
||||
statement.startsOnNewLine = true;
|
||||
setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.CustomPrologue);
|
||||
statements.push(statement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether we need to add statements to handle a rest parameter.
|
||||
*
|
||||
* @param node A ParameterDeclaration node.
|
||||
* @param inConstructorWithSynthesizedSuper A value indicating whether the parameter is
|
||||
* part of a constructor declaration with a
|
||||
* synthesized call to `super`
|
||||
*/
|
||||
function shouldAddRestParameter(node: ParameterDeclaration, inConstructorWithSynthesizedSuper: boolean) {
|
||||
return node && node.dotDotDotToken && node.name.kind === SyntaxKind.Identifier && !inConstructorWithSynthesizedSuper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds statements to the body of a function-like node if it contains a rest parameter.
|
||||
*
|
||||
* @param statements The statements for the new function body.
|
||||
* @param node A function-like node.
|
||||
* @param inConstructorWithSynthesizedSuper A value indicating whether the parameter is
|
||||
* part of a constructor declaration with a
|
||||
* synthesized call to `super`
|
||||
*/
|
||||
export function addRestParameterIfNeeded(statements: Statement[], node: FunctionLikeDeclaration, inConstructorWithSynthesizedSuper: boolean): void {
|
||||
const parameter = lastOrUndefined(node.parameters);
|
||||
if (!shouldAddRestParameter(parameter, inConstructorWithSynthesizedSuper)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// `declarationName` is the name of the local declaration for the parameter.
|
||||
const declarationName = getMutableClone(<Identifier>parameter.name);
|
||||
setEmitFlags(declarationName, EmitFlags.NoSourceMap);
|
||||
|
||||
// `expressionName` is the name of the parameter used in expressions.
|
||||
const expressionName = getSynthesizedClone(<Identifier>parameter.name);
|
||||
const restIndex = node.parameters.length - 1;
|
||||
const temp = createLoopVariable();
|
||||
|
||||
// var param = [];
|
||||
statements.push(
|
||||
setEmitFlags(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
declarationName,
|
||||
/*type*/ undefined,
|
||||
createArrayLiteral([])
|
||||
)
|
||||
]),
|
||||
/*location*/ parameter
|
||||
),
|
||||
EmitFlags.CustomPrologue
|
||||
)
|
||||
);
|
||||
|
||||
// for (var _i = restIndex; _i < arguments.length; _i++) {
|
||||
// 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
|
||||
),
|
||||
createPostfixIncrement(temp, /*location*/ parameter),
|
||||
createBlock([
|
||||
startOnNewLine(
|
||||
createStatement(
|
||||
createAssignment(
|
||||
createElementAccess(
|
||||
expressionName,
|
||||
createSubtract(temp, createLiteral(restIndex))
|
||||
),
|
||||
createElementAccess(createIdentifier("arguments"), temp)
|
||||
),
|
||||
/*location*/ parameter
|
||||
)
|
||||
)
|
||||
])
|
||||
);
|
||||
|
||||
setEmitFlags(forStatement, EmitFlags.CustomPrologue);
|
||||
startOnNewLine(forStatement);
|
||||
statements.push(forStatement);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export function convertForOf(node: ForOfStatement, convertedLoopBodyStatements: Statement[],
|
||||
visitor: (node: Node) => VisitResult<Node>,
|
||||
enableSubstitutionsForBlockScopedBindings: () => void,
|
||||
context: TransformationContext,
|
||||
convertObjectRest?: boolean): ForStatement | ForOfStatement {
|
||||
// The following ES6 code:
|
||||
//
|
||||
// for (let v of expr) { }
|
||||
//
|
||||
// should be emitted as
|
||||
//
|
||||
// for (var _i = 0, _a = expr; _i < _a.length; _i++) {
|
||||
// var v = _a[_i];
|
||||
// }
|
||||
//
|
||||
// where _a and _i are temps emitted to capture the RHS and the counter,
|
||||
// respectively.
|
||||
// When the left hand side is an expression instead of a let declaration,
|
||||
// the "let v" is not emitted.
|
||||
// When the left hand side is a let/const, the v is renamed if there is
|
||||
// another v in scope.
|
||||
// Note that all assignments to the LHS are emitted in the body, including
|
||||
// all destructuring.
|
||||
// Note also that because an extra statement is needed to assign to the LHS,
|
||||
// for-of bodies are always emitted as blocks.
|
||||
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
const initializer = node.initializer;
|
||||
const statements: Statement[] = [];
|
||||
|
||||
// In the case where the user wrote an identifier as the RHS, like this:
|
||||
//
|
||||
// for (let v of arr) { }
|
||||
//
|
||||
// we don't want to emit a temporary variable for the RHS, just use it directly.
|
||||
const counter = convertObjectRest ? undefined : createLoopVariable();
|
||||
const rhsReference = expression.kind === SyntaxKind.Identifier
|
||||
? createUniqueName((<Identifier>expression).text)
|
||||
: createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const elementAccess = convertObjectRest ? rhsReference : createElementAccess(rhsReference, counter);
|
||||
|
||||
// Initialize LHS
|
||||
// var v = _a[_i];
|
||||
if (isVariableDeclarationList(initializer)) {
|
||||
if (initializer.flags & NodeFlags.BlockScoped) {
|
||||
enableSubstitutionsForBlockScopedBindings();
|
||||
}
|
||||
|
||||
const firstOriginalDeclaration = firstOrUndefined(initializer.declarations);
|
||||
if (firstOriginalDeclaration && isBindingPattern(firstOriginalDeclaration.name)) {
|
||||
// This works whether the declaration is a var, let, or const.
|
||||
// It will use rhsIterationValue _a[_i] as the initializer.
|
||||
const declarations = flattenVariableDestructuring(
|
||||
firstOriginalDeclaration,
|
||||
elementAccess,
|
||||
visitor,
|
||||
/*recordTempVariable*/ undefined,
|
||||
convertObjectRest
|
||||
);
|
||||
|
||||
const declarationList = createVariableDeclarationList(declarations, /*location*/ initializer);
|
||||
setOriginalNode(declarationList, initializer);
|
||||
|
||||
// Adjust the source map range for the first declaration to align with the old
|
||||
// emitter.
|
||||
const firstDeclaration = declarations[0];
|
||||
const lastDeclaration = lastOrUndefined(declarations);
|
||||
setSourceMapRange(declarationList, createRange(firstDeclaration.pos, lastDeclaration.end));
|
||||
|
||||
statements.push(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
declarationList
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
// 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
|
||||
),
|
||||
/*location*/ moveRangeEnd(initializer, -1)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Initializer is an expression. Emit the expression in the body, so that it's
|
||||
// evaluated on every iteration.
|
||||
const assignment = createAssignment(initializer, elementAccess);
|
||||
if (isDestructuringAssignment(assignment)) {
|
||||
// This is a destructuring pattern, so we flatten the destructuring instead.
|
||||
statements.push(
|
||||
createStatement(
|
||||
flattenDestructuringAssignment(
|
||||
context,
|
||||
assignment,
|
||||
/*needsValue*/ false,
|
||||
context.hoistVariableDeclaration,
|
||||
visitor,
|
||||
convertObjectRest
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
// 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)));
|
||||
}
|
||||
}
|
||||
|
||||
let bodyLocation: TextRange;
|
||||
let statementsLocation: TextRange;
|
||||
if (convertedLoopBodyStatements) {
|
||||
addRange(statements, convertedLoopBodyStatements);
|
||||
}
|
||||
else {
|
||||
const statement = visitNode(node.statement, visitor, isStatement);
|
||||
if (isBlock(statement)) {
|
||||
addRange(statements, statement.statements);
|
||||
bodyLocation = statement;
|
||||
statementsLocation = statement.statements;
|
||||
}
|
||||
else {
|
||||
statements.push(statement);
|
||||
}
|
||||
}
|
||||
|
||||
// The old emitter does not emit source maps for the expression
|
||||
setEmitFlags(expression, EmitFlags.NoSourceMap | getEmitFlags(expression));
|
||||
|
||||
// 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
|
||||
);
|
||||
|
||||
setEmitFlags(body, EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps);
|
||||
|
||||
let forStatement: ForStatement | ForOfStatement;
|
||||
if (convertObjectRest) {
|
||||
forStatement = createForOf(
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(rhsReference, /*type*/ undefined, /*initializer*/ undefined, /*location*/ node.expression)
|
||||
], /*location*/ node.expression),
|
||||
node.expression,
|
||||
body,
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
else {
|
||||
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),
|
||||
EmitFlags.NoHoisting
|
||||
),
|
||||
createLessThan(
|
||||
counter,
|
||||
createPropertyAccess(rhsReference, "length"),
|
||||
/*location*/ node.expression
|
||||
),
|
||||
createPostfixIncrement(counter, /*location*/ node.expression),
|
||||
body,
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
|
||||
// Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter.
|
||||
setEmitFlags(forStatement, EmitFlags.NoTokenTrailingSourceMaps);
|
||||
return forStatement;
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,6 +74,8 @@ namespace ts {
|
||||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).questionToken) ||
|
||||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).equalsToken) ||
|
||||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).objectAssignmentInitializer);
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
return visitNode(cbNode, (<SpreadAssignment>node).expression);
|
||||
case SyntaxKind.Parameter:
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
@ -197,8 +199,8 @@ namespace ts {
|
||||
visitNode(cbNode, (<ConditionalExpression>node).whenTrue) ||
|
||||
visitNode(cbNode, (<ConditionalExpression>node).colonToken) ||
|
||||
visitNode(cbNode, (<ConditionalExpression>node).whenFalse);
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
return visitNode(cbNode, (<SpreadElementExpression>node).expression);
|
||||
case SyntaxKind.SpreadElement:
|
||||
return visitNode(cbNode, (<SpreadElement>node).expression);
|
||||
case SyntaxKind.Block:
|
||||
case SyntaxKind.ModuleBlock:
|
||||
return visitNodes(cbNodes, (<Block>node).statements);
|
||||
@ -438,6 +440,10 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function parseIsolatedEntityName(text: string, languageVersion: ScriptTarget): EntityName {
|
||||
return Parser.parseIsolatedEntityName(text, languageVersion);
|
||||
}
|
||||
|
||||
export function isExternalModule(file: SourceFile): boolean {
|
||||
return file.externalModuleIndicator !== undefined;
|
||||
}
|
||||
@ -589,6 +595,16 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function parseIsolatedEntityName(content: string, languageVersion: ScriptTarget): EntityName {
|
||||
initializeState(content, languageVersion, /*syntaxCursor*/ undefined, ScriptKind.JS);
|
||||
// Prime the scanner.
|
||||
nextToken();
|
||||
const entityName = parseEntityName(/*allowReservedWords*/ true);
|
||||
const isInvalid = token() === SyntaxKind.EndOfFileToken && !parseDiagnostics.length;
|
||||
clearState();
|
||||
return isInvalid ? entityName : undefined;
|
||||
}
|
||||
|
||||
function getLanguageVariant(scriptKind: ScriptKind) {
|
||||
// .tsx and .jsx files are treated as jsx language variant.
|
||||
return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS ? LanguageVariant.JSX : LanguageVariant.Standard;
|
||||
@ -1269,9 +1285,11 @@ namespace ts {
|
||||
// which would be a candidate for improved error reporting.
|
||||
return token() === SyntaxKind.OpenBracketToken || isLiteralPropertyName();
|
||||
case ParsingContext.ObjectLiteralMembers:
|
||||
return token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.AsteriskToken || isLiteralPropertyName();
|
||||
return token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.AsteriskToken || token() === SyntaxKind.DotDotDotToken || isLiteralPropertyName();
|
||||
case ParsingContext.RestProperties:
|
||||
return isLiteralPropertyName();
|
||||
case ParsingContext.ObjectBindingElements:
|
||||
return token() === SyntaxKind.OpenBracketToken || isLiteralPropertyName();
|
||||
return token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.DotDotDotToken || isLiteralPropertyName();
|
||||
case ParsingContext.HeritageClauseElement:
|
||||
// If we see { } then only consume it as an expression if it is followed by , or {
|
||||
// That way we won't consume the body of a class in its heritage clause.
|
||||
@ -1398,6 +1416,7 @@ namespace ts {
|
||||
case ParsingContext.ArrayBindingElements:
|
||||
return token() === SyntaxKind.CloseBracketToken;
|
||||
case ParsingContext.Parameters:
|
||||
case ParsingContext.RestProperties:
|
||||
// Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery
|
||||
return token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.CloseBracketToken /*|| token === SyntaxKind.OpenBraceToken*/;
|
||||
case ParsingContext.TypeArguments:
|
||||
@ -1583,6 +1602,9 @@ namespace ts {
|
||||
case ParsingContext.Parameters:
|
||||
return isReusableParameter(node);
|
||||
|
||||
case ParsingContext.RestProperties:
|
||||
return false;
|
||||
|
||||
// Any other lists we do not care about reusing nodes in. But feel free to add if
|
||||
// you can do so safely. Danger areas involve nodes that may involve speculative
|
||||
// parsing. If speculative parsing is involved with the node, then the range the
|
||||
@ -1780,6 +1802,7 @@ namespace ts {
|
||||
case ParsingContext.BlockStatements: return Diagnostics.Declaration_or_statement_expected;
|
||||
case ParsingContext.SwitchClauses: return Diagnostics.case_or_default_expected;
|
||||
case ParsingContext.SwitchClauseStatements: return Diagnostics.Statement_expected;
|
||||
case ParsingContext.RestProperties: // fallthrough
|
||||
case ParsingContext.TypeMembers: return Diagnostics.Property_or_signature_expected;
|
||||
case ParsingContext.ClassMembers: return Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected;
|
||||
case ParsingContext.EnumMembers: return Diagnostics.Enum_member_expected;
|
||||
@ -4122,7 +4145,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseSpreadElement(): Expression {
|
||||
const node = <SpreadElementExpression>createNode(SyntaxKind.SpreadElementExpression);
|
||||
const node = <SpreadElement>createNode(SyntaxKind.SpreadElement);
|
||||
parseExpected(SyntaxKind.DotDotDotToken);
|
||||
node.expression = parseAssignmentExpressionOrHigher();
|
||||
return finishNode(node);
|
||||
@ -4162,6 +4185,12 @@ namespace ts {
|
||||
|
||||
function parseObjectLiteralElement(): ObjectLiteralElementLike {
|
||||
const fullStart = scanner.getStartPos();
|
||||
const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken);
|
||||
if (dotDotDotToken) {
|
||||
const spreadElement = <SpreadAssignment>createNode(SyntaxKind.SpreadAssignment, fullStart);
|
||||
spreadElement.expression = parseAssignmentExpressionOrHigher();
|
||||
return addJSDocComment(finishNode(spreadElement));
|
||||
}
|
||||
const decorators = parseDecorators();
|
||||
const modifiers = parseModifiers();
|
||||
|
||||
@ -4865,6 +4894,7 @@ namespace ts {
|
||||
|
||||
function parseObjectBindingElement(): BindingElement {
|
||||
const node = <BindingElement>createNode(SyntaxKind.BindingElement);
|
||||
node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken);
|
||||
const tokenIsIdentifier = isIdentifier();
|
||||
const propertyName = parsePropertyName();
|
||||
if (tokenIsIdentifier && token() !== SyntaxKind.ColonToken) {
|
||||
@ -5809,6 +5839,7 @@ namespace ts {
|
||||
JsxChildren, // Things between opening and closing JSX tags
|
||||
ArrayLiteralMembers, // Members in array literal
|
||||
Parameters, // Parameters in parameter list
|
||||
RestProperties, // Property names in a rest type list
|
||||
TypeParameters, // Type parameters in type parameter list
|
||||
TypeArguments, // Type arguments in type argument list
|
||||
TupleElementTypes, // Element types in tuple element type list
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
namespace ts {
|
||||
/** The version of the TypeScript compiler release */
|
||||
|
||||
export const version = "2.1.0";
|
||||
export const version = "2.2.0";
|
||||
|
||||
const emptyArray: any[] = [];
|
||||
|
||||
@ -239,11 +239,11 @@ namespace ts {
|
||||
const { line, character } = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
|
||||
const fileName = diagnostic.file.fileName;
|
||||
const relativeFileName = convertToRelativePath(fileName, host.getCurrentDirectory(), fileName => host.getCanonicalFileName(fileName));
|
||||
output += `${ relativeFileName }(${ line + 1 },${ character + 1 }): `;
|
||||
output += `${relativeFileName}(${line + 1},${character + 1}): `;
|
||||
}
|
||||
|
||||
const category = DiagnosticCategory[diagnostic.category].toLowerCase();
|
||||
output += `${ category } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) }${ host.getNewLine() }`;
|
||||
output += `${category} TS${diagnostic.code}: ${flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine())}${host.getNewLine()}`;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
@ -420,6 +420,7 @@ namespace ts {
|
||||
getTypeCount: () => getDiagnosticsProducingTypeChecker().getTypeCount(),
|
||||
getFileProcessingDiagnostics: () => fileProcessingDiagnostics,
|
||||
getResolvedTypeReferenceDirectives: () => resolvedTypeReferenceDirectives,
|
||||
isSourceFileFromExternalLibrary,
|
||||
dropDiagnosticsProducingTypeChecker
|
||||
};
|
||||
|
||||
@ -449,10 +450,6 @@ namespace ts {
|
||||
return commonSourceDirectory;
|
||||
}
|
||||
|
||||
function isSourceFileFromExternalLibrary(file: SourceFile): boolean {
|
||||
return !!sourceFilesFoundSearchingNodeModules[file.path];
|
||||
}
|
||||
|
||||
function getClassifiableNames() {
|
||||
if (!classifiableNames) {
|
||||
// Initialize a checker so that all our files are bound.
|
||||
@ -480,7 +477,7 @@ namespace ts {
|
||||
return resolveModuleNamesWorker(moduleNames, containingFile);
|
||||
}
|
||||
|
||||
// at this point we know that either
|
||||
// at this point we know that either
|
||||
// - file has local declarations for ambient modules
|
||||
// OR
|
||||
// - old program state is available
|
||||
@ -674,7 +671,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const modifiedFilePaths = modifiedSourceFiles.map(f => f.newFile.path);
|
||||
// try to verify results of module resolution
|
||||
// try to verify results of module resolution
|
||||
for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {
|
||||
const newSourceFilePath = getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory);
|
||||
if (resolveModuleNamesWorker) {
|
||||
@ -734,6 +731,10 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function isSourceFileFromExternalLibrary(file: SourceFile): boolean {
|
||||
return sourceFilesFoundSearchingNodeModules[file.path];
|
||||
}
|
||||
|
||||
function getDiagnosticsProducingTypeChecker() {
|
||||
return diagnosticsProducingTypeChecker || (diagnosticsProducingTypeChecker = createTypeChecker(program, /*produceDiagnostics:*/ true));
|
||||
}
|
||||
@ -908,48 +909,24 @@ namespace ts {
|
||||
function getJavaScriptSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
|
||||
return runWithCancellationToken(() => {
|
||||
const diagnostics: Diagnostic[] = [];
|
||||
let parent: Node = sourceFile;
|
||||
walk(sourceFile);
|
||||
|
||||
return diagnostics;
|
||||
|
||||
function walk(node: Node): boolean {
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
function walk(node: Node) {
|
||||
// Return directly from the case if the given node doesnt want to visit each child
|
||||
// Otherwise break to visit each child
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.import_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.ExportAssignment:
|
||||
if ((<ExportAssignment>node).isExportEquals) {
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.export_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.Parameter:
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
if ((<ParameterDeclaration | PropertyDeclaration>parent).questionToken === node) {
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics._0_can_only_be_used_in_a_ts_file, "?"));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
let classDeclaration = <ClassDeclaration>node;
|
||||
if (checkModifiers(classDeclaration.modifiers) ||
|
||||
checkTypeParameters(classDeclaration.typeParameters)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.HeritageClause:
|
||||
let heritageClause = <HeritageClause>node;
|
||||
if (heritageClause.token === SyntaxKind.ImplementsKeyword) {
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.implements_clauses_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.interface_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.module_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.type_aliases_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
|
||||
// Pass through
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.Constructor:
|
||||
@ -959,124 +936,151 @@ namespace ts {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
const functionDeclaration = <FunctionLikeDeclaration>node;
|
||||
if (checkModifiers(functionDeclaration.modifiers) ||
|
||||
checkTypeParameters(functionDeclaration.typeParameters) ||
|
||||
checkTypeAnnotation(functionDeclaration.type)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.VariableStatement:
|
||||
const variableStatement = <VariableStatement>node;
|
||||
if (checkModifiers(variableStatement.modifiers)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
const variableDeclaration = <VariableDeclaration>node;
|
||||
if (checkTypeAnnotation(variableDeclaration.type)) {
|
||||
return true;
|
||||
// type annotation
|
||||
if ((<FunctionLikeDeclaration | VariableDeclaration | ParameterDeclaration | PropertyDeclaration>parent).type === node) {
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.types_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.import_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
case SyntaxKind.ExportAssignment:
|
||||
if ((<ExportAssignment>node).isExportEquals) {
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.export_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.HeritageClause:
|
||||
let heritageClause = <HeritageClause>node;
|
||||
if (heritageClause.token === SyntaxKind.ImplementsKeyword) {
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.implements_clauses_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.interface_declarations_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.module_declarations_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.type_aliases_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.enum_declarations_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
let typeAssertionExpression = <TypeAssertion>node;
|
||||
diagnostics.push(createDiagnosticForNode(typeAssertionExpression.type, Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
}
|
||||
|
||||
const prevParent = parent;
|
||||
parent = node;
|
||||
forEachChild(node, walk, walkArray);
|
||||
parent = prevParent;
|
||||
}
|
||||
|
||||
function walkArray(nodes: NodeArray<Node>) {
|
||||
if (parent.decorators === nodes && !options.experimentalDecorators) {
|
||||
diagnostics.push(createDiagnosticForNode(parent, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning));
|
||||
}
|
||||
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
// Check type parameters
|
||||
if (nodes === (<ClassDeclaration | FunctionLikeDeclaration>parent).typeParameters) {
|
||||
diagnostics.push(createDiagnosticForNodeArray(nodes, Diagnostics.type_parameter_declarations_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
}
|
||||
// pass through
|
||||
case SyntaxKind.VariableStatement:
|
||||
// Check modifiers
|
||||
if (nodes === (<ClassDeclaration | FunctionLikeDeclaration | VariableStatement>parent).modifiers) {
|
||||
return checkModifiers(<NodeArray<Modifier>>nodes, parent.kind === SyntaxKind.VariableStatement);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
// Check modifiers of property declaration
|
||||
if (nodes === (<PropertyDeclaration>parent).modifiers) {
|
||||
for (const modifier of <NodeArray<Modifier>>nodes) {
|
||||
if (modifier.kind !== SyntaxKind.StaticKeyword) {
|
||||
diagnostics.push(createDiagnosticForNode(modifier, Diagnostics._0_can_only_be_used_in_a_ts_file, tokenToString(modifier.kind)));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.Parameter:
|
||||
// Check modifiers of parameter declaration
|
||||
if (nodes === (<ParameterDeclaration>parent).modifiers) {
|
||||
diagnostics.push(createDiagnosticForNodeArray(nodes, Diagnostics.parameter_modifiers_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
const expression = <CallExpression>node;
|
||||
if (expression.typeArguments && expression.typeArguments.length > 0) {
|
||||
const start = expression.typeArguments.pos;
|
||||
diagnostics.push(createFileDiagnostic(sourceFile, start, expression.typeArguments.end - start,
|
||||
Diagnostics.type_arguments_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
// Check type arguments
|
||||
if (nodes === (<CallExpression | NewExpression | ExpressionWithTypeArguments>parent).typeArguments) {
|
||||
diagnostics.push(createDiagnosticForNodeArray(nodes, Diagnostics.type_arguments_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.Parameter:
|
||||
const parameter = <ParameterDeclaration>node;
|
||||
if (parameter.modifiers) {
|
||||
const start = parameter.modifiers.pos;
|
||||
diagnostics.push(createFileDiagnostic(sourceFile, start, parameter.modifiers.end - start,
|
||||
Diagnostics.parameter_modifiers_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
if (parameter.questionToken) {
|
||||
diagnostics.push(createDiagnosticForNode(parameter.questionToken, Diagnostics._0_can_only_be_used_in_a_ts_file, "?"));
|
||||
return true;
|
||||
}
|
||||
if (parameter.type) {
|
||||
diagnostics.push(createDiagnosticForNode(parameter.type, Diagnostics.types_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
const propertyDeclaration = <PropertyDeclaration>node;
|
||||
if (propertyDeclaration.modifiers) {
|
||||
for (const modifier of propertyDeclaration.modifiers) {
|
||||
if (modifier.kind !== SyntaxKind.StaticKeyword) {
|
||||
diagnostics.push(createDiagnosticForNode(modifier, Diagnostics._0_can_only_be_used_in_a_ts_file, tokenToString(modifier.kind)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (const node of nodes) {
|
||||
walk(node);
|
||||
}
|
||||
}
|
||||
|
||||
function checkModifiers(modifiers: NodeArray<Modifier>, isConstValid: boolean) {
|
||||
for (const modifier of modifiers) {
|
||||
switch (modifier.kind) {
|
||||
case SyntaxKind.ConstKeyword:
|
||||
if (isConstValid) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (checkTypeAnnotation((<PropertyDeclaration>node).type)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.enum_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
let typeAssertionExpression = <TypeAssertion>node;
|
||||
diagnostics.push(createDiagnosticForNode(typeAssertionExpression.type, Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.Decorator:
|
||||
if (!options.experimentalDecorators) {
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Fallthrough to report error
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.ReadonlyKeyword:
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
case SyntaxKind.AbstractKeyword:
|
||||
diagnostics.push(createDiagnosticForNode(modifier, Diagnostics._0_can_only_be_used_in_a_ts_file, tokenToString(modifier.kind)));
|
||||
break;
|
||||
|
||||
return forEachChild(node, walk);
|
||||
}
|
||||
|
||||
function checkTypeParameters(typeParameters: NodeArray<TypeParameterDeclaration>): boolean {
|
||||
if (typeParameters) {
|
||||
const start = typeParameters.pos;
|
||||
diagnostics.push(createFileDiagnostic(sourceFile, start, typeParameters.end - start, Diagnostics.type_parameter_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkTypeAnnotation(type: TypeNode): boolean {
|
||||
if (type) {
|
||||
diagnostics.push(createDiagnosticForNode(type, Diagnostics.types_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkModifiers(modifiers: NodeArray<Modifier>): boolean {
|
||||
if (modifiers) {
|
||||
for (const modifier of modifiers) {
|
||||
switch (modifier.kind) {
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.ReadonlyKeyword:
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
diagnostics.push(createDiagnosticForNode(modifier, Diagnostics._0_can_only_be_used_in_a_ts_file, tokenToString(modifier.kind)));
|
||||
return true;
|
||||
|
||||
// These are all legal modifiers.
|
||||
case SyntaxKind.StaticKeyword:
|
||||
case SyntaxKind.ExportKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
case SyntaxKind.DefaultKeyword:
|
||||
case SyntaxKind.AbstractKeyword:
|
||||
}
|
||||
// These are all legal modifiers.
|
||||
case SyntaxKind.StaticKeyword:
|
||||
case SyntaxKind.ExportKeyword:
|
||||
case SyntaxKind.DefaultKeyword:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
function createDiagnosticForNodeArray(nodes: NodeArray<Node>, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic {
|
||||
const start = nodes.pos;
|
||||
return createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
// Since these are syntactic diagnostics, parent might not have been set
|
||||
// this means the sourceFile cannot be infered from the node
|
||||
function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic {
|
||||
return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1140,9 +1144,14 @@ namespace ts {
|
||||
if (options.importHelpers
|
||||
&& (options.isolatedModules || isExternalModuleFile)
|
||||
&& !file.isDeclarationFile) {
|
||||
const externalHelpersModuleReference = <StringLiteral>createNode(SyntaxKind.StringLiteral);
|
||||
// synthesize 'import "tslib"' declaration
|
||||
const externalHelpersModuleReference = <StringLiteral>createSynthesizedNode(SyntaxKind.StringLiteral);
|
||||
externalHelpersModuleReference.text = externalHelpersModuleNameText;
|
||||
externalHelpersModuleReference.parent = file;
|
||||
const importDecl = createSynthesizedNode(SyntaxKind.ImportDeclaration);
|
||||
|
||||
importDecl.parent = file;
|
||||
externalHelpersModuleReference.parent = importDecl;
|
||||
|
||||
imports = [externalHelpersModuleReference];
|
||||
}
|
||||
|
||||
@ -1439,7 +1448,9 @@ namespace ts {
|
||||
collectExternalModuleReferences(file);
|
||||
if (file.imports.length || file.moduleAugmentations.length) {
|
||||
file.resolvedModules = createMap<ResolvedModuleFull>();
|
||||
const moduleNames = map(concatenate(file.imports, file.moduleAugmentations), getTextOfLiteral);
|
||||
// Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
|
||||
const nonGlobalAugmentation = filter(file.moduleAugmentations, (moduleAugmentation) => moduleAugmentation.kind === SyntaxKind.StringLiteral);
|
||||
const moduleNames = map(concatenate(file.imports, nonGlobalAugmentation), getTextOfLiteral);
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory), file);
|
||||
Debug.assert(resolutions.length === moduleNames.length);
|
||||
for (let i = 0; i < moduleNames.length; i++) {
|
||||
@ -1670,7 +1681,15 @@ namespace ts {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators"));
|
||||
}
|
||||
|
||||
if (options.reactNamespace && !isIdentifierText(options.reactNamespace, languageVersion)) {
|
||||
if (options.jsxFactory) {
|
||||
if (options.reactNamespace) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "reactNamespace", "jsxFactory"));
|
||||
}
|
||||
if (!parseIsolatedEntityName(options.jsxFactory, languageVersion)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFactory));
|
||||
}
|
||||
}
|
||||
else if (options.reactNamespace && !isIdentifierText(options.reactNamespace, languageVersion)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace));
|
||||
}
|
||||
|
||||
@ -1690,13 +1709,19 @@ namespace ts {
|
||||
const emitFilePath = toPath(emitFileName, currentDirectory, getCanonicalFileName);
|
||||
// Report error if the output overwrites input file
|
||||
if (filesByName.contains(emitFilePath)) {
|
||||
createEmitBlockingDiagnostics(emitFileName, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file);
|
||||
let chain: DiagnosticMessageChain;
|
||||
if (!options.configFilePath) {
|
||||
// The program is from either an inferred project or an external project
|
||||
chain = chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig);
|
||||
}
|
||||
chain = chainDiagnosticMessages(chain, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file, emitFileName);
|
||||
blockEmittingOfFile(emitFileName, createCompilerDiagnosticFromMessageChain(chain));
|
||||
}
|
||||
|
||||
// Report error if multiple files write into same file
|
||||
if (emitFilesSeen.contains(emitFilePath)) {
|
||||
// Already seen the same emit file - report error
|
||||
createEmitBlockingDiagnostics(emitFileName, Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files);
|
||||
blockEmittingOfFile(emitFileName, createCompilerDiagnostic(Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files, emitFileName));
|
||||
}
|
||||
else {
|
||||
emitFilesSeen.set(emitFilePath, true);
|
||||
@ -1705,9 +1730,9 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createEmitBlockingDiagnostics(emitFileName: string, message: DiagnosticMessage) {
|
||||
function blockEmittingOfFile(emitFileName: string, diag: Diagnostic) {
|
||||
hasEmitBlockingDiagnostics.set(toPath(emitFileName, currentDirectory, getCanonicalFileName), true);
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, emitFileName));
|
||||
programDiagnostics.add(diag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +17,11 @@ namespace ts {
|
||||
readFile(path: string, encoding?: string): string;
|
||||
getFileSize?(path: string): number;
|
||||
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
|
||||
watchFile?(path: string, callback: FileWatcherCallback): FileWatcher;
|
||||
/**
|
||||
* @pollingInterval - this parameter is used in polling-based watchers and ignored in watchers that
|
||||
* use native OS file watching
|
||||
*/
|
||||
watchFile?(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
watchDirectory?(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
resolvePath(path: string): string;
|
||||
fileExists(path: string): boolean;
|
||||
@ -439,6 +443,7 @@ namespace ts {
|
||||
return filter<string>(_fs.readdirSync(path), dir => fileSystemEntryExists(combinePaths(path, dir), FileSystemEntryKind.Directory));
|
||||
}
|
||||
|
||||
const noOpFileWatcher: FileWatcher = { close: noop };
|
||||
const nodeSystem: System = {
|
||||
args: process.argv.slice(2),
|
||||
newLine: _os.EOL,
|
||||
@ -448,7 +453,7 @@ namespace ts {
|
||||
},
|
||||
readFile,
|
||||
writeFile,
|
||||
watchFile: (fileName, callback) => {
|
||||
watchFile: (fileName, callback, pollingInterval) => {
|
||||
if (useNonPollingWatchers) {
|
||||
const watchedFile = watchedFileSet.addFile(fileName, callback);
|
||||
return {
|
||||
@ -456,7 +461,7 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
else {
|
||||
_fs.watchFile(fileName, { persistent: true, interval: 250 }, fileChanged);
|
||||
_fs.watchFile(fileName, { persistent: true, interval: pollingInterval || 250 }, fileChanged);
|
||||
return {
|
||||
close: () => _fs.unwatchFile(fileName, fileChanged)
|
||||
};
|
||||
@ -475,7 +480,7 @@ namespace ts {
|
||||
// (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
|
||||
let options: any;
|
||||
if (!directoryExists(directoryName)) {
|
||||
return;
|
||||
return noOpFileWatcher;
|
||||
}
|
||||
|
||||
if (isNode4OrLater() && (process.platform === "win32" || process.platform === "darwin")) {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/// <reference path="visitor.ts" />
|
||||
/// <reference path="transformers/ts.ts" />
|
||||
/// <reference path="transformers/jsx.ts" />
|
||||
/// <reference path="transformers/esnext.ts" />
|
||||
/// <reference path="transformers/es2017.ts" />
|
||||
/// <reference path="transformers/es2016.ts" />
|
||||
/// <reference path="transformers/es2015.ts" />
|
||||
@ -116,6 +117,10 @@ namespace ts {
|
||||
transformers.push(transformJsx);
|
||||
}
|
||||
|
||||
if (languageVersion < ScriptTarget.ESNext) {
|
||||
transformers.push(transformESNext);
|
||||
}
|
||||
|
||||
if (languageVersion < ScriptTarget.ES2017) {
|
||||
transformers.push(transformES2017);
|
||||
}
|
||||
|
||||
@ -17,7 +17,8 @@ namespace ts {
|
||||
node: BinaryExpression,
|
||||
needsValue: boolean,
|
||||
recordTempVariable: (node: Identifier) => void,
|
||||
visitor?: (node: Node) => VisitResult<Node>): Expression {
|
||||
visitor?: (node: Node) => VisitResult<Node>,
|
||||
transformRest?: boolean): Expression {
|
||||
|
||||
if (isEmptyObjectLiteralOrArrayLiteral(node.left)) {
|
||||
const right = node.right;
|
||||
@ -51,7 +52,7 @@ namespace ts {
|
||||
location = value;
|
||||
}
|
||||
|
||||
flattenDestructuring(node, value, location, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
flattenDestructuring(node, value, location, emitAssignment, emitTempVariableAssignment, recordTempVariable, emitRestAssignment, transformRest, visitor);
|
||||
|
||||
if (needsValue) {
|
||||
expressions.push(value);
|
||||
@ -61,7 +62,7 @@ namespace ts {
|
||||
aggregateTransformFlags(expression);
|
||||
return expression;
|
||||
|
||||
function emitAssignment(name: Identifier, value: Expression, location: TextRange) {
|
||||
function emitAssignment(name: Identifier | ObjectLiteralExpression, value: Expression, location: TextRange) {
|
||||
const expression = createAssignment(name, value, location);
|
||||
|
||||
// NOTE: this completely disables source maps, but aligns with the behavior of
|
||||
@ -77,6 +78,10 @@ namespace ts {
|
||||
emitAssignment(name, value, location);
|
||||
return name;
|
||||
}
|
||||
|
||||
function emitRestAssignment(elements: ObjectLiteralElementLike[], value: Expression, location: TextRange) {
|
||||
emitAssignment(createObjectLiteral(elements), value, location);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,14 +94,15 @@ namespace ts {
|
||||
export function flattenParameterDestructuring(
|
||||
node: ParameterDeclaration,
|
||||
value: Expression,
|
||||
visitor?: (node: Node) => VisitResult<Node>) {
|
||||
visitor?: (node: Node) => VisitResult<Node>,
|
||||
transformRest?: boolean) {
|
||||
const declarations: VariableDeclaration[] = [];
|
||||
|
||||
flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, noop, emitRestAssignment, transformRest, visitor);
|
||||
|
||||
return declarations;
|
||||
|
||||
function emitAssignment(name: Identifier, value: Expression, location: TextRange) {
|
||||
function emitAssignment(name: Identifier | BindingPattern, value: Expression, location: TextRange) {
|
||||
const declaration = createVariableDeclaration(name, /*type*/ undefined, value, location);
|
||||
|
||||
// NOTE: this completely disables source maps, but aligns with the behavior of
|
||||
@ -112,6 +118,10 @@ namespace ts {
|
||||
emitAssignment(name, value, location);
|
||||
return name;
|
||||
}
|
||||
|
||||
function emitRestAssignment(elements: BindingElement[], value: Expression, location: TextRange) {
|
||||
emitAssignment(createObjectBindingPattern(elements), value, location);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -125,15 +135,16 @@ namespace ts {
|
||||
node: VariableDeclaration,
|
||||
value?: Expression,
|
||||
visitor?: (node: Node) => VisitResult<Node>,
|
||||
recordTempVariable?: (node: Identifier) => void) {
|
||||
recordTempVariable?: (node: Identifier) => void,
|
||||
transformRest?: boolean) {
|
||||
const declarations: VariableDeclaration[] = [];
|
||||
|
||||
let pendingAssignments: Expression[];
|
||||
flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, recordTempVariable, emitRestAssignment, transformRest, visitor);
|
||||
|
||||
return declarations;
|
||||
|
||||
function emitAssignment(name: Identifier, value: Expression, location: TextRange, original: Node) {
|
||||
function emitAssignment(name: Identifier | BindingPattern, value: Expression, location: TextRange, original: Node) {
|
||||
if (pendingAssignments) {
|
||||
pendingAssignments.push(value);
|
||||
value = inlineExpressions(pendingAssignments);
|
||||
@ -167,6 +178,10 @@ namespace ts {
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
function emitRestAssignment(elements: BindingElement[], value: Expression, location: TextRange, original: Node) {
|
||||
emitAssignment(createObjectBindingPattern(elements), value, location, original);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,15 +201,17 @@ namespace ts {
|
||||
|
||||
const pendingAssignments: Expression[] = [];
|
||||
|
||||
flattenDestructuring(node, /*value*/ undefined, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
flattenDestructuring(node, /*value*/ undefined, node, emitAssignment, emitTempVariableAssignment, noop, emitRestAssignment, /*transformRest*/ false, visitor);
|
||||
|
||||
const expression = inlineExpressions(pendingAssignments);
|
||||
aggregateTransformFlags(expression);
|
||||
return expression;
|
||||
|
||||
function emitAssignment(name: Identifier, value: Expression, location: TextRange, original: Node) {
|
||||
function emitAssignment(name: Identifier | ObjectLiteralExpression, value: Expression, location: TextRange, original: Node) {
|
||||
const expression = createAssignmentCallback
|
||||
? createAssignmentCallback(name, value, location)
|
||||
? createAssignmentCallback(name.kind === SyntaxKind.Identifier ? name : emitTempVariableAssignment(name, location),
|
||||
value,
|
||||
location)
|
||||
: createAssignment(name, value, location);
|
||||
|
||||
emitPendingAssignment(expression, original);
|
||||
@ -206,6 +223,10 @@ namespace ts {
|
||||
return name;
|
||||
}
|
||||
|
||||
function emitRestAssignment(elements: ObjectLiteralElementLike[], value: Expression, location: TextRange, original: Node) {
|
||||
emitAssignment(createObjectLiteral(elements), value, location, original);
|
||||
}
|
||||
|
||||
function emitPendingAssignment(expression: Expression, original: Node) {
|
||||
expression.original = original;
|
||||
|
||||
@ -223,6 +244,9 @@ namespace ts {
|
||||
location: TextRange,
|
||||
emitAssignment: (name: Identifier, value: Expression, location: TextRange, original: Node) => void,
|
||||
emitTempVariableAssignment: (value: Expression, location: TextRange) => Identifier,
|
||||
recordTempVariable: (node: Identifier) => void,
|
||||
emitRestAssignment: (elements: (ObjectLiteralElementLike[] | BindingElement[]), value: Expression, location: TextRange, original: Node) => void,
|
||||
transformRest: boolean,
|
||||
visitor?: (node: Node) => VisitResult<Node>) {
|
||||
if (value && visitor) {
|
||||
value = visitNode(value, visitor, isExpression);
|
||||
@ -284,23 +308,92 @@ namespace ts {
|
||||
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, location, emitTempVariableAssignment);
|
||||
}
|
||||
|
||||
for (const p of properties) {
|
||||
let bindingElements: ObjectLiteralElementLike[] = [];
|
||||
for (let i = 0; i < properties.length; i++) {
|
||||
const p = properties[i];
|
||||
if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
const propName = <Identifier | LiteralExpression>(<PropertyAssignment>p).name;
|
||||
const target = p.kind === SyntaxKind.ShorthandPropertyAssignment ? <ShorthandPropertyAssignment>p : (<PropertyAssignment>p).initializer || propName;
|
||||
// Assignment for target = value.propName should highligh whole property, hence use p as source map node
|
||||
emitDestructuringAssignment(target, createDestructuringPropertyAccess(value, propName), p);
|
||||
if (!transformRest ||
|
||||
p.transformFlags & TransformFlags.ContainsSpreadExpression ||
|
||||
(p.kind === SyntaxKind.PropertyAssignment && p.initializer.transformFlags & TransformFlags.ContainsSpreadExpression)) {
|
||||
if (bindingElements.length) {
|
||||
emitRestAssignment(bindingElements, value, location, target);
|
||||
bindingElements = [];
|
||||
}
|
||||
const propName = <Identifier | LiteralExpression>(<PropertyAssignment>p).name;
|
||||
const bindingTarget = p.kind === SyntaxKind.ShorthandPropertyAssignment ? <ShorthandPropertyAssignment>p : (<PropertyAssignment>p).initializer || propName;
|
||||
// Assignment for bindingTarget = value.propName should highlight whole property, hence use p as source map node
|
||||
emitDestructuringAssignment(bindingTarget, createDestructuringPropertyAccess(value, propName), p);
|
||||
}
|
||||
else {
|
||||
bindingElements.push(p);
|
||||
}
|
||||
}
|
||||
else if (i === properties.length - 1 &&
|
||||
p.kind === SyntaxKind.SpreadAssignment &&
|
||||
p.expression.kind === SyntaxKind.Identifier) {
|
||||
if (bindingElements.length) {
|
||||
emitRestAssignment(bindingElements, value, location, target);
|
||||
bindingElements = [];
|
||||
}
|
||||
const propName = (p as SpreadAssignment).expression as Identifier;
|
||||
const restCall = createRestCall(value, target.properties, p => p.name, target);
|
||||
emitDestructuringAssignment(propName, restCall, p);
|
||||
}
|
||||
}
|
||||
if (bindingElements.length) {
|
||||
emitRestAssignment(bindingElements, value, location, target);
|
||||
bindingElements = [];
|
||||
}
|
||||
}
|
||||
|
||||
function emitArrayLiteralAssignment(target: ArrayLiteralExpression, value: Expression, location: TextRange) {
|
||||
if (transformRest) {
|
||||
emitESNextArrayLiteralAssignment(target, value, location);
|
||||
}
|
||||
else {
|
||||
emitES2015ArrayLiteralAssignment(target, value, location);
|
||||
}
|
||||
}
|
||||
|
||||
function emitESNextArrayLiteralAssignment(target: ArrayLiteralExpression, value: Expression, location: TextRange) {
|
||||
const elements = target.elements;
|
||||
const numElements = elements.length;
|
||||
if (numElements !== 1) {
|
||||
// For anything but a single element destructuring we need to generate a temporary
|
||||
// to ensure value is evaluated exactly once.
|
||||
// When doing so we want to hightlight the passed in source map node since thats the one needing this temp assignment
|
||||
// When doing so we want to highlight the passed-in source map node since thats the one needing this temp assignment
|
||||
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, location, emitTempVariableAssignment);
|
||||
}
|
||||
|
||||
const expressions: Expression[] = [];
|
||||
const spreadContainingExpressions: [Expression, Identifier][] = [];
|
||||
for (let i = 0; i < numElements; i++) {
|
||||
const e = elements[i];
|
||||
if (e.kind === SyntaxKind.OmittedExpression) {
|
||||
continue;
|
||||
}
|
||||
if (e.transformFlags & TransformFlags.ContainsSpreadExpression && i < numElements - 1) {
|
||||
const tmp = createTempVariable(recordTempVariable);
|
||||
spreadContainingExpressions.push([e, tmp]);
|
||||
expressions.push(tmp);
|
||||
}
|
||||
else {
|
||||
expressions.push(e);
|
||||
}
|
||||
}
|
||||
emitAssignment(updateArrayLiteral(target, expressions) as any as Identifier, value, undefined, undefined);
|
||||
for (const [e, tmp] of spreadContainingExpressions) {
|
||||
emitDestructuringAssignment(e, tmp, e);
|
||||
}
|
||||
}
|
||||
|
||||
function emitES2015ArrayLiteralAssignment(target: ArrayLiteralExpression, value: Expression, location: TextRange) {
|
||||
const elements = target.elements;
|
||||
const numElements = elements.length;
|
||||
if (numElements !== 1) {
|
||||
// For anything but a single element destructuring we need to generate a temporary
|
||||
// to ensure value is evaluated exactly once.
|
||||
// When doing so we want to highlight the passed-in source map node since thats the one needing this temp assignment
|
||||
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, location, emitTempVariableAssignment);
|
||||
}
|
||||
|
||||
@ -308,20 +401,41 @@ namespace ts {
|
||||
const e = elements[i];
|
||||
if (e.kind !== SyntaxKind.OmittedExpression) {
|
||||
// Assignment for target = value.propName should highligh whole property, hence use e as source map node
|
||||
if (e.kind !== SyntaxKind.SpreadElementExpression) {
|
||||
if (e.kind !== SyntaxKind.SpreadElement) {
|
||||
emitDestructuringAssignment(e, createElementAccess(value, createLiteral(i)), e);
|
||||
}
|
||||
else if (i === numElements - 1) {
|
||||
emitDestructuringAssignment((<SpreadElementExpression>e).expression, createArraySlice(value, i), e);
|
||||
emitDestructuringAssignment((<SpreadElement>e).expression, createArraySlice(value, i), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement
|
||||
* `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);`*/
|
||||
function createRestCall<T extends Node>(value: Expression, elements: T[], getPropertyName: (element: T) => PropertyName, location: TextRange): Expression {
|
||||
const propertyNames: LiteralExpression[] = [];
|
||||
for (let i = 0; i < elements.length - 1; i++) {
|
||||
if (isOmittedExpression(elements[i])) {
|
||||
continue;
|
||||
}
|
||||
const str = <StringLiteral>createSynthesizedNode(SyntaxKind.StringLiteral);
|
||||
str.pos = location.pos;
|
||||
str.end = location.end;
|
||||
str.text = getTextOfPropertyName(getPropertyName(elements[i]));
|
||||
propertyNames.push(str);
|
||||
}
|
||||
const args = createSynthesizedNodeArray([value, createArrayLiteral(propertyNames, location)]);
|
||||
return createCall(createIdentifier("__rest"), undefined, args);
|
||||
}
|
||||
|
||||
function emitBindingElement(target: VariableDeclaration | ParameterDeclaration | BindingElement, value: Expression) {
|
||||
// Any temporary assignments needed to emit target = value should point to target
|
||||
const initializer = visitor ? visitNode(target.initializer, visitor, isExpression) : target.initializer;
|
||||
if (initializer) {
|
||||
if (transformRest) {
|
||||
value = value || initializer;
|
||||
}
|
||||
else if (initializer) {
|
||||
// Combine value and initializer
|
||||
value = value ? createDefaultValueCheck(value, initializer, target) : initializer;
|
||||
}
|
||||
@ -331,9 +445,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
const name = target.name;
|
||||
if (isBindingPattern(name)) {
|
||||
const elements = name.elements;
|
||||
const numElements = elements.length;
|
||||
if (!isBindingPattern(name)) {
|
||||
emitAssignment(name, value, target, target);
|
||||
}
|
||||
else {
|
||||
const numElements = name.elements.length;
|
||||
if (numElements !== 1) {
|
||||
// For anything other than a single-element destructuring we need to generate a temporary
|
||||
// to ensure value is evaluated exactly once. Additionally, if we have zero elements
|
||||
@ -341,29 +457,104 @@ namespace ts {
|
||||
// so in that case, we'll intentionally create that temporary.
|
||||
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ numElements !== 0, target, emitTempVariableAssignment);
|
||||
}
|
||||
for (let i = 0; i < numElements; i++) {
|
||||
const element = elements[i];
|
||||
if (isOmittedExpression(element)) {
|
||||
continue;
|
||||
}
|
||||
else if (name.kind === SyntaxKind.ObjectBindingPattern) {
|
||||
// Rewrite element to a declaration with an initializer that fetches property
|
||||
const propName = element.propertyName || <Identifier>element.name;
|
||||
emitBindingElement(element, createDestructuringPropertyAccess(value, propName));
|
||||
}
|
||||
else {
|
||||
if (!element.dotDotDotToken) {
|
||||
// Rewrite element to a declaration that accesses array element at index i
|
||||
emitBindingElement(element, createElementAccess(value, i));
|
||||
}
|
||||
else if (i === numElements - 1) {
|
||||
emitBindingElement(element, createArraySlice(value, i));
|
||||
}
|
||||
}
|
||||
if (name.kind === SyntaxKind.ArrayBindingPattern) {
|
||||
emitArrayBindingElement(name as ArrayBindingPattern, value);
|
||||
}
|
||||
else {
|
||||
emitObjectBindingElement(target, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitArrayBindingElement(name: ArrayBindingPattern, value: Expression) {
|
||||
if (transformRest) {
|
||||
emitESNextArrayBindingElement(name, value);
|
||||
}
|
||||
else {
|
||||
emitAssignment(name, value, target, target);
|
||||
emitES2015ArrayBindingElement(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
function emitES2015ArrayBindingElement(name: ArrayBindingPattern, value: Expression) {
|
||||
const elements = name.elements;
|
||||
const numElements = elements.length;
|
||||
for (let i = 0; i < numElements; i++) {
|
||||
const element = elements[i];
|
||||
if (isOmittedExpression(element)) {
|
||||
continue;
|
||||
}
|
||||
if (!element.dotDotDotToken) {
|
||||
// Rewrite element to a declaration that accesses array element at index i
|
||||
emitBindingElement(element, createElementAccess(value, i));
|
||||
}
|
||||
else if (i === numElements - 1) {
|
||||
emitBindingElement(element, createArraySlice(value, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitESNextArrayBindingElement(name: ArrayBindingPattern, value: Expression) {
|
||||
const elements = name.elements;
|
||||
const numElements = elements.length;
|
||||
const bindingElements: BindingElement[] = [];
|
||||
const spreadContainingElements: BindingElement[] = [];
|
||||
for (let i = 0; i < numElements; i++) {
|
||||
const element = elements[i];
|
||||
if (isOmittedExpression(element)) {
|
||||
continue;
|
||||
}
|
||||
if (element.transformFlags & TransformFlags.ContainsSpreadExpression && i < numElements - 1) {
|
||||
spreadContainingElements.push(element);
|
||||
bindingElements.push(createBindingElement(undefined, undefined, getGeneratedNameForNode(element), undefined, value));
|
||||
}
|
||||
else {
|
||||
bindingElements.push(element);
|
||||
}
|
||||
}
|
||||
emitAssignment(updateArrayBindingPattern(name, bindingElements) as any as Identifier, value, undefined, undefined);
|
||||
for (const element of spreadContainingElements) {
|
||||
emitBindingElement(element, getGeneratedNameForNode(element));
|
||||
}
|
||||
}
|
||||
|
||||
function emitObjectBindingElement(target: VariableDeclaration | ParameterDeclaration | BindingElement, value: Expression) {
|
||||
const name = target.name as BindingPattern;
|
||||
const elements = name.elements;
|
||||
const numElements = elements.length;
|
||||
let bindingElements: BindingElement[] = [];
|
||||
for (let i = 0; i < numElements; i++) {
|
||||
const element = elements[i];
|
||||
if (isOmittedExpression(element)) {
|
||||
continue;
|
||||
}
|
||||
if (i === numElements - 1 && element.dotDotDotToken) {
|
||||
if (bindingElements.length) {
|
||||
emitRestAssignment(bindingElements, value, target, target);
|
||||
bindingElements = [];
|
||||
}
|
||||
const restCall = createRestCall(value,
|
||||
name.elements,
|
||||
element => (element as BindingElement).propertyName || <Identifier>(element as BindingElement).name,
|
||||
name);
|
||||
emitBindingElement(element, restCall);
|
||||
}
|
||||
else if (transformRest && !(element.transformFlags & TransformFlags.ContainsSpreadExpression)) {
|
||||
// do not emit until we have a complete bundle of ES2015 syntax
|
||||
bindingElements.push(element);
|
||||
}
|
||||
else {
|
||||
if (bindingElements.length) {
|
||||
emitRestAssignment(bindingElements, value, target, target);
|
||||
bindingElements = [];
|
||||
}
|
||||
// Rewrite element to a declaration with an initializer that fetches property
|
||||
const propName = element.propertyName || <Identifier>element.name;
|
||||
emitBindingElement(element, createDestructuringPropertyAccess(value, propName));
|
||||
}
|
||||
}
|
||||
if (bindingElements.length) {
|
||||
emitRestAssignment(bindingElements, value, target, target);
|
||||
bindingElements = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -861,7 +861,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (constructor) {
|
||||
addDefaultValueAssignmentsIfNeeded(statements, constructor);
|
||||
addDefaultValueAssignmentsIfNeeded(statements, constructor, visitor, /*convertObjectRest*/ false);
|
||||
addRestParameterIfNeeded(statements, constructor, hasSynthesizedSuper);
|
||||
Debug.assert(statementOffset >= 0, "statementOffset not initialized correctly!");
|
||||
|
||||
@ -954,7 +954,7 @@ namespace ts {
|
||||
// If this isn't a derived class, just capture 'this' for arrow functions if necessary.
|
||||
if (!hasExtendsClause) {
|
||||
if (ctor) {
|
||||
addCaptureThisForNodeIfNeeded(statements, ctor);
|
||||
addCaptureThisForNodeIfNeeded(statements, ctor, enableSubstitutionsForCapturedThis);
|
||||
}
|
||||
return SuperCaptureResult.NoReplacement;
|
||||
}
|
||||
@ -1016,7 +1016,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Perform the capture.
|
||||
captureThisForNode(statements, ctor, superCallExpression, firstStatement);
|
||||
captureThisForNode(statements, ctor, superCallExpression, enableSubstitutionsForCapturedThis, firstStatement);
|
||||
|
||||
// If we're actually replacing the original statement, we need to signal this to the caller.
|
||||
if (superCallExpression) {
|
||||
@ -1085,242 +1085,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether we need to add default value assignments for a
|
||||
* function-like node.
|
||||
*
|
||||
* @param node A function-like node.
|
||||
*/
|
||||
function shouldAddDefaultValueAssignments(node: FunctionLikeDeclaration): boolean {
|
||||
return (node.transformFlags & TransformFlags.ContainsDefaultValueAssignments) !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds statements to the body of a function-like node if it contains parameters with
|
||||
* binding patterns or initializers.
|
||||
*
|
||||
* @param statements The statements for the new function body.
|
||||
* @param node A function-like node.
|
||||
*/
|
||||
function addDefaultValueAssignmentsIfNeeded(statements: Statement[], node: FunctionLikeDeclaration): void {
|
||||
if (!shouldAddDefaultValueAssignments(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const parameter of node.parameters) {
|
||||
const { name, initializer, dotDotDotToken } = parameter;
|
||||
|
||||
// A rest parameter cannot have a binding pattern or an initializer,
|
||||
// so let's just ignore it.
|
||||
if (dotDotDotToken) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isBindingPattern(name)) {
|
||||
addDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer);
|
||||
}
|
||||
else if (initializer) {
|
||||
addDefaultValueAssignmentForInitializer(statements, parameter, name, initializer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds statements to the body of a function-like node for parameters with binding patterns
|
||||
*
|
||||
* @param statements The statements for the new function body.
|
||||
* @param parameter The parameter for the function.
|
||||
* @param name The name of the parameter.
|
||||
* @param initializer The initializer for the parameter.
|
||||
*/
|
||||
function addDefaultValueAssignmentForBindingPattern(statements: Statement[], parameter: ParameterDeclaration, name: BindingPattern, initializer: Expression): void {
|
||||
const temp = getGeneratedNameForNode(parameter);
|
||||
|
||||
// In cases where a binding pattern is simply '[]' or '{}',
|
||||
// we usually don't want to emit a var declaration; however, in the presence
|
||||
// of an initializer, we must emit that expression to preserve side effects.
|
||||
if (name.elements.length > 0) {
|
||||
statements.push(
|
||||
setEmitFlags(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(
|
||||
flattenParameterDestructuring(parameter, temp, visitor)
|
||||
)
|
||||
),
|
||||
EmitFlags.CustomPrologue
|
||||
)
|
||||
);
|
||||
}
|
||||
else if (initializer) {
|
||||
statements.push(
|
||||
setEmitFlags(
|
||||
createStatement(
|
||||
createAssignment(
|
||||
temp,
|
||||
visitNode(initializer, visitor, isExpression)
|
||||
)
|
||||
),
|
||||
EmitFlags.CustomPrologue
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds statements to the body of a function-like node for parameters with initializers.
|
||||
*
|
||||
* @param statements The statements for the new function body.
|
||||
* @param parameter The parameter for the function.
|
||||
* @param name The name of the parameter.
|
||||
* @param initializer The initializer for the parameter.
|
||||
*/
|
||||
function addDefaultValueAssignmentForInitializer(statements: Statement[], parameter: ParameterDeclaration, name: Identifier, initializer: Expression): void {
|
||||
initializer = visitNode(initializer, visitor, isExpression);
|
||||
const statement = createIf(
|
||||
createStrictEquality(
|
||||
getSynthesizedClone(name),
|
||||
createVoidZero()
|
||||
),
|
||||
setEmitFlags(
|
||||
createBlock([
|
||||
createStatement(
|
||||
createAssignment(
|
||||
setEmitFlags(getMutableClone(name), EmitFlags.NoSourceMap),
|
||||
setEmitFlags(initializer, EmitFlags.NoSourceMap | getEmitFlags(initializer)),
|
||||
/*location*/ parameter
|
||||
)
|
||||
)
|
||||
], /*location*/ parameter),
|
||||
EmitFlags.SingleLine | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTokenSourceMaps
|
||||
),
|
||||
/*elseStatement*/ undefined,
|
||||
/*location*/ parameter
|
||||
);
|
||||
statement.startsOnNewLine = true;
|
||||
setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.CustomPrologue);
|
||||
statements.push(statement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether we need to add statements to handle a rest parameter.
|
||||
*
|
||||
* @param node A ParameterDeclaration node.
|
||||
* @param inConstructorWithSynthesizedSuper A value indicating whether the parameter is
|
||||
* part of a constructor declaration with a
|
||||
* synthesized call to `super`
|
||||
*/
|
||||
function shouldAddRestParameter(node: ParameterDeclaration, inConstructorWithSynthesizedSuper: boolean) {
|
||||
return node && node.dotDotDotToken && node.name.kind === SyntaxKind.Identifier && !inConstructorWithSynthesizedSuper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds statements to the body of a function-like node if it contains a rest parameter.
|
||||
*
|
||||
* @param statements The statements for the new function body.
|
||||
* @param node A function-like node.
|
||||
* @param inConstructorWithSynthesizedSuper A value indicating whether the parameter is
|
||||
* part of a constructor declaration with a
|
||||
* synthesized call to `super`
|
||||
*/
|
||||
function addRestParameterIfNeeded(statements: Statement[], node: FunctionLikeDeclaration, inConstructorWithSynthesizedSuper: boolean): void {
|
||||
const parameter = lastOrUndefined(node.parameters);
|
||||
if (!shouldAddRestParameter(parameter, inConstructorWithSynthesizedSuper)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// `declarationName` is the name of the local declaration for the parameter.
|
||||
const declarationName = getMutableClone(<Identifier>parameter.name);
|
||||
setEmitFlags(declarationName, EmitFlags.NoSourceMap);
|
||||
|
||||
// `expressionName` is the name of the parameter used in expressions.
|
||||
const expressionName = getSynthesizedClone(<Identifier>parameter.name);
|
||||
const restIndex = node.parameters.length - 1;
|
||||
const temp = createLoopVariable();
|
||||
|
||||
// var param = [];
|
||||
statements.push(
|
||||
setEmitFlags(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
declarationName,
|
||||
/*type*/ undefined,
|
||||
createArrayLiteral([])
|
||||
)
|
||||
]),
|
||||
/*location*/ parameter
|
||||
),
|
||||
EmitFlags.CustomPrologue
|
||||
)
|
||||
);
|
||||
|
||||
// for (var _i = restIndex; _i < arguments.length; _i++) {
|
||||
// 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
|
||||
),
|
||||
createPostfixIncrement(temp, /*location*/ parameter),
|
||||
createBlock([
|
||||
startOnNewLine(
|
||||
createStatement(
|
||||
createAssignment(
|
||||
createElementAccess(
|
||||
expressionName,
|
||||
createSubtract(temp, createLiteral(restIndex))
|
||||
),
|
||||
createElementAccess(createIdentifier("arguments"), temp)
|
||||
),
|
||||
/*location*/ parameter
|
||||
)
|
||||
)
|
||||
])
|
||||
);
|
||||
|
||||
setEmitFlags(forStatement, EmitFlags.CustomPrologue);
|
||||
startOnNewLine(forStatement);
|
||||
statements.push(forStatement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a statement to capture the `this` of a function declaration if it is needed.
|
||||
*
|
||||
* @param statements The statements for the new function body.
|
||||
* @param node A node.
|
||||
*/
|
||||
function addCaptureThisForNodeIfNeeded(statements: Statement[], node: Node): void {
|
||||
if (node.transformFlags & TransformFlags.ContainsCapturedLexicalThis && node.kind !== SyntaxKind.ArrowFunction) {
|
||||
captureThisForNode(statements, node, createThis());
|
||||
}
|
||||
}
|
||||
|
||||
function captureThisForNode(statements: Statement[], node: Node, initializer: Expression | undefined, originalStatement?: Statement): void {
|
||||
enableSubstitutionsForCapturedThis();
|
||||
const captureThisStatement = createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
"_this",
|
||||
/*type*/ undefined,
|
||||
initializer
|
||||
)
|
||||
]),
|
||||
originalStatement
|
||||
);
|
||||
|
||||
setEmitFlags(captureThisStatement, EmitFlags.NoComments | EmitFlags.CustomPrologue);
|
||||
setSourceMapRange(captureThisStatement, node);
|
||||
statements.push(captureThisStatement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds statements to the class body function for a class to define the members of the
|
||||
* class.
|
||||
@ -1518,7 +1282,7 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node),
|
||||
transformFunctionBody(node, visitor, currentSourceFile, context, enableSubstitutionsForCapturedThis),
|
||||
/*location*/ node
|
||||
),
|
||||
/*original*/ node);
|
||||
@ -1545,7 +1309,7 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
/*type*/ undefined,
|
||||
saveStateAndInvoke(node, transformFunctionBody),
|
||||
saveStateAndInvoke(node, node => transformFunctionBody(node, visitor, currentSourceFile, context, enableSubstitutionsForCapturedThis)),
|
||||
location
|
||||
),
|
||||
/*original*/ node
|
||||
@ -1555,96 +1319,6 @@ namespace ts {
|
||||
return expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the body of a function-like node.
|
||||
*
|
||||
* @param node A function-like node.
|
||||
*/
|
||||
function transformFunctionBody(node: FunctionLikeDeclaration) {
|
||||
let multiLine = false; // indicates whether the block *must* be emitted as multiple lines
|
||||
let singleLine = false; // indicates whether the block *may* be emitted as a single line
|
||||
let statementsLocation: TextRange;
|
||||
let closeBraceLocation: TextRange;
|
||||
|
||||
const statements: Statement[] = [];
|
||||
const body = node.body;
|
||||
let statementOffset: number;
|
||||
|
||||
startLexicalEnvironment();
|
||||
if (isBlock(body)) {
|
||||
// ensureUseStrict is false because no new prologue-directive should be added.
|
||||
// addPrologueDirectives will simply put already-existing directives at the beginning of the target statement-array
|
||||
statementOffset = addPrologueDirectives(statements, body.statements, /*ensureUseStrict*/ false, visitor);
|
||||
}
|
||||
|
||||
addCaptureThisForNodeIfNeeded(statements, node);
|
||||
addDefaultValueAssignmentsIfNeeded(statements, node);
|
||||
addRestParameterIfNeeded(statements, node, /*inConstructorWithSynthesizedSuper*/ false);
|
||||
|
||||
// If we added any generated statements, this must be a multi-line block.
|
||||
if (!multiLine && statements.length > 0) {
|
||||
multiLine = true;
|
||||
}
|
||||
|
||||
if (isBlock(body)) {
|
||||
statementsLocation = body.statements;
|
||||
addRange(statements, visitNodes(body.statements, visitor, isStatement, statementOffset));
|
||||
|
||||
// If the original body was a multi-line block, this must be a multi-line block.
|
||||
if (!multiLine && body.multiLine) {
|
||||
multiLine = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Debug.assert(node.kind === SyntaxKind.ArrowFunction);
|
||||
|
||||
// To align with the old emitter, we use a synthetic end position on the location
|
||||
// for the statement list we synthesize when we down-level an arrow function with
|
||||
// an expression function body. This prevents both comments and source maps from
|
||||
// being emitted for the end position only.
|
||||
statementsLocation = moveRangeEnd(body, -1);
|
||||
|
||||
const equalsGreaterThanToken = (<ArrowFunction>node).equalsGreaterThanToken;
|
||||
if (!nodeIsSynthesized(equalsGreaterThanToken) && !nodeIsSynthesized(body)) {
|
||||
if (rangeEndIsOnSameLineAsRangeStart(equalsGreaterThanToken, body, currentSourceFile)) {
|
||||
singleLine = true;
|
||||
}
|
||||
else {
|
||||
multiLine = true;
|
||||
}
|
||||
}
|
||||
|
||||
const expression = visitNode(body, visitor, isExpression);
|
||||
const returnStatement = createReturn(expression, /*location*/ body);
|
||||
setEmitFlags(returnStatement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoTrailingSourceMap | EmitFlags.NoTrailingComments);
|
||||
statements.push(returnStatement);
|
||||
|
||||
// To align with the source map emit for the old emitter, we set a custom
|
||||
// source map location for the close brace.
|
||||
closeBraceLocation = body;
|
||||
}
|
||||
|
||||
const lexicalEnvironment = endLexicalEnvironment();
|
||||
addRange(statements, lexicalEnvironment);
|
||||
|
||||
// If we added any final generated statements, this must be a multi-line block
|
||||
if (!multiLine && lexicalEnvironment && lexicalEnvironment.length) {
|
||||
multiLine = true;
|
||||
}
|
||||
|
||||
const block = createBlock(createNodeArray(statements, statementsLocation), node.body, multiLine);
|
||||
if (!multiLine && singleLine) {
|
||||
setEmitFlags(block, EmitFlags.SingleLine);
|
||||
}
|
||||
|
||||
if (closeBraceLocation) {
|
||||
setTokenSourceMapRange(block, SyntaxKind.CloseBraceToken, closeBraceLocation);
|
||||
}
|
||||
|
||||
setOriginalNode(block, node.body);
|
||||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an ExpressionStatement that contains a destructuring assignment.
|
||||
*
|
||||
@ -1926,171 +1600,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function convertForOfToFor(node: ForOfStatement, convertedLoopBodyStatements: Statement[]): ForStatement {
|
||||
// The following ES6 code:
|
||||
//
|
||||
// for (let v of expr) { }
|
||||
//
|
||||
// should be emitted as
|
||||
//
|
||||
// for (var _i = 0, _a = expr; _i < _a.length; _i++) {
|
||||
// var v = _a[_i];
|
||||
// }
|
||||
//
|
||||
// where _a and _i are temps emitted to capture the RHS and the counter,
|
||||
// respectively.
|
||||
// When the left hand side is an expression instead of a let declaration,
|
||||
// the "let v" is not emitted.
|
||||
// When the left hand side is a let/const, the v is renamed if there is
|
||||
// another v in scope.
|
||||
// Note that all assignments to the LHS are emitted in the body, including
|
||||
// all destructuring.
|
||||
// Note also that because an extra statement is needed to assign to the LHS,
|
||||
// for-of bodies are always emitted as blocks.
|
||||
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
const initializer = node.initializer;
|
||||
const statements: Statement[] = [];
|
||||
|
||||
// In the case where the user wrote an identifier as the RHS, like this:
|
||||
//
|
||||
// for (let v of arr) { }
|
||||
//
|
||||
// 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)
|
||||
: createTempVariable(/*recordTempVariable*/ undefined);
|
||||
|
||||
// Initialize LHS
|
||||
// var v = _a[_i];
|
||||
if (isVariableDeclarationList(initializer)) {
|
||||
if (initializer.flags & NodeFlags.BlockScoped) {
|
||||
enableSubstitutionsForBlockScopedBindings();
|
||||
}
|
||||
|
||||
const firstOriginalDeclaration = firstOrUndefined(initializer.declarations);
|
||||
if (firstOriginalDeclaration && isBindingPattern(firstOriginalDeclaration.name)) {
|
||||
// This works whether the declaration is a var, let, or const.
|
||||
// It will use rhsIterationValue _a[_i] as the initializer.
|
||||
const declarations = flattenVariableDestructuring(
|
||||
firstOriginalDeclaration,
|
||||
createElementAccess(rhsReference, counter),
|
||||
visitor
|
||||
);
|
||||
|
||||
const declarationList = createVariableDeclarationList(declarations, /*location*/ initializer);
|
||||
setOriginalNode(declarationList, initializer);
|
||||
|
||||
// Adjust the source map range for the first declaration to align with the old
|
||||
// emitter.
|
||||
const firstDeclaration = declarations[0];
|
||||
const lastDeclaration = lastOrUndefined(declarations);
|
||||
setSourceMapRange(declarationList, createRange(firstDeclaration.pos, lastDeclaration.end));
|
||||
|
||||
statements.push(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
declarationList
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
// 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
|
||||
),
|
||||
/*location*/ moveRangeEnd(initializer, -1)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Initializer is an expression. Emit the expression in the body, so that it's
|
||||
// evaluated on every iteration.
|
||||
const assignment = createAssignment(initializer, createElementAccess(rhsReference, counter));
|
||||
if (isDestructuringAssignment(assignment)) {
|
||||
// This is a destructuring pattern, so we flatten the destructuring instead.
|
||||
statements.push(
|
||||
createStatement(
|
||||
flattenDestructuringAssignment(
|
||||
context,
|
||||
assignment,
|
||||
/*needsValue*/ false,
|
||||
hoistVariableDeclaration,
|
||||
visitor
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
// 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)));
|
||||
}
|
||||
}
|
||||
|
||||
let bodyLocation: TextRange;
|
||||
let statementsLocation: TextRange;
|
||||
if (convertedLoopBodyStatements) {
|
||||
addRange(statements, convertedLoopBodyStatements);
|
||||
}
|
||||
else {
|
||||
const statement = visitNode(node.statement, visitor, isStatement);
|
||||
if (isBlock(statement)) {
|
||||
addRange(statements, statement.statements);
|
||||
bodyLocation = statement;
|
||||
statementsLocation = statement.statements;
|
||||
}
|
||||
else {
|
||||
statements.push(statement);
|
||||
}
|
||||
}
|
||||
|
||||
// The old emitter does not emit source maps for the expression
|
||||
setEmitFlags(expression, EmitFlags.NoSourceMap | getEmitFlags(expression));
|
||||
|
||||
// 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
|
||||
);
|
||||
|
||||
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),
|
||||
EmitFlags.NoHoisting
|
||||
),
|
||||
createLessThan(
|
||||
counter,
|
||||
createPropertyAccess(rhsReference, "length"),
|
||||
/*location*/ node.expression
|
||||
),
|
||||
createPostfixIncrement(counter, /*location*/ node.expression),
|
||||
body,
|
||||
/*location*/ node
|
||||
);
|
||||
|
||||
// Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter.
|
||||
setEmitFlags(forStatement, EmitFlags.NoTokenTrailingSourceMaps);
|
||||
return forStatement;
|
||||
return <ForStatement>convertForOf(node, convertedLoopBodyStatements, visitor, enableSubstitutionsForBlockScopedBindings, context, /*transformRest*/ false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2751,7 +2261,7 @@ namespace ts {
|
||||
setEmitFlags(thisArg, EmitFlags.NoSubstitution);
|
||||
}
|
||||
let resultingCall: CallExpression | BinaryExpression;
|
||||
if (node.transformFlags & TransformFlags.ContainsSpreadElementExpression) {
|
||||
if (node.transformFlags & TransformFlags.ContainsSpreadExpression) {
|
||||
// [source]
|
||||
// f(...a, b)
|
||||
// x.m(...a, b)
|
||||
@ -2813,7 +2323,7 @@ namespace ts {
|
||||
*/
|
||||
function visitNewExpression(node: NewExpression): LeftHandSideExpression {
|
||||
// We are here because we contain a SpreadElementExpression.
|
||||
Debug.assert((node.transformFlags & TransformFlags.ContainsSpreadElementExpression) !== 0);
|
||||
Debug.assert((node.transformFlags & TransformFlags.ContainsSpreadExpression) !== 0);
|
||||
|
||||
// [source]
|
||||
// new C(...a)
|
||||
@ -2834,7 +2344,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms an array of Expression nodes that contains a SpreadElementExpression.
|
||||
* Transforms an array of Expression nodes that contains a SpreadExpression.
|
||||
*
|
||||
* @param elements The array of Expression nodes.
|
||||
* @param needsUniqueCopy A value indicating whether to ensure that the result is a fresh array.
|
||||
@ -2851,14 +2361,14 @@ namespace ts {
|
||||
// expressions into an array literal.
|
||||
const numElements = elements.length;
|
||||
const segments = flatten(
|
||||
spanMap(elements, partitionSpreadElement, (partition, visitPartition, _start, end) =>
|
||||
spanMap(elements, partitionSpread, (partition, visitPartition, _start, end) =>
|
||||
visitPartition(partition, multiLine, hasTrailingComma && end === numElements)
|
||||
)
|
||||
);
|
||||
|
||||
if (segments.length === 1) {
|
||||
const firstElement = elements[0];
|
||||
return needsUniqueCopy && isSpreadElementExpression(firstElement) && firstElement.expression.kind !== SyntaxKind.ArrayLiteralExpression
|
||||
return needsUniqueCopy && isSpreadExpression(firstElement) && firstElement.expression.kind !== SyntaxKind.ArrayLiteralExpression
|
||||
? createArraySlice(segments[0])
|
||||
: segments[0];
|
||||
}
|
||||
@ -2867,17 +2377,17 @@ namespace ts {
|
||||
return createArrayConcat(segments.shift(), segments);
|
||||
}
|
||||
|
||||
function partitionSpreadElement(node: Expression) {
|
||||
return isSpreadElementExpression(node)
|
||||
? visitSpanOfSpreadElements
|
||||
: visitSpanOfNonSpreadElements;
|
||||
function partitionSpread(node: Expression) {
|
||||
return isSpreadExpression(node)
|
||||
? visitSpanOfSpreads
|
||||
: visitSpanOfNonSpreads;
|
||||
}
|
||||
|
||||
function visitSpanOfSpreadElements(chunk: Expression[]): VisitResult<Expression> {
|
||||
return map(chunk, visitExpressionOfSpreadElement);
|
||||
function visitSpanOfSpreads(chunk: Expression[]): VisitResult<Expression> {
|
||||
return map(chunk, visitExpressionOfSpread);
|
||||
}
|
||||
|
||||
function visitSpanOfNonSpreadElements(chunk: Expression[], multiLine: boolean, hasTrailingComma: boolean): VisitResult<Expression> {
|
||||
function visitSpanOfNonSpreads(chunk: Expression[], multiLine: boolean, hasTrailingComma: boolean): VisitResult<Expression> {
|
||||
return createArrayLiteral(
|
||||
visitNodes(createNodeArray(chunk, /*location*/ undefined, hasTrailingComma), visitor, isExpression),
|
||||
/*location*/ undefined,
|
||||
@ -2886,11 +2396,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the expression of a SpreadElementExpression node.
|
||||
* Transforms the expression of a SpreadExpression node.
|
||||
*
|
||||
* @param node A SpreadElementExpression node.
|
||||
* @param node A SpreadExpression node.
|
||||
*/
|
||||
function visitExpressionOfSpreadElement(node: SpreadElementExpression) {
|
||||
function visitExpressionOfSpread(node: SpreadElement) {
|
||||
return visitNode(node.expression, visitor, isExpression);
|
||||
}
|
||||
|
||||
@ -3076,7 +2586,7 @@ namespace ts {
|
||||
const statements: Statement[] = [];
|
||||
startLexicalEnvironment();
|
||||
addRange(statements, prologue);
|
||||
addCaptureThisForNodeIfNeeded(statements, node);
|
||||
addCaptureThisForNodeIfNeeded(statements, node, enableSubstitutionsForCapturedThis);
|
||||
addRange(statements, visitNodes(createNodeArray(remaining), visitor, isStatement));
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
const clone = getMutableClone(node);
|
||||
@ -3266,11 +2776,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
const callArgument = singleOrUndefined((<CallExpression>statementExpression).arguments);
|
||||
if (!callArgument || !nodeIsSynthesized(callArgument) || callArgument.kind !== SyntaxKind.SpreadElementExpression) {
|
||||
if (!callArgument || !nodeIsSynthesized(callArgument) || callArgument.kind !== SyntaxKind.SpreadElement) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const expression = (<SpreadElementExpression>callArgument).expression;
|
||||
const expression = (<SpreadElement>callArgument).expression;
|
||||
return isIdentifier(expression) && expression === parameter.name;
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +32,6 @@ namespace ts {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.BinaryExpression:
|
||||
return visitBinaryExpression(<BinaryExpression>node);
|
||||
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return visitEachChild(node, visitor, context);
|
||||
|
||||
272
src/compiler/transformers/esnext.ts
Normal file
272
src/compiler/transformers/esnext.ts
Normal file
@ -0,0 +1,272 @@
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../visitor.ts" />
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
export function transformESNext(context: TransformationContext) {
|
||||
const {
|
||||
hoistVariableDeclaration,
|
||||
} = context;
|
||||
let currentSourceFile: SourceFile;
|
||||
return transformSourceFile;
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
currentSourceFile = node;
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
if (node.transformFlags & TransformFlags.ESNext) {
|
||||
return visitorWorker(node);
|
||||
}
|
||||
else if (node.transformFlags & TransformFlags.ContainsESNext) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
else {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
function visitorWorker(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return visitObjectLiteralExpression(node as ObjectLiteralExpression);
|
||||
case SyntaxKind.BinaryExpression:
|
||||
return visitBinaryExpression(node as BinaryExpression);
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return visitVariableDeclaration(node as VariableDeclaration);
|
||||
case SyntaxKind.ForOfStatement:
|
||||
return visitForOfStatement(node as ForOfStatement);
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
return node;
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
return visitFunctionDeclaration(node as FunctionDeclaration);
|
||||
case SyntaxKind.FunctionExpression:
|
||||
return visitFunctionExpression(node as FunctionExpression);
|
||||
case SyntaxKind.ArrowFunction:
|
||||
return visitArrowFunction(node as ArrowFunction);
|
||||
case SyntaxKind.Parameter:
|
||||
return visitParameter(node as ParameterDeclaration);
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
}
|
||||
|
||||
function chunkObjectLiteralElements(elements: ObjectLiteralElement[]): Expression[] {
|
||||
let chunkObject: (ShorthandPropertyAssignment | PropertyAssignment)[];
|
||||
const objects: Expression[] = [];
|
||||
for (const e of elements) {
|
||||
if (e.kind === SyntaxKind.SpreadAssignment) {
|
||||
if (chunkObject) {
|
||||
objects.push(createObjectLiteral(chunkObject));
|
||||
chunkObject = undefined;
|
||||
}
|
||||
const target = (e as SpreadAssignment).expression;
|
||||
objects.push(visitNode(target, visitor, isExpression));
|
||||
}
|
||||
else {
|
||||
if (!chunkObject) {
|
||||
chunkObject = [];
|
||||
}
|
||||
if (e.kind === SyntaxKind.PropertyAssignment) {
|
||||
const p = e as PropertyAssignment;
|
||||
chunkObject.push(createPropertyAssignment(p.name, visitNode(p.initializer, visitor, isExpression)));
|
||||
}
|
||||
else {
|
||||
chunkObject.push(e as ShorthandPropertyAssignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chunkObject) {
|
||||
objects.push(createObjectLiteral(chunkObject));
|
||||
}
|
||||
|
||||
return objects;
|
||||
}
|
||||
|
||||
function visitObjectLiteralExpression(node: ObjectLiteralExpression): Expression {
|
||||
// spread elements emit like so:
|
||||
// non-spread elements are chunked together into object literals, and then all are passed to __assign:
|
||||
// { a, ...o, b } => __assign({a}, o, {b});
|
||||
// If the first element is a spread element, then the first argument to __assign is {}:
|
||||
// { ...o, a, b, ...o2 } => __assign({}, o, {a, b}, o2)
|
||||
const objects = chunkObjectLiteralElements(node.properties);
|
||||
if (objects.length && objects[0].kind !== SyntaxKind.ObjectLiteralExpression) {
|
||||
objects.unshift(createObjectLiteral());
|
||||
}
|
||||
return createCall(createIdentifier("__assign"), undefined, objects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a BinaryExpression that contains a destructuring assignment.
|
||||
*
|
||||
* @param node A BinaryExpression node.
|
||||
*/
|
||||
function visitBinaryExpression(node: BinaryExpression): Expression {
|
||||
if (isDestructuringAssignment(node) && node.left.transformFlags & TransformFlags.AssertESNext) {
|
||||
return flattenDestructuringAssignment(context, node, /*needsDestructuringValue*/ true, hoistVariableDeclaration, visitor, /*transformRest*/ true);
|
||||
}
|
||||
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a VariableDeclaration node with a binding pattern.
|
||||
*
|
||||
* @param node A VariableDeclaration node.
|
||||
*/
|
||||
function visitVariableDeclaration(node: VariableDeclaration): VisitResult<VariableDeclaration> {
|
||||
// If we are here it is because the name contains a binding pattern with a rest somewhere in it.
|
||||
if (isBindingPattern(node.name) && node.name.transformFlags & TransformFlags.AssertESNext) {
|
||||
const result = flattenVariableDestructuring(node, /*value*/ undefined, visitor, /*recordTempVariable*/ undefined, /*transformRest*/ true);
|
||||
return result;
|
||||
}
|
||||
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a ForOfStatement and converts it into a ES2015-compatible ForOfStatement.
|
||||
*
|
||||
* @param node A ForOfStatement.
|
||||
*/
|
||||
function visitForOfStatement(node: ForOfStatement): VisitResult<Statement> {
|
||||
// The following ESNext code:
|
||||
//
|
||||
// for (let { x, y, ...rest } of expr) { }
|
||||
//
|
||||
// should be emitted as
|
||||
//
|
||||
// for (var _a of expr) {
|
||||
// let { x, y } = _a, rest = __rest(_a, ["x", "y"]);
|
||||
// }
|
||||
//
|
||||
// where _a is a temp emitted to capture the RHS.
|
||||
// When the left hand side is an expression instead of a let declaration,
|
||||
// the `let` before the `{ x, y }` is not emitted.
|
||||
// When the left hand side is a let/const, the v is renamed if there is
|
||||
// another v in scope.
|
||||
// Note that all assignments to the LHS are emitted in the body, including
|
||||
// all destructuring.
|
||||
// Note also that because an extra statement is needed to assign to the LHS,
|
||||
// for-of bodies are always emitted as blocks.
|
||||
|
||||
// for (<init> of <expression>) <statement>
|
||||
// where <init> is [let] variabledeclarationlist | expression
|
||||
const initializer = node.initializer;
|
||||
if (!isRestBindingPattern(initializer) && !isRestAssignment(initializer)) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
return convertForOf(node, undefined, visitor, noop, context, /*transformRest*/ true);
|
||||
}
|
||||
|
||||
function isRestBindingPattern(initializer: ForInitializer) {
|
||||
if (isVariableDeclarationList(initializer)) {
|
||||
const declaration = firstOrUndefined(initializer.declarations);
|
||||
return declaration && declaration.name &&
|
||||
declaration.name.kind === SyntaxKind.ObjectBindingPattern &&
|
||||
!!(declaration.name.transformFlags & TransformFlags.ContainsSpreadExpression);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isRestAssignment(initializer: ForInitializer) {
|
||||
return initializer.kind === SyntaxKind.ObjectLiteralExpression &&
|
||||
initializer.transformFlags & TransformFlags.ContainsSpreadExpression;
|
||||
}
|
||||
|
||||
function visitParameter(node: ParameterDeclaration): ParameterDeclaration {
|
||||
if (isObjectRestParameter(node)) {
|
||||
// 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,
|
||||
node.initializer,
|
||||
/*location*/ node
|
||||
),
|
||||
/*original*/ node
|
||||
);
|
||||
}
|
||||
else {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
function isObjectRestParameter(node: ParameterDeclaration) {
|
||||
return node.name &&
|
||||
node.name.kind === SyntaxKind.ObjectBindingPattern &&
|
||||
!!(node.name.transformFlags & TransformFlags.ContainsSpreadExpression);
|
||||
}
|
||||
|
||||
function visitFunctionDeclaration(node: FunctionDeclaration): FunctionDeclaration {
|
||||
const hasRest = forEach(node.parameters, isObjectRestParameter);
|
||||
const body = hasRest ?
|
||||
transformFunctionBody(node, visitor, currentSourceFile, context, noop, /*convertObjectRest*/ true) as Block :
|
||||
visitEachChild(node.body, visitor, context);
|
||||
|
||||
return setOriginalNode(
|
||||
createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
/*type*/ undefined,
|
||||
body,
|
||||
/*location*/ node
|
||||
),
|
||||
/*original*/ node);
|
||||
}
|
||||
|
||||
function visitArrowFunction(node: ArrowFunction) {
|
||||
const hasRest = forEach(node.parameters, isObjectRestParameter);
|
||||
const body = hasRest ?
|
||||
transformFunctionBody(node, visitor, currentSourceFile, context, noop, /*convertObjectRest*/ true) as Block :
|
||||
visitEachChild(node.body, visitor, context);
|
||||
const func = setOriginalNode(
|
||||
createArrowFunction(
|
||||
/*modifiers*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
/*type*/ undefined,
|
||||
node.equalsGreaterThanToken,
|
||||
body,
|
||||
/*location*/ node
|
||||
),
|
||||
/*original*/ node
|
||||
);
|
||||
setEmitFlags(func, EmitFlags.CapturesThis);
|
||||
return func;
|
||||
}
|
||||
|
||||
function visitFunctionExpression(node: FunctionExpression): Expression {
|
||||
const hasRest = forEach(node.parameters, isObjectRestParameter);
|
||||
const body = hasRest ?
|
||||
transformFunctionBody(node, visitor, currentSourceFile, context, noop, /*convertObjectRest*/ true) as Block :
|
||||
visitEachChild(node.body, visitor, context);
|
||||
return setOriginalNode(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
node.asteriskToken,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, visitor, isParameter),
|
||||
/*type*/ undefined,
|
||||
body,
|
||||
/*location*/ node
|
||||
),
|
||||
/*original*/ node
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -113,7 +113,8 @@ namespace ts {
|
||||
|| createAssignHelper(currentSourceFile.externalHelpersModuleName, segments);
|
||||
}
|
||||
|
||||
const element = createReactCreateElement(
|
||||
const element = createExpressionForJsxElement(
|
||||
context.getEmitResolver().getJsxFactoryEntity(),
|
||||
compilerOptions.reactNamespace,
|
||||
tagName,
|
||||
objectProperties,
|
||||
|
||||
@ -1474,7 +1474,7 @@ namespace ts {
|
||||
if (isAssignmentExpression(node)) {
|
||||
return hasExportedReferenceInDestructuringTarget(node.left);
|
||||
}
|
||||
else if (isSpreadElementExpression(node)) {
|
||||
else if (isSpreadExpression(node)) {
|
||||
return hasExportedReferenceInDestructuringTarget(node.expression);
|
||||
}
|
||||
else if (isObjectLiteralExpression(node)) {
|
||||
|
||||
@ -471,7 +471,11 @@ namespace ts {
|
||||
currentSourceFile = node;
|
||||
|
||||
// ensure "use strict" is emitted in all scenarios in alwaysStrict mode
|
||||
if (compilerOptions.alwaysStrict) {
|
||||
// There is no need to emit "use strict" in the following cases:
|
||||
// 1. The file is an external module and target is es2015 or higher
|
||||
// or 2. The file is an external module and module-kind is es6 or es2015 as such value is not allowed when targeting es5 or lower
|
||||
if (compilerOptions.alwaysStrict &&
|
||||
!(isExternalModule(node) && (compilerOptions.target >= ScriptTarget.ES2015 || compilerOptions.module === ModuleKind.ES2015))) {
|
||||
node = ensureUseStrict(node);
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
"visitor.ts",
|
||||
"transformers/ts.ts",
|
||||
"transformers/jsx.ts",
|
||||
"transformers/esnext.ts",
|
||||
"transformers/es2017.ts",
|
||||
"transformers/es2016.ts",
|
||||
"transformers/es2015.ts",
|
||||
|
||||
@ -246,7 +246,7 @@ namespace ts {
|
||||
ConditionalExpression,
|
||||
TemplateExpression,
|
||||
YieldExpression,
|
||||
SpreadElementExpression,
|
||||
SpreadElement,
|
||||
ClassExpression,
|
||||
OmittedExpression,
|
||||
ExpressionWithTypeArguments,
|
||||
@ -320,6 +320,7 @@ namespace ts {
|
||||
// Property assignments
|
||||
PropertyAssignment,
|
||||
ShorthandPropertyAssignment,
|
||||
SpreadAssignment,
|
||||
|
||||
// Enum
|
||||
EnumMember,
|
||||
@ -418,20 +419,21 @@ namespace ts {
|
||||
HasDecorators = 1 << 11, // If the file has decorators (initialized by binding)
|
||||
HasParamDecorators = 1 << 12, // If the file has parameter decorators (initialized by binding)
|
||||
HasAsyncFunctions = 1 << 13, // If the file has async functions (initialized by binding)
|
||||
HasJsxSpreadAttributes = 1 << 14, // If the file as JSX spread attributes (initialized by binding)
|
||||
DisallowInContext = 1 << 15, // If node was parsed in a context where 'in-expressions' are not allowed
|
||||
YieldContext = 1 << 16, // If node was parsed in the 'yield' context created when parsing a generator
|
||||
DecoratorContext = 1 << 17, // If node was parsed as part of a decorator
|
||||
AwaitContext = 1 << 18, // If node was parsed in the 'await' context created when parsing an async function
|
||||
ThisNodeHasError = 1 << 19, // If the parser encountered an error when parsing the code that created this node
|
||||
JavaScriptFile = 1 << 20, // If node was parsed in a JavaScript
|
||||
ThisNodeOrAnySubNodesHasError = 1 << 21, // If this node or any of its children had an error
|
||||
HasAggregatedChildData = 1 << 22, // If we've computed data from children and cached it in this node
|
||||
HasSpreadAttribute = 1 << 14, // If the file as JSX spread attributes (initialized by binding)
|
||||
HasRestAttribute = 1 << 15, // If the file has object destructure elements
|
||||
DisallowInContext = 1 << 16, // If node was parsed in a context where 'in-expressions' are not allowed
|
||||
YieldContext = 1 << 17, // If node was parsed in the 'yield' context created when parsing a generator
|
||||
DecoratorContext = 1 << 18, // If node was parsed as part of a decorator
|
||||
AwaitContext = 1 << 19, // If node was parsed in the 'await' context created when parsing an async function
|
||||
ThisNodeHasError = 1 << 20, // If the parser encountered an error when parsing the code that created this node
|
||||
JavaScriptFile = 1 << 21, // If node was parsed in a JavaScript
|
||||
ThisNodeOrAnySubNodesHasError = 1 << 22, // If this node or any of its children had an error
|
||||
HasAggregatedChildData = 1 << 23, // If we've computed data from children and cached it in this node
|
||||
|
||||
BlockScoped = Let | Const,
|
||||
|
||||
ReachabilityCheckFlags = HasImplicitReturn | HasExplicitReturn,
|
||||
EmitHelperFlags = HasClassExtends | HasDecorators | HasParamDecorators | HasAsyncFunctions | HasJsxSpreadAttributes,
|
||||
EmitHelperFlags = HasClassExtends | HasDecorators | HasParamDecorators | HasAsyncFunctions | HasSpreadAttribute | HasRestAttribute,
|
||||
ReachabilityAndEmitFlags = ReachabilityCheckFlags | EmitHelperFlags,
|
||||
|
||||
// Parsing context flags
|
||||
@ -454,7 +456,6 @@ namespace ts {
|
||||
Async = 1 << 8, // Property/Method/Function
|
||||
Default = 1 << 9, // Function/Class (export default declaration)
|
||||
Const = 1 << 11, // Variable declaration
|
||||
|
||||
HasComputedFlags = 1 << 29, // Modifier flags have been computed
|
||||
|
||||
AccessibilityModifier = Public | Private | Protected,
|
||||
@ -649,7 +650,7 @@ namespace ts {
|
||||
export interface BindingElement extends Declaration {
|
||||
kind: SyntaxKind.BindingElement;
|
||||
propertyName?: PropertyName; // Binding property name (in object binding pattern)
|
||||
dotDotDotToken?: DotDotDotToken; // Present on rest binding element
|
||||
dotDotDotToken?: DotDotDotToken; // Present on rest element (in object binding pattern)
|
||||
name: BindingName; // Declared binding element name
|
||||
initializer?: Expression; // Optional initializer
|
||||
}
|
||||
@ -675,7 +676,7 @@ namespace ts {
|
||||
name?: PropertyName;
|
||||
}
|
||||
|
||||
export type ObjectLiteralElementLike = PropertyAssignment | ShorthandPropertyAssignment | MethodDeclaration | AccessorDeclaration;
|
||||
export type ObjectLiteralElementLike = PropertyAssignment | ShorthandPropertyAssignment | MethodDeclaration | AccessorDeclaration | SpreadAssignment;
|
||||
|
||||
export interface PropertyAssignment extends ObjectLiteralElement {
|
||||
kind: SyntaxKind.PropertyAssignment;
|
||||
@ -694,6 +695,11 @@ namespace ts {
|
||||
objectAssignmentInitializer?: Expression;
|
||||
}
|
||||
|
||||
export interface SpreadAssignment extends ObjectLiteralElement {
|
||||
kind: SyntaxKind.SpreadAssignment;
|
||||
expression: Expression;
|
||||
}
|
||||
|
||||
// SyntaxKind.VariableDeclaration
|
||||
// SyntaxKind.Parameter
|
||||
// SyntaxKind.BindingElement
|
||||
@ -1279,8 +1285,8 @@ namespace ts {
|
||||
multiLine?: boolean;
|
||||
}
|
||||
|
||||
export interface SpreadElementExpression extends Expression {
|
||||
kind: SyntaxKind.SpreadElementExpression;
|
||||
export interface SpreadElement extends Expression {
|
||||
kind: SyntaxKind.SpreadElement;
|
||||
expression: Expression;
|
||||
}
|
||||
|
||||
@ -2192,6 +2198,7 @@ namespace ts {
|
||||
|
||||
/* @internal */ getFileProcessingDiagnostics(): DiagnosticCollection;
|
||||
/* @internal */ getResolvedTypeReferenceDirectives(): Map<ResolvedTypeReferenceDirective>;
|
||||
/* @internal */ isSourceFileFromExternalLibrary(file: SourceFile): boolean;
|
||||
// For testing purposes only.
|
||||
/* @internal */ structureIsReused?: boolean;
|
||||
}
|
||||
@ -2380,6 +2387,12 @@ namespace ts {
|
||||
CannotBeNamed
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const enum SyntheticSymbolKind {
|
||||
UnionOrIntersection,
|
||||
Spread
|
||||
}
|
||||
|
||||
export const enum TypePredicateKind {
|
||||
This,
|
||||
Identifier
|
||||
@ -2472,6 +2485,7 @@ namespace ts {
|
||||
getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): string[];
|
||||
isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean;
|
||||
writeLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, writer: SymbolWriter): void;
|
||||
getJsxFactoryEntity(): EntityName;
|
||||
}
|
||||
|
||||
export const enum SymbolFlags {
|
||||
@ -2591,7 +2605,9 @@ namespace ts {
|
||||
instantiations?: Map<Type>; // Instantiations of generic type alias (undefined if non-generic)
|
||||
mapper?: TypeMapper; // Type mapper for instantiation alias
|
||||
referenced?: boolean; // True if alias symbol has been referenced as a value
|
||||
containingType?: UnionOrIntersectionType; // Containing union or intersection type for synthetic property
|
||||
containingType?: UnionOrIntersectionType; // Containing union or intersection type for synthetic property
|
||||
leftSpread?: Symbol; // Left source for synthetic spread property
|
||||
rightSpread?: Symbol; // Right source for synthetic spread property
|
||||
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
|
||||
@ -2709,7 +2725,7 @@ namespace ts {
|
||||
EnumLike = Enum | EnumLiteral,
|
||||
UnionOrIntersection = Union | Intersection,
|
||||
StructuredType = Object | Union | Intersection,
|
||||
StructuredOrTypeParameter = StructuredType | TypeParameter,
|
||||
StructuredOrTypeParameter = StructuredType | TypeParameter | Index,
|
||||
|
||||
// 'Narrowable' types are types where narrowing actually narrows.
|
||||
// This *should* be every type other than null, undefined, void, and never
|
||||
@ -2923,6 +2939,8 @@ namespace ts {
|
||||
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
|
||||
/* @internal */
|
||||
typePredicate?: TypePredicate;
|
||||
/* @internal */
|
||||
instantiations?: Map<Signature>; // Generic signature instantiation cache
|
||||
}
|
||||
|
||||
export const enum IndexKind {
|
||||
@ -2940,7 +2958,6 @@ namespace ts {
|
||||
export interface TypeMapper {
|
||||
(t: TypeParameter): Type;
|
||||
mappedTypes?: Type[]; // Types mapped by this mapper
|
||||
targetTypes?: Type[]; // Types substituted for mapped types
|
||||
instantiations?: Type[]; // Cache of instantiations created using this type mapper.
|
||||
context?: InferenceContext; // The inference context this mapper was created from.
|
||||
// Only inference mappers have this set (in createInferenceMapper).
|
||||
@ -3058,6 +3075,7 @@ namespace ts {
|
||||
moduleResolution?: ModuleResolutionKind;
|
||||
newLine?: NewLineKind;
|
||||
noEmit?: boolean;
|
||||
/*@internal*/noEmitForJsFiles?: boolean;
|
||||
noEmitHelpers?: boolean;
|
||||
noEmitOnError?: boolean;
|
||||
noErrorTruncation?: boolean;
|
||||
@ -3078,6 +3096,7 @@ namespace ts {
|
||||
project?: string;
|
||||
/* @internal */ pretty?: DiagnosticStyle;
|
||||
reactNamespace?: string;
|
||||
jsxFactory?: string;
|
||||
removeComments?: boolean;
|
||||
rootDir?: string;
|
||||
rootDirs?: string[];
|
||||
@ -3160,7 +3179,8 @@ namespace ts {
|
||||
ES2015 = 2,
|
||||
ES2016 = 3,
|
||||
ES2017 = 4,
|
||||
Latest = ES2017,
|
||||
ESNext = 5,
|
||||
Latest = ESNext,
|
||||
}
|
||||
|
||||
export const enum LanguageVariant {
|
||||
@ -3475,32 +3495,34 @@ namespace ts {
|
||||
ContainsTypeScript = 1 << 1,
|
||||
Jsx = 1 << 2,
|
||||
ContainsJsx = 1 << 3,
|
||||
ES2017 = 1 << 4,
|
||||
ContainsES2017 = 1 << 5,
|
||||
ES2016 = 1 << 6,
|
||||
ContainsES2016 = 1 << 7,
|
||||
ES2015 = 1 << 8,
|
||||
ContainsES2015 = 1 << 9,
|
||||
Generator = 1 << 10,
|
||||
ContainsGenerator = 1 << 11,
|
||||
DestructuringAssignment = 1 << 12,
|
||||
ContainsDestructuringAssignment = 1 << 13,
|
||||
ESNext = 1 << 4,
|
||||
ContainsESNext = 1 << 5,
|
||||
ES2017 = 1 << 6,
|
||||
ContainsES2017 = 1 << 7,
|
||||
ES2016 = 1 << 8,
|
||||
ContainsES2016 = 1 << 9,
|
||||
ES2015 = 1 << 10,
|
||||
ContainsES2015 = 1 << 11,
|
||||
Generator = 1 << 12,
|
||||
ContainsGenerator = 1 << 13,
|
||||
DestructuringAssignment = 1 << 14,
|
||||
ContainsDestructuringAssignment = 1 << 15,
|
||||
|
||||
// Markers
|
||||
// - Flags used to indicate that a subtree contains a specific transformation.
|
||||
ContainsDecorators = 1 << 14,
|
||||
ContainsPropertyInitializer = 1 << 15,
|
||||
ContainsLexicalThis = 1 << 16,
|
||||
ContainsCapturedLexicalThis = 1 << 17,
|
||||
ContainsLexicalThisInComputedPropertyName = 1 << 18,
|
||||
ContainsDefaultValueAssignments = 1 << 19,
|
||||
ContainsParameterPropertyAssignments = 1 << 20,
|
||||
ContainsSpreadElementExpression = 1 << 21,
|
||||
ContainsComputedPropertyName = 1 << 22,
|
||||
ContainsBlockScopedBinding = 1 << 23,
|
||||
ContainsBindingPattern = 1 << 24,
|
||||
ContainsYield = 1 << 25,
|
||||
ContainsHoistedDeclarationOrCompletion = 1 << 26,
|
||||
ContainsDecorators = 1 << 16,
|
||||
ContainsPropertyInitializer = 1 << 17,
|
||||
ContainsLexicalThis = 1 << 18,
|
||||
ContainsCapturedLexicalThis = 1 << 19,
|
||||
ContainsLexicalThisInComputedPropertyName = 1 << 20,
|
||||
ContainsDefaultValueAssignments = 1 << 21,
|
||||
ContainsParameterPropertyAssignments = 1 << 22,
|
||||
ContainsSpreadExpression = 1 << 23,
|
||||
ContainsComputedPropertyName = 1 << 24,
|
||||
ContainsBlockScopedBinding = 1 << 25,
|
||||
ContainsBindingPattern = 1 << 26,
|
||||
ContainsYield = 1 << 27,
|
||||
ContainsHoistedDeclarationOrCompletion = 1 << 28,
|
||||
|
||||
HasComputedFlags = 1 << 29, // Transform flags have been computed.
|
||||
|
||||
@ -3508,6 +3530,7 @@ namespace ts {
|
||||
// - Bitmasks that are used to assert facts about the syntax of a node and its subtree.
|
||||
AssertTypeScript = TypeScript | ContainsTypeScript,
|
||||
AssertJsx = Jsx | ContainsJsx,
|
||||
AssertESNext = ESNext | ContainsESNext,
|
||||
AssertES2017 = ES2017 | ContainsES2017,
|
||||
AssertES2016 = ES2016 | ContainsES2016,
|
||||
AssertES2015 = ES2015 | ContainsES2015,
|
||||
@ -3517,7 +3540,7 @@ namespace ts {
|
||||
// Scope Exclusions
|
||||
// - Bitmasks that exclude flags from propagating out of a specific context
|
||||
// into the subtree flags of their container.
|
||||
NodeExcludes = TypeScript | Jsx | ES2017 | ES2016 | ES2015 | DestructuringAssignment | Generator | HasComputedFlags,
|
||||
NodeExcludes = TypeScript | Jsx | ESNext | ES2017 | ES2016 | ES2015 | DestructuringAssignment | Generator | HasComputedFlags,
|
||||
ArrowFunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion,
|
||||
FunctionExcludes = NodeExcludes | ContainsDecorators | ContainsDefaultValueAssignments | ContainsCapturedLexicalThis | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion,
|
||||
ConstructorExcludes = NodeExcludes | ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsYield | ContainsHoistedDeclarationOrCompletion,
|
||||
@ -3526,7 +3549,7 @@ namespace ts {
|
||||
ModuleExcludes = NodeExcludes | ContainsDecorators | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding | ContainsHoistedDeclarationOrCompletion,
|
||||
TypeExcludes = ~ContainsTypeScript,
|
||||
ObjectLiteralExcludes = NodeExcludes | ContainsDecorators | ContainsComputedPropertyName | ContainsLexicalThisInComputedPropertyName,
|
||||
ArrayLiteralOrCallOrNewExcludes = NodeExcludes | ContainsSpreadElementExpression,
|
||||
ArrayLiteralOrCallOrNewExcludes = NodeExcludes | ContainsSpreadExpression,
|
||||
VariableDeclarationListExcludes = NodeExcludes | ContainsBindingPattern,
|
||||
ParameterExcludes = NodeExcludes | ContainsBindingPattern,
|
||||
|
||||
|
||||
@ -192,7 +192,7 @@ namespace ts {
|
||||
export function nodePosToString(node: Node): string {
|
||||
const file = getSourceFileOfNode(node);
|
||||
const loc = getLineAndCharacterOfPosition(file, node.pos);
|
||||
return `${ file.fileName }(${ loc.line + 1 },${ loc.character + 1 })`;
|
||||
return `${file.fileName}(${loc.line + 1},${loc.character + 1})`;
|
||||
}
|
||||
|
||||
export function getStartPosOfNode(node: Node): number {
|
||||
@ -439,7 +439,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function isBlockScope(node: Node, parentNode: Node) {
|
||||
switch (node.kind) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.SourceFile:
|
||||
case SyntaxKind.CaseBlock:
|
||||
case SyntaxKind.CatchClause:
|
||||
@ -485,6 +485,22 @@ namespace ts {
|
||||
return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name);
|
||||
}
|
||||
|
||||
export function getTextOfPropertyName(name: PropertyName): string {
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return (<Identifier>name).text;
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return (<LiteralExpression>name).text;
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
if (isStringOrNumericLiteral((<ComputedPropertyName>name).expression.kind)) {
|
||||
return (<LiteralExpression>(<ComputedPropertyName>name).expression).text;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function entityNameToString(name: EntityNameOrEntityNameExpression): string {
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
@ -498,6 +514,10 @@ namespace ts {
|
||||
|
||||
export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic {
|
||||
const sourceFile = getSourceFileOfNode(node);
|
||||
return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
export function createDiagnosticForNodeInSourceFile(sourceFile: SourceFile, node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic {
|
||||
const span = getErrorSpanForNode(sourceFile, node);
|
||||
return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2);
|
||||
}
|
||||
@ -624,9 +644,9 @@ namespace ts {
|
||||
|
||||
export function getJsDocCommentsFromText(node: Node, text: string) {
|
||||
const commentRanges = (node.kind === SyntaxKind.Parameter ||
|
||||
node.kind === SyntaxKind.TypeParameter ||
|
||||
node.kind === SyntaxKind.FunctionExpression ||
|
||||
node.kind === SyntaxKind.ArrowFunction) ?
|
||||
node.kind === SyntaxKind.TypeParameter ||
|
||||
node.kind === SyntaxKind.FunctionExpression ||
|
||||
node.kind === SyntaxKind.ArrowFunction) ?
|
||||
concatenate(getTrailingCommentRanges(text, node.pos), getLeadingCommentRanges(text, node.pos)) :
|
||||
getLeadingCommentRangesOfNodeFromText(node, text);
|
||||
return filter(commentRanges, isJsDocComment);
|
||||
@ -891,7 +911,7 @@ namespace ts {
|
||||
export function isObjectLiteralOrClassExpressionMethod(node: Node): node is MethodDeclaration {
|
||||
return node.kind === SyntaxKind.MethodDeclaration &&
|
||||
(node.parent.kind === SyntaxKind.ObjectLiteralExpression ||
|
||||
node.parent.kind === SyntaxKind.ClassExpression);
|
||||
node.parent.kind === SyntaxKind.ClassExpression);
|
||||
}
|
||||
|
||||
export function isIdentifierTypePredicate(predicate: TypePredicate): predicate is IdentifierTypePredicate {
|
||||
@ -1113,8 +1133,8 @@ namespace ts {
|
||||
// if the parameter's parent has a body and its grandparent is a class declaration, this is a valid target;
|
||||
return (<FunctionLikeDeclaration>node.parent).body !== undefined
|
||||
&& (node.parent.kind === SyntaxKind.Constructor
|
||||
|| node.parent.kind === SyntaxKind.MethodDeclaration
|
||||
|| node.parent.kind === SyntaxKind.SetAccessor)
|
||||
|| node.parent.kind === SyntaxKind.MethodDeclaration
|
||||
|| node.parent.kind === SyntaxKind.SetAccessor)
|
||||
&& node.parent.parent.kind === SyntaxKind.ClassDeclaration;
|
||||
}
|
||||
|
||||
@ -1179,7 +1199,7 @@ namespace ts {
|
||||
case SyntaxKind.PostfixUnaryExpression:
|
||||
case SyntaxKind.BinaryExpression:
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
case SyntaxKind.SpreadElement:
|
||||
case SyntaxKind.TemplateExpression:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.OmittedExpression:
|
||||
@ -1461,7 +1481,7 @@ namespace ts {
|
||||
}, tags => tags);
|
||||
}
|
||||
|
||||
function getJSDocs<T>(node: Node, checkParentVariableStatement: boolean, getDocs: (docs: JSDoc[]) => T[], getTags: (tags: JSDocTag[]) => T[]): T[] {
|
||||
function getJSDocs<T>(node: Node, checkParentVariableStatement: boolean, getDocs: (docs: JSDoc[]) => T[], getTags: (tags: JSDocTag[]) => T[]): T[] {
|
||||
// TODO: Get rid of getJsDocComments and friends (note the lowercase 's' in Js)
|
||||
// TODO: A lot of this work should be cached, maybe. I guess it's only used in services right now...
|
||||
let result: T[] = undefined;
|
||||
@ -1482,8 +1502,8 @@ namespace ts {
|
||||
|
||||
const variableStatementNode =
|
||||
isInitializerOfVariableDeclarationInStatement ? node.parent.parent.parent :
|
||||
isVariableOfVariableDeclarationStatement ? node.parent.parent :
|
||||
undefined;
|
||||
isVariableOfVariableDeclarationStatement ? node.parent.parent :
|
||||
undefined;
|
||||
if (variableStatementNode) {
|
||||
result = append(result, getJSDocs(variableStatementNode, checkParentVariableStatement, getDocs, getTags));
|
||||
}
|
||||
@ -1641,14 +1661,14 @@ namespace ts {
|
||||
return (<ForInStatement | ForOfStatement>parent).initializer === node ? AssignmentKind.Definite : AssignmentKind.None;
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
case SyntaxKind.SpreadElement:
|
||||
node = parent;
|
||||
break;
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
if ((<ShorthandPropertyAssignment>parent).name !== node) {
|
||||
return AssignmentKind.None;
|
||||
}
|
||||
// Fall through
|
||||
// Fall through
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
node = parent.parent;
|
||||
break;
|
||||
@ -2226,7 +2246,7 @@ namespace ts {
|
||||
case SyntaxKind.YieldExpression:
|
||||
return 2;
|
||||
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
case SyntaxKind.SpreadElement:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
@ -2550,14 +2570,18 @@ namespace ts {
|
||||
if (options.outFile || options.out) {
|
||||
const moduleKind = getEmitModuleKind(options);
|
||||
const moduleEmitEnabled = moduleKind === ModuleKind.AMD || moduleKind === ModuleKind.System;
|
||||
const sourceFiles = host.getSourceFiles();
|
||||
const sourceFiles = getAllEmittableSourceFiles();
|
||||
// Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified
|
||||
return filter(sourceFiles, moduleEmitEnabled ? isNonDeclarationFile : isBundleEmitNonExternalModule);
|
||||
}
|
||||
else {
|
||||
const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile];
|
||||
const sourceFiles = targetSourceFile === undefined ? getAllEmittableSourceFiles() : [targetSourceFile];
|
||||
return filterSourceFilesInDirectory(sourceFiles, file => host.isSourceFileFromExternalLibrary(file));
|
||||
}
|
||||
|
||||
function getAllEmittableSourceFiles() {
|
||||
return options.noEmitForJsFiles ? filter(host.getSourceFiles(), sourceFile => !isSourceFileJavaScript(sourceFile)) : host.getSourceFiles();
|
||||
}
|
||||
}
|
||||
|
||||
/** Don't call this for `--outFile`, just for `--outDir` or plain emit. */
|
||||
@ -2602,7 +2626,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
for (const sourceFile of sourceFiles) {
|
||||
// Don't emit if source file is a declaration file, or was located under node_modules
|
||||
// Don't emit if source file is a declaration file, or was located under node_modules
|
||||
if (!isDeclarationFile(sourceFile) && !host.isSourceFileFromExternalLibrary(sourceFile)) {
|
||||
onSingleFileEmit(host, sourceFile);
|
||||
}
|
||||
@ -2664,7 +2688,7 @@ namespace ts {
|
||||
onBundledEmit(host);
|
||||
}
|
||||
else {
|
||||
const sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile];
|
||||
const sourceFiles = targetSourceFile === undefined ? getSourceFilesToEmit(host) : [targetSourceFile];
|
||||
for (const sourceFile of sourceFiles) {
|
||||
if (shouldEmitInDirectory(sourceFile, file => host.isSourceFileFromExternalLibrary(file))) {
|
||||
onSingleFileEmit(host, sourceFile);
|
||||
@ -2701,11 +2725,11 @@ namespace ts {
|
||||
function onBundledEmit(host: EmitHost) {
|
||||
// Can emit only sources that are not declaration file and are either non module code or module with
|
||||
// --module or --target es6 specified. Files included by searching under node_modules are also not emitted.
|
||||
const bundledSources = filter(host.getSourceFiles(),
|
||||
const bundledSources = filter(getSourceFilesToEmit(host),
|
||||
sourceFile => !isDeclarationFile(sourceFile) &&
|
||||
!host.isSourceFileFromExternalLibrary(sourceFile) &&
|
||||
(!isExternalModule(sourceFile) ||
|
||||
!!getEmitModuleKind(options)));
|
||||
!host.isSourceFileFromExternalLibrary(sourceFile) &&
|
||||
(!isExternalModule(sourceFile) ||
|
||||
!!getEmitModuleKind(options)));
|
||||
if (bundledSources.length) {
|
||||
const jsFilePath = options.outFile || options.out;
|
||||
const emitFileNames: EmitFileNames = {
|
||||
@ -2891,7 +2915,7 @@ namespace ts {
|
||||
writeComment: (text: string, lineMap: number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) => void,
|
||||
node: TextRange, newLine: string, removeComments: boolean) {
|
||||
let leadingComments: CommentRange[];
|
||||
let currentDetachedCommentInfo: {nodePos: number, detachedCommentEndPos: number};
|
||||
let currentDetachedCommentInfo: { nodePos: number, detachedCommentEndPos: number };
|
||||
if (removeComments) {
|
||||
// removeComments is true, only reserve pinned comment at the top of file
|
||||
// For example:
|
||||
@ -3238,10 +3262,10 @@ namespace ts {
|
||||
|
||||
function stringifyValue(value: any): string {
|
||||
return typeof value === "string" ? `"${escapeString(value)}"`
|
||||
: typeof value === "number" ? isFinite(value) ? String(value) : "null"
|
||||
: typeof value === "boolean" ? value ? "true" : "false"
|
||||
: typeof value === "object" && value ? isArray(value) ? cycleCheck(stringifyArray, value) : cycleCheck(stringifyObject, value)
|
||||
: /*fallback*/ "null";
|
||||
: typeof value === "number" ? isFinite(value) ? String(value) : "null"
|
||||
: typeof value === "boolean" ? value ? "true" : "false"
|
||||
: typeof value === "object" && value ? isArray(value) ? cycleCheck(stringifyArray, value) : cycleCheck(stringifyObject, value)
|
||||
: /*fallback*/ "null";
|
||||
}
|
||||
|
||||
function cycleCheck(cb: (value: any) => string, value: any) {
|
||||
@ -3266,7 +3290,7 @@ namespace ts {
|
||||
|
||||
function stringifyProperty(memo: string, value: any, key: string) {
|
||||
return value === undefined || typeof value === "function" || key === "__cycle" ? memo
|
||||
: (memo ? memo + "," : memo) + `"${escapeString(key)}":${stringifyValue(value)}`;
|
||||
: (memo ? memo + "," : memo) + `"${escapeString(key)}":${stringifyValue(value)}`;
|
||||
}
|
||||
|
||||
const base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
@ -3511,7 +3535,7 @@ namespace ts {
|
||||
* @param token The token.
|
||||
*/
|
||||
export function createTokenRange(pos: number, token: SyntaxKind): TextRange {
|
||||
return createRange(pos, pos + tokenToString(token).length);
|
||||
return createRange(pos, pos + tokenToString(token).length);
|
||||
}
|
||||
|
||||
export function rangeIsOnSingleLine(range: TextRange, sourceFile: SourceFile) {
|
||||
@ -3874,6 +3898,7 @@ namespace ts {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.PropertyAssignment
|
||||
|| kind === SyntaxKind.ShorthandPropertyAssignment
|
||||
|| kind === SyntaxKind.SpreadAssignment
|
||||
|| kind === SyntaxKind.MethodDeclaration
|
||||
|| kind === SyntaxKind.GetAccessor
|
||||
|| kind === SyntaxKind.SetAccessor
|
||||
@ -3961,8 +3986,8 @@ namespace ts {
|
||||
|| kind === SyntaxKind.NoSubstitutionTemplateLiteral;
|
||||
}
|
||||
|
||||
export function isSpreadElementExpression(node: Node): node is SpreadElementExpression {
|
||||
return node.kind === SyntaxKind.SpreadElementExpression;
|
||||
export function isSpreadExpression(node: Node): node is SpreadElement {
|
||||
return node.kind === SyntaxKind.SpreadElement;
|
||||
}
|
||||
|
||||
export function isExpressionWithTypeArguments(node: Node): node is ExpressionWithTypeArguments {
|
||||
@ -4020,7 +4045,7 @@ namespace ts {
|
||||
|| kind === SyntaxKind.YieldExpression
|
||||
|| kind === SyntaxKind.ArrowFunction
|
||||
|| kind === SyntaxKind.BinaryExpression
|
||||
|| kind === SyntaxKind.SpreadElementExpression
|
||||
|| kind === SyntaxKind.SpreadElement
|
||||
|| kind === SyntaxKind.AsExpression
|
||||
|| kind === SyntaxKind.OmittedExpression
|
||||
|| isUnaryExpressionKind(kind);
|
||||
@ -4322,6 +4347,7 @@ namespace ts {
|
||||
namespace ts {
|
||||
export function getDefaultLibFileName(options: CompilerOptions): string {
|
||||
switch (options.target) {
|
||||
case ScriptTarget.ESNext:
|
||||
case ScriptTarget.ES2017:
|
||||
return "lib.es2017.d.ts";
|
||||
case ScriptTarget.ES2016:
|
||||
|
||||
@ -267,9 +267,9 @@ namespace ts {
|
||||
case SyntaxKind.VoidExpression:
|
||||
case SyntaxKind.AwaitExpression:
|
||||
case SyntaxKind.YieldExpression:
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
case SyntaxKind.SpreadElement:
|
||||
case SyntaxKind.NonNullExpression:
|
||||
result = reduceNode((<ParenthesizedExpression | DeleteExpression | TypeOfExpression | VoidExpression | AwaitExpression | YieldExpression | SpreadElementExpression | NonNullExpression>node).expression, f, result);
|
||||
result = reduceNode((<ParenthesizedExpression | DeleteExpression | TypeOfExpression | VoidExpression | AwaitExpression | YieldExpression | SpreadElement | NonNullExpression>node).expression, f, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
@ -510,6 +510,10 @@ namespace ts {
|
||||
result = reduceNode((<ShorthandPropertyAssignment>node).objectAssignmentInitializer, f, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
result = reduceNode((node as SpreadAssignment).expression, f, result);
|
||||
break;
|
||||
|
||||
// Top-level nodes
|
||||
case SyntaxKind.SourceFile:
|
||||
result = reduceLeft((<SourceFile>node).statements, f, result);
|
||||
@ -553,6 +557,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
aggregateTransformFlags(node);
|
||||
const visited = visitor(node);
|
||||
if (visited === node) {
|
||||
return node;
|
||||
@ -621,6 +626,7 @@ namespace ts {
|
||||
// Visit each original node.
|
||||
for (let i = 0; i < count; i++) {
|
||||
const node = nodes[i + start];
|
||||
aggregateTransformFlags(node);
|
||||
const visited = node !== undefined ? visitor(node) : undefined;
|
||||
if (updated !== undefined || visited === undefined || visited !== node) {
|
||||
if (updated === undefined) {
|
||||
@ -870,9 +876,9 @@ namespace ts {
|
||||
return updateYield(<YieldExpression>node,
|
||||
visitNode((<YieldExpression>node).expression, visitor, isExpression));
|
||||
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
return updateSpread(<SpreadElementExpression>node,
|
||||
visitNode((<SpreadElementExpression>node).expression, visitor, isExpression));
|
||||
case SyntaxKind.SpreadElement:
|
||||
return updateSpread(<SpreadElement>node,
|
||||
visitNode((<SpreadElement>node).expression, visitor, isExpression));
|
||||
|
||||
case SyntaxKind.ClassExpression:
|
||||
return updateClassExpression(<ClassExpression>node,
|
||||
@ -1125,7 +1131,11 @@ namespace ts {
|
||||
visitNode((<ShorthandPropertyAssignment>node).name, visitor, isIdentifier),
|
||||
visitNode((<ShorthandPropertyAssignment>node).objectAssignmentInitializer, visitor, isExpression));
|
||||
|
||||
// Top-level nodes
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
return updateSpreadAssignment(node as SpreadAssignment,
|
||||
visitNode((node as SpreadAssignment).expression, visitor, isExpression));
|
||||
|
||||
// Top-level nodes
|
||||
case SyntaxKind.SourceFile:
|
||||
context.startLexicalEnvironment();
|
||||
return updateSourceFileNode(<SourceFile>node,
|
||||
@ -1268,66 +1278,6 @@ namespace ts {
|
||||
return transformFlags | aggregateTransformFlagsForNode(child);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the transform flags to exclude when unioning the transform flags of a subtree.
|
||||
*
|
||||
* NOTE: This needs to be kept up-to-date with the exclusions used in `computeTransformFlagsForNode`.
|
||||
* For performance reasons, `computeTransformFlagsForNode` uses local constant values rather
|
||||
* than calling this function.
|
||||
*/
|
||||
function getTransformFlagsSubtreeExclusions(kind: SyntaxKind) {
|
||||
if (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode) {
|
||||
return TransformFlags.TypeExcludes;
|
||||
}
|
||||
|
||||
switch (kind) {
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
return TransformFlags.ArrayLiteralOrCallOrNewExcludes;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return TransformFlags.ModuleExcludes;
|
||||
case SyntaxKind.Parameter:
|
||||
return TransformFlags.ParameterExcludes;
|
||||
case SyntaxKind.ArrowFunction:
|
||||
return TransformFlags.ArrowFunctionExcludes;
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
return TransformFlags.FunctionExcludes;
|
||||
case SyntaxKind.VariableDeclarationList:
|
||||
return TransformFlags.VariableDeclarationListExcludes;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.ClassExpression:
|
||||
return TransformFlags.ClassExcludes;
|
||||
case SyntaxKind.Constructor:
|
||||
return TransformFlags.ConstructorExcludes;
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
return TransformFlags.MethodOrAccessorExcludes;
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.VoidKeyword:
|
||||
case SyntaxKind.TypeParameter:
|
||||
case SyntaxKind.PropertySignature:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.IndexSignature:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
return TransformFlags.TypeExcludes;
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return TransformFlags.ObjectLiteralExcludes;
|
||||
default:
|
||||
return TransformFlags.NodeExcludes;
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Debug {
|
||||
export const failNotOptional = shouldAssert(AssertionLevel.Normal)
|
||||
? (message?: string) => assert(false, message || "Node not optional.")
|
||||
|
||||
@ -1026,7 +1026,7 @@ namespace FourSlash {
|
||||
ts.displayPartsToString(help.suffixDisplayParts), expected);
|
||||
}
|
||||
|
||||
public verifyCurrentParameterIsletiable(isVariable: boolean) {
|
||||
public verifyCurrentParameterIsVariable(isVariable: boolean) {
|
||||
const signature = this.getActiveSignatureHelpItem();
|
||||
assert.isOk(signature);
|
||||
assert.equal(isVariable, signature.isVariadic);
|
||||
@ -1053,6 +1053,10 @@ namespace FourSlash {
|
||||
assert.equal(this.getActiveSignatureHelpItem().parameters.length, expectedCount);
|
||||
}
|
||||
|
||||
public verifyCurrentSignatureHelpIsVariadic(expected: boolean) {
|
||||
assert.equal(this.getActiveSignatureHelpItem().isVariadic, expected);
|
||||
}
|
||||
|
||||
public verifyCurrentSignatureHelpDocComment(docComment: string) {
|
||||
const actualDocComment = this.getActiveSignatureHelpItem().documentation;
|
||||
assert.equal(ts.displayPartsToString(actualDocComment), docComment, this.assertionMessageAtLastKnownMarker("current signature help doc comment"));
|
||||
@ -1253,7 +1257,18 @@ namespace FourSlash {
|
||||
resultString += "Diagnostics:" + Harness.IO.newLine();
|
||||
const diagnostics = ts.getPreEmitDiagnostics(this.languageService.getProgram());
|
||||
for (const diagnostic of diagnostics) {
|
||||
resultString += " " + diagnostic.messageText + Harness.IO.newLine();
|
||||
if (typeof diagnostic.messageText !== "string") {
|
||||
let chainedMessage = <ts.DiagnosticMessageChain>diagnostic.messageText;
|
||||
let indentation = " ";
|
||||
while (chainedMessage) {
|
||||
resultString += indentation + chainedMessage.messageText + Harness.IO.newLine();
|
||||
chainedMessage = chainedMessage.next;
|
||||
indentation = indentation + " ";
|
||||
}
|
||||
}
|
||||
else {
|
||||
resultString += " " + diagnostic.messageText + Harness.IO.newLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3220,6 +3235,10 @@ namespace FourSlashInterface {
|
||||
this.state.verifySignatureHelpCount(expected);
|
||||
}
|
||||
|
||||
public signatureHelpCurrentArgumentListIsVariadic(expected: boolean) {
|
||||
this.state.verifyCurrentSignatureHelpIsVariadic(expected);
|
||||
}
|
||||
|
||||
public signatureHelpArgumentCountIs(expected: number) {
|
||||
this.state.verifySignatureHelpArgumentCount(expected);
|
||||
}
|
||||
|
||||
@ -1472,7 +1472,7 @@ namespace Harness {
|
||||
}
|
||||
|
||||
if (typesError && symbolsError) {
|
||||
throw new Error(typesError.message + ts.sys.newLine + symbolsError.message);
|
||||
throw new Error(typesError.message + Harness.IO.newLine() + symbolsError.message);
|
||||
}
|
||||
|
||||
if (typesError) {
|
||||
@ -1756,7 +1756,7 @@ namespace Harness {
|
||||
}
|
||||
|
||||
// Regex for parsing options in the format "@Alpha: Value of any sort"
|
||||
const optionRegex = /^[\/]{2}\s*@(\w+)\s*:\s*(\S*)/gm; // multiple matches on multiple lines
|
||||
const optionRegex = /^[\/]{2}\s*@(\w+)\s*:\s*([^\r\n]*)/gm; // multiple matches on multiple lines
|
||||
|
||||
function extractCompilerSettings(content: string): CompilerSettings {
|
||||
const opts: CompilerSettings = {};
|
||||
@ -1765,7 +1765,7 @@ namespace Harness {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
while ((match = optionRegex.exec(content)) !== null) {
|
||||
/* tslint:enable:no-null-keyword */
|
||||
opts[match[1]] = match[2];
|
||||
opts[match[1]] = match[2].trim();
|
||||
}
|
||||
|
||||
return opts;
|
||||
@ -1793,7 +1793,7 @@ namespace Harness {
|
||||
// Comment line, check for global/file @options and record them
|
||||
optionRegex.lastIndex = 0;
|
||||
const metaDataName = testMetaData[1].toLowerCase();
|
||||
currentFileOptions[testMetaData[1]] = testMetaData[2];
|
||||
currentFileOptions[testMetaData[1]] = testMetaData[2].trim();
|
||||
if (metaDataName !== "filename") {
|
||||
continue;
|
||||
}
|
||||
@ -1813,12 +1813,12 @@ namespace Harness {
|
||||
// Reset local data
|
||||
currentFileContent = undefined;
|
||||
currentFileOptions = {};
|
||||
currentFileName = testMetaData[2];
|
||||
currentFileName = testMetaData[2].trim();
|
||||
refs = [];
|
||||
}
|
||||
else {
|
||||
// First metadata marker in the file
|
||||
currentFileName = testMetaData[2];
|
||||
currentFileName = testMetaData[2].trim();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@ -720,6 +720,10 @@ namespace Harness.LanguageService {
|
||||
clearImmediate(timeoutId: any): void {
|
||||
clearImmediate(timeoutId);
|
||||
}
|
||||
|
||||
createHash(s: string) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
export class ServerLanguageServiceAdapter implements LanguageServiceAdapter {
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
"../compiler/visitor.ts",
|
||||
"../compiler/transformers/ts.ts",
|
||||
"../compiler/transformers/jsx.ts",
|
||||
"../compiler/transformers/esnext.ts",
|
||||
"../compiler/transformers/es2017.ts",
|
||||
"../compiler/transformers/es2016.ts",
|
||||
"../compiler/transformers/es2015.ts",
|
||||
|
||||
@ -43,7 +43,8 @@ namespace ts {
|
||||
setTimeout,
|
||||
clearTimeout,
|
||||
setImmediate: typeof setImmediate !== "undefined" ? setImmediate : action => setTimeout(action, 0),
|
||||
clearImmediate: typeof clearImmediate !== "undefined" ? clearImmediate : clearTimeout
|
||||
clearImmediate: typeof clearImmediate !== "undefined" ? clearImmediate : clearTimeout,
|
||||
createHash: s => s
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -60,7 +60,7 @@ namespace ts {
|
||||
assertParseResult(["--lib", "es5,invalidOption", "0.ts"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@ -165,7 +165,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017'",
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'esnext'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@ -263,7 +263,7 @@ namespace ts {
|
||||
assertParseResult(["--lib", "es5,", "es7", "0.ts"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@ -283,7 +283,7 @@ namespace ts {
|
||||
assertParseResult(["--lib", "es5, ", "es7", "0.ts"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
|
||||
@ -492,5 +492,45 @@ namespace ts.projectSystem {
|
||||
assert.isTrue(host.fileExists(expectedEmittedFileName));
|
||||
assert.equal(host.readFile(expectedEmittedFileName), `"use strict";\r\nfunction Foo() { return 10; }\r\nexports.Foo = Foo;\r\n`);
|
||||
});
|
||||
|
||||
it("shoud not emit js files in external projects", () => {
|
||||
const file1 = {
|
||||
path: "/a/b/file1.ts",
|
||||
content: "consonle.log('file1');"
|
||||
};
|
||||
// file2 has errors. The emitting should not be blocked.
|
||||
const file2 = {
|
||||
path: "/a/b/file2.js",
|
||||
content: "console.log'file2');"
|
||||
};
|
||||
const file3 = {
|
||||
path: "/a/b/file3.js",
|
||||
content: "console.log('file3');"
|
||||
};
|
||||
const externalProjectName = "externalproject";
|
||||
const host = createServerHost([file1, file2, file3, libFile]);
|
||||
const session = createSession(host);
|
||||
const projectService = session.getProjectService();
|
||||
|
||||
projectService.openExternalProject({
|
||||
rootFiles: toExternalFiles([file1.path, file2.path]),
|
||||
options: {
|
||||
allowJs: true,
|
||||
outFile: "dist.js",
|
||||
compileOnSave: true
|
||||
},
|
||||
projectFileName: externalProjectName
|
||||
});
|
||||
|
||||
const emitRequest = makeSessionRequest<server.protocol.CompileOnSaveEmitFileRequestArgs>(CommandNames.CompileOnSaveEmitFile, { file: file1.path });
|
||||
session.executeCommand(emitRequest);
|
||||
|
||||
const expectedOutFileName = "/a/b/dist.js";
|
||||
assert.isTrue(host.fileExists(expectedOutFileName));
|
||||
const outFileContent = host.readFile(expectedOutFileName);
|
||||
assert.isTrue(outFileContent.indexOf(file1.content) !== -1);
|
||||
assert.isTrue(outFileContent.indexOf(file2.content) === -1);
|
||||
assert.isTrue(outFileContent.indexOf(file3.content) === -1);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -176,7 +176,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017'",
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'esnext'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@ -233,7 +233,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@ -264,7 +264,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@ -295,7 +295,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@ -326,7 +326,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
|
||||
@ -44,10 +44,10 @@ namespace ts {
|
||||
|
||||
// NOTE: 'reusedElements' is the expected count of elements reused from the old tree to the new
|
||||
// tree. It may change as we tweak the parser. If the count increases then that should always
|
||||
// be a good thing. If it decreases, that's not great (less reusability), but that may be
|
||||
// unavoidable. If it does decrease an investigation should be done to make sure that things
|
||||
// be a good thing. If it decreases, that's not great (less reusability), but that may be
|
||||
// unavoidable. If it does decrease an investigation should be done to make sure that things
|
||||
// are still ok and we're still appropriately reusing most of the tree.
|
||||
function compareTrees(oldText: IScriptSnapshot, newText: IScriptSnapshot, textChangeRange: TextChangeRange, expectedReusedElements: number, oldTree?: SourceFile): SourceFile {
|
||||
function compareTrees(oldText: IScriptSnapshot, newText: IScriptSnapshot, textChangeRange: TextChangeRange, expectedReusedElements: number, oldTree?: SourceFile) {
|
||||
oldTree = oldTree || createTree(oldText, /*version:*/ ".");
|
||||
Utils.assertInvariants(oldTree, /*parent:*/ undefined);
|
||||
|
||||
@ -76,7 +76,7 @@ namespace ts {
|
||||
assert.equal(actualReusedCount, expectedReusedElements, actualReusedCount + " !== " + expectedReusedElements);
|
||||
}
|
||||
|
||||
return incrementalNewTree;
|
||||
return { oldTree, newTree, incrementalNewTree };
|
||||
}
|
||||
|
||||
function reusedElements(oldNode: SourceFile, newNode: SourceFile): number {
|
||||
@ -103,7 +103,7 @@ namespace ts {
|
||||
for (let i = 0; i < repeat; i++) {
|
||||
const oldText = ScriptSnapshot.fromString(source);
|
||||
const newTextAndChange = withDelete(oldText, index, 1);
|
||||
const newTree = compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1, oldTree);
|
||||
const newTree = compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1, oldTree).incrementalNewTree;
|
||||
|
||||
source = newTextAndChange.text.getText(0, newTextAndChange.text.getLength());
|
||||
oldTree = newTree;
|
||||
@ -116,7 +116,7 @@ namespace ts {
|
||||
for (let i = 0; i < repeat; i++) {
|
||||
const oldText = ScriptSnapshot.fromString(source);
|
||||
const newTextAndChange = withInsert(oldText, index + i, toInsert.charAt(i));
|
||||
const newTree = compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1, oldTree);
|
||||
const newTree = compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1, oldTree).incrementalNewTree;
|
||||
|
||||
source = newTextAndChange.text.getText(0, newTextAndChange.text.getLength());
|
||||
oldTree = newTree;
|
||||
@ -639,7 +639,7 @@ module m3 { }\
|
||||
});
|
||||
|
||||
it("Unterminated comment after keyword converted to identifier", () => {
|
||||
// 'public' as a keyword should be incrementally unusable (because it has an
|
||||
// 'public' as a keyword should be incrementally unusable (because it has an
|
||||
// unterminated comment). When we convert it to an identifier, that shouldn't
|
||||
// change anything, and we should still get the same errors.
|
||||
const source = "return; a.public /*";
|
||||
@ -796,6 +796,16 @@ module m3 { }\
|
||||
compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 4);
|
||||
});
|
||||
|
||||
it("Reuse transformFlags of subtree during bind", () => {
|
||||
const source = `class Greeter { constructor(element: HTMLElement) { } }`;
|
||||
const oldText = ScriptSnapshot.fromString(source);
|
||||
const newTextAndChange = withChange(oldText, 15, 0, "\n");
|
||||
const { oldTree, incrementalNewTree } = compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, -1);
|
||||
bindSourceFile(oldTree, {});
|
||||
bindSourceFile(incrementalNewTree, {});
|
||||
assert.equal(oldTree.transformFlags, incrementalNewTree.transformFlags);
|
||||
});
|
||||
|
||||
// Simulated typing tests.
|
||||
|
||||
it("Type extends clause 1", () => {
|
||||
|
||||
@ -24,7 +24,8 @@ namespace ts.server {
|
||||
setTimeout() { return 0; },
|
||||
clearTimeout: noop,
|
||||
setImmediate: () => 0,
|
||||
clearImmediate: noop
|
||||
clearImmediate: noop,
|
||||
createHash: s => s
|
||||
};
|
||||
const nullCancellationToken: HostCancellationToken = { isCancellationRequested: () => false };
|
||||
const mockLogger: Logger = {
|
||||
|
||||
@ -385,6 +385,10 @@ var x = 0;`, {
|
||||
options: { compilerOptions: { reactNamespace: "react" }, fileName: "input.js", reportDiagnostics: true }
|
||||
});
|
||||
|
||||
transpilesCorrectly("Supports setting 'jsxFactory'", "x;", {
|
||||
options: { compilerOptions: { jsxFactory: "createElement" }, fileName: "input.js", reportDiagnostics: true }
|
||||
});
|
||||
|
||||
transpilesCorrectly("Supports setting 'removeComments'", "x;", {
|
||||
options: { compilerOptions: { removeComments: true }, fileName: "input.js", reportDiagnostics: true }
|
||||
});
|
||||
|
||||
@ -18,7 +18,6 @@ namespace ts.projectSystem {
|
||||
};
|
||||
|
||||
export interface PostExecAction {
|
||||
readonly requestKind: TI.RequestKind;
|
||||
readonly success: boolean;
|
||||
readonly callback: TI.RequestCompletedAction;
|
||||
}
|
||||
@ -47,9 +46,14 @@ namespace ts.projectSystem {
|
||||
|
||||
export class TestTypingsInstaller extends TI.TypingsInstaller implements server.ITypingsInstaller {
|
||||
protected projectService: server.ProjectService;
|
||||
constructor(readonly globalTypingsCacheLocation: string, throttleLimit: number, readonly installTypingHost: server.ServerHost, log?: TI.Log) {
|
||||
super(globalTypingsCacheLocation, safeList.path, throttleLimit, log);
|
||||
this.init();
|
||||
constructor(
|
||||
readonly globalTypingsCacheLocation: string,
|
||||
throttleLimit: number,
|
||||
installTypingHost: server.ServerHost,
|
||||
readonly typesRegistry = createMap<void>(),
|
||||
telemetryEnabled?: boolean,
|
||||
log?: TI.Log) {
|
||||
super(installTypingHost, globalTypingsCacheLocation, safeList.path, throttleLimit, telemetryEnabled, log);
|
||||
}
|
||||
|
||||
safeFileList = safeList.path;
|
||||
@ -63,9 +67,8 @@ namespace ts.projectSystem {
|
||||
}
|
||||
}
|
||||
|
||||
checkPendingCommands(expected: TI.RequestKind[]) {
|
||||
assert.equal(this.postExecActions.length, expected.length, `Expected ${expected.length} post install actions`);
|
||||
this.postExecActions.forEach((act, i) => assert.equal(act.requestKind, expected[i], "Unexpected post install action"));
|
||||
checkPendingCommands(expectedCount: number) {
|
||||
assert.equal(this.postExecActions.length, expectedCount, `Expected ${expectedCount} post install actions`);
|
||||
}
|
||||
|
||||
onProjectClosed() {
|
||||
@ -79,15 +82,8 @@ namespace ts.projectSystem {
|
||||
return this.installTypingHost;
|
||||
}
|
||||
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
switch (requestKind) {
|
||||
case TI.NpmViewRequest:
|
||||
case TI.NpmInstallRequest:
|
||||
break;
|
||||
default:
|
||||
assert.isTrue(false, `request ${requestKind} is not supported`);
|
||||
}
|
||||
this.addPostExecAction(requestKind, "success", cb);
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
this.addPostExecAction("success", cb);
|
||||
}
|
||||
|
||||
sendResponse(response: server.SetTypings | server.InvalidateCachedTypings) {
|
||||
@ -99,12 +95,11 @@ namespace ts.projectSystem {
|
||||
this.install(request);
|
||||
}
|
||||
|
||||
addPostExecAction(requestKind: TI.RequestKind, stdout: string | string[], cb: TI.RequestCompletedAction) {
|
||||
addPostExecAction(stdout: string | string[], cb: TI.RequestCompletedAction) {
|
||||
const out = typeof stdout === "string" ? stdout : createNpmPackageJsonString(stdout);
|
||||
const action: PostExecAction = {
|
||||
success: !!out,
|
||||
callback: cb,
|
||||
requestKind
|
||||
callback: cb
|
||||
};
|
||||
this.postExecActions.push(action);
|
||||
}
|
||||
@ -439,6 +434,10 @@ namespace ts.projectSystem {
|
||||
};
|
||||
}
|
||||
|
||||
createHash(s: string): string {
|
||||
return s;
|
||||
}
|
||||
|
||||
triggerDirectoryWatcherCallback(directoryName: string, fileName: string): void {
|
||||
const path = this.toPath(directoryName);
|
||||
const callbacks = this.watchedDirectories[path];
|
||||
@ -1969,6 +1968,33 @@ namespace ts.projectSystem {
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.configuredProjects[0], [libES5.path, libES2015Promise.path, app.path]);
|
||||
});
|
||||
|
||||
it("should handle non-existing directories in config file", () => {
|
||||
const f = {
|
||||
path: "/a/src/app.ts",
|
||||
content: "let x = 1;"
|
||||
};
|
||||
const config = {
|
||||
path: "/a/tsconfig.json",
|
||||
content: JSON.stringify({
|
||||
compilerOptions: {},
|
||||
include: [
|
||||
"src/**/*",
|
||||
"notexistingfolder/*"
|
||||
]
|
||||
})
|
||||
};
|
||||
const host = createServerHost([f, config]);
|
||||
const projectService = createProjectService(host);
|
||||
projectService.openClientFile(f.path);
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
|
||||
projectService.closeClientFile(f.path);
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 0 });
|
||||
|
||||
projectService.openClientFile(f.path);
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
});
|
||||
});
|
||||
|
||||
describe("prefer typings to js", () => {
|
||||
@ -2227,6 +2253,27 @@ namespace ts.projectSystem {
|
||||
assert.equal(diags.length, 0);
|
||||
});
|
||||
|
||||
it("should property handle missing config files", () => {
|
||||
const f1 = {
|
||||
path: "/a/b/app.ts",
|
||||
content: "let x = 1"
|
||||
};
|
||||
const config = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: "{}"
|
||||
};
|
||||
const projectName = "project1";
|
||||
const host = createServerHost([f1]);
|
||||
const projectService = createProjectService(host);
|
||||
projectService.openExternalProject({ rootFiles: toExternalFiles([f1.path, config.path]), options: {}, projectFileName: projectName });
|
||||
|
||||
// should have one external project since config file is missing
|
||||
projectService.checkNumberOfProjects({ externalProjects: 1 });
|
||||
|
||||
host.reloadFS([f1, config]);
|
||||
projectService.openExternalProject({ rootFiles: toExternalFiles([f1.path, config.path]), options: {}, projectFileName: projectName });
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
});
|
||||
});
|
||||
|
||||
describe("add the missing module file for inferred project", () => {
|
||||
@ -2505,4 +2552,45 @@ namespace ts.projectSystem {
|
||||
checkProjectActualFiles(projectService.inferredProjects[0], [f.path]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("No overwrite emit error", () => {
|
||||
it("for inferred project", () => {
|
||||
const f1 = {
|
||||
path: "/a/b/f1.js",
|
||||
content: "function test1() { }"
|
||||
};
|
||||
const host = createServerHost([f1, libFile]);
|
||||
const session = createSession(host);
|
||||
openFilesForSession([f1], session);
|
||||
|
||||
const projectService = session.getProjectService();
|
||||
checkNumberOfProjects(projectService, { inferredProjects: 1 });
|
||||
const projectName = projectService.inferredProjects[0].getProjectName();
|
||||
|
||||
const diags = session.executeCommand(<server.protocol.CompilerOptionsDiagnosticsRequest>{
|
||||
type: "request",
|
||||
command: server.CommandNames.CompilerOptionsDiagnosticsFull,
|
||||
seq: 2,
|
||||
arguments: { projectFileName: projectName }
|
||||
}).response;
|
||||
assert.isTrue(diags.length === 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("import helpers", () => {
|
||||
it("should not crash in tsserver", () => {
|
||||
const f1 = {
|
||||
path: "/a/app.ts",
|
||||
content: "export async function foo() { return 100; }"
|
||||
};
|
||||
const tslib = {
|
||||
path: "/a/node_modules/tslib/index.d.ts",
|
||||
content: ""
|
||||
};
|
||||
const host = createServerHost([f1, tslib]);
|
||||
const service = createProjectService(host);
|
||||
service.openExternalProject({ projectFileName: "p", rootFiles: [toExternalFile(f1.path)], options: { importHelpers: true } });
|
||||
service.checkNumberOfProjects({ externalProjects: 1 });
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -8,44 +8,44 @@ namespace ts.projectSystem {
|
||||
interface InstallerParams {
|
||||
globalTypingsCacheLocation?: string;
|
||||
throttleLimit?: number;
|
||||
typesRegistry?: Map<void>;
|
||||
}
|
||||
|
||||
function createTypesRegistry(...list: string[]): Map<void> {
|
||||
const map = createMap<void>();
|
||||
for (const l of list) {
|
||||
map[l] = undefined;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
class Installer extends TestTypingsInstaller {
|
||||
constructor(host: server.ServerHost, p?: InstallerParams, log?: TI.Log) {
|
||||
constructor(host: server.ServerHost, p?: InstallerParams, telemetryEnabled?: boolean, log?: TI.Log) {
|
||||
super(
|
||||
(p && p.globalTypingsCacheLocation) || "/a/data",
|
||||
(p && p.throttleLimit) || 5,
|
||||
host,
|
||||
(p && p.typesRegistry),
|
||||
telemetryEnabled,
|
||||
log);
|
||||
}
|
||||
|
||||
installAll(expectedView: typeof TI.NpmViewRequest[], expectedInstall: typeof TI.NpmInstallRequest[]) {
|
||||
this.checkPendingCommands(expectedView);
|
||||
this.executePendingCommands();
|
||||
this.checkPendingCommands(expectedInstall);
|
||||
installAll(expectedCount: number) {
|
||||
this.checkPendingCommands(expectedCount);
|
||||
this.executePendingCommands();
|
||||
}
|
||||
}
|
||||
|
||||
describe("typingsInstaller", () => {
|
||||
function executeCommand(self: Installer, host: TestServerHost, installedTypings: string[], typingFiles: FileOrFolder[], requestKind: TI.RequestKind, cb: TI.RequestCompletedAction): void {
|
||||
switch (requestKind) {
|
||||
case TI.NpmInstallRequest:
|
||||
self.addPostExecAction(requestKind, installedTypings, success => {
|
||||
for (const file of typingFiles) {
|
||||
host.createFileOrFolder(file, /*createParentDirectory*/ true);
|
||||
}
|
||||
cb(success);
|
||||
});
|
||||
break;
|
||||
case TI.NpmViewRequest:
|
||||
self.addPostExecAction(requestKind, installedTypings, cb);
|
||||
break;
|
||||
default:
|
||||
assert.isTrue(false, `unexpected request kind ${requestKind}`);
|
||||
break;
|
||||
function executeCommand(self: Installer, host: TestServerHost, installedTypings: string[], typingFiles: FileOrFolder[], cb: TI.RequestCompletedAction): void {
|
||||
self.addPostExecAction(installedTypings, success => {
|
||||
for (const file of typingFiles) {
|
||||
host.createFileOrFolder(file, /*createParentDirectory*/ true);
|
||||
}
|
||||
}
|
||||
cb(success);
|
||||
});
|
||||
}
|
||||
|
||||
describe("typingsInstaller", () => {
|
||||
it("configured projects (typings installed) 1", () => {
|
||||
const file1 = {
|
||||
path: "/a/b/app.js",
|
||||
@ -79,12 +79,12 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost([file1, tsconfig, packageJson]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host);
|
||||
super(host, { typesRegistry: createTypesRegistry("jquery") });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
const installedTypings = ["@types/jquery"];
|
||||
const typingFiles = [jquery];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
executeCommand(this, host, installedTypings, typingFiles, cb);
|
||||
}
|
||||
})();
|
||||
|
||||
@ -95,7 +95,7 @@ namespace ts.projectSystem {
|
||||
const p = projectService.configuredProjects[0];
|
||||
checkProjectActualFiles(p, [file1.path]);
|
||||
|
||||
installer.installAll([TI.NpmViewRequest], [TI.NpmInstallRequest]);
|
||||
installer.installAll(/*expectedCount*/ 1);
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(p, [file1.path, jquery.path]);
|
||||
@ -123,12 +123,12 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost([file1, packageJson]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host);
|
||||
super(host, { typesRegistry: createTypesRegistry("jquery") });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
const installedTypings = ["@types/jquery"];
|
||||
const typingFiles = [jquery];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
executeCommand(this, host, installedTypings, typingFiles, cb);
|
||||
}
|
||||
})();
|
||||
|
||||
@ -139,7 +139,7 @@ namespace ts.projectSystem {
|
||||
const p = projectService.inferredProjects[0];
|
||||
checkProjectActualFiles(p, [file1.path]);
|
||||
|
||||
installer.installAll([TI.NpmViewRequest], [TI.NpmInstallRequest]);
|
||||
installer.installAll(/*expectedCount*/ 1);
|
||||
|
||||
checkNumberOfProjects(projectService, { inferredProjects: 1 });
|
||||
checkProjectActualFiles(p, [file1.path, jquery.path]);
|
||||
@ -167,7 +167,7 @@ namespace ts.projectSystem {
|
||||
options: {},
|
||||
rootFiles: [toExternalFile(file1.path)]
|
||||
});
|
||||
installer.checkPendingCommands([]);
|
||||
installer.checkPendingCommands(/*expectedCount*/ 0);
|
||||
// by default auto discovery will kick in if project contain only .js/.d.ts files
|
||||
// in this case project contain only ts files - no auto discovery
|
||||
projectService.checkNumberOfProjects({ externalProjects: 1 });
|
||||
@ -181,7 +181,7 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost([file1]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host);
|
||||
super(host, { typesRegistry: createTypesRegistry("jquery") });
|
||||
}
|
||||
enqueueInstallTypingsRequest() {
|
||||
assert(false, "auto discovery should not be enabled");
|
||||
@ -196,7 +196,7 @@ namespace ts.projectSystem {
|
||||
rootFiles: [toExternalFile(file1.path)],
|
||||
typingOptions: { include: ["jquery"] }
|
||||
});
|
||||
installer.checkPendingCommands([]);
|
||||
installer.checkPendingCommands(/*expectedCount*/ 0);
|
||||
// by default auto discovery will kick in if project contain only .js/.d.ts files
|
||||
// in this case project contain only ts files - no auto discovery even if typing options is set
|
||||
projectService.checkNumberOfProjects({ externalProjects: 1 });
|
||||
@ -215,16 +215,16 @@ namespace ts.projectSystem {
|
||||
let enqueueIsCalled = false;
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host);
|
||||
super(host, { typesRegistry: createTypesRegistry("jquery") });
|
||||
}
|
||||
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions, unresolvedImports: server.SortedReadonlyArray<string>) {
|
||||
enqueueIsCalled = true;
|
||||
super.enqueueInstallTypingsRequest(project, typingOptions, unresolvedImports);
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
const installedTypings = ["@types/jquery"];
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
const installedTypings = ["@types/node"];
|
||||
const typingFiles = [jquery];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
executeCommand(this, host, installedTypings, typingFiles, cb);
|
||||
}
|
||||
})();
|
||||
|
||||
@ -234,11 +234,11 @@ namespace ts.projectSystem {
|
||||
projectFileName,
|
||||
options: {},
|
||||
rootFiles: [toExternalFile(file1.path)],
|
||||
typingOptions: { enableAutoDiscovery: true, include: ["node"] }
|
||||
typingOptions: { enableAutoDiscovery: true, include: ["jquery"] }
|
||||
});
|
||||
|
||||
assert.isTrue(enqueueIsCalled, "expected enqueueIsCalled to be true");
|
||||
installer.installAll([TI.NpmViewRequest], [TI.NpmInstallRequest]);
|
||||
installer.installAll(/*expectedCount*/ 1);
|
||||
|
||||
// autoDiscovery is set in typing options - use it even if project contains only .ts files
|
||||
projectService.checkNumberOfProjects({ externalProjects: 1 });
|
||||
@ -273,12 +273,12 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost([file1, file2, file3]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host);
|
||||
super(host, { typesRegistry: createTypesRegistry("lodash", "react") });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
const installedTypings = ["@types/lodash", "@types/react"];
|
||||
const typingFiles = [lodash, react];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
executeCommand(this, host, installedTypings, typingFiles, cb);
|
||||
}
|
||||
})();
|
||||
|
||||
@ -295,7 +295,7 @@ namespace ts.projectSystem {
|
||||
projectService.checkNumberOfProjects({ externalProjects: 1 });
|
||||
checkProjectActualFiles(p, [file1.path, file2.path, file3.path]);
|
||||
|
||||
installer.installAll([TI.NpmViewRequest, TI.NpmViewRequest], [TI.NpmInstallRequest], );
|
||||
installer.installAll(/*expectedCount*/ 1);
|
||||
|
||||
checkNumberOfProjects(projectService, { externalProjects: 1 });
|
||||
checkProjectActualFiles(p, [file1.path, file2.path, file3.path, lodash.path, react.path]);
|
||||
@ -317,16 +317,16 @@ namespace ts.projectSystem {
|
||||
let enqueueIsCalled = false;
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host);
|
||||
super(host, { typesRegistry: createTypesRegistry("jquery") });
|
||||
}
|
||||
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions, unresolvedImports: server.SortedReadonlyArray<string>) {
|
||||
enqueueIsCalled = true;
|
||||
super.enqueueInstallTypingsRequest(project, typingOptions, unresolvedImports);
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
const installedTypings: string[] = [];
|
||||
const typingFiles: FileOrFolder[] = [];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
executeCommand(this, host, installedTypings, typingFiles, cb);
|
||||
}
|
||||
})();
|
||||
|
||||
@ -343,7 +343,7 @@ namespace ts.projectSystem {
|
||||
projectService.checkNumberOfProjects({ externalProjects: 1 });
|
||||
checkProjectActualFiles(p, [file1.path, file2.path]);
|
||||
|
||||
installer.checkPendingCommands([]);
|
||||
installer.checkPendingCommands(/*expectedCount*/ 0);
|
||||
|
||||
checkNumberOfProjects(projectService, { externalProjects: 1 });
|
||||
checkProjectActualFiles(p, [file1.path, file2.path]);
|
||||
@ -396,12 +396,12 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost([file1, file2, file3, packageJson]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host);
|
||||
super(host, { typesRegistry: createTypesRegistry("jquery", "commander", "moment", "express") });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
const installedTypings = ["@types/commander", "@types/express", "@types/jquery", "@types/moment"];
|
||||
const typingFiles = [commander, express, jquery, moment];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
executeCommand(this, host, installedTypings, typingFiles, cb);
|
||||
}
|
||||
})();
|
||||
|
||||
@ -418,10 +418,7 @@ namespace ts.projectSystem {
|
||||
projectService.checkNumberOfProjects({ externalProjects: 1 });
|
||||
checkProjectActualFiles(p, [file1.path, file2.path, file3.path]);
|
||||
|
||||
installer.installAll(
|
||||
[TI.NpmViewRequest, TI.NpmViewRequest, TI.NpmViewRequest, TI.NpmViewRequest],
|
||||
[TI.NpmInstallRequest]
|
||||
);
|
||||
installer.installAll(/*expectedCount*/ 1);
|
||||
|
||||
checkNumberOfProjects(projectService, { externalProjects: 1 });
|
||||
checkProjectActualFiles(p, [file1.path, file2.path, file3.path, commander.path, express.path, jquery.path, moment.path]);
|
||||
@ -475,11 +472,11 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost([lodashJs, commanderJs, file3, packageJson]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { throttleLimit: 3 });
|
||||
super(host, { throttleLimit: 3, typesRegistry: createTypesRegistry("commander", "express", "jquery", "moment", "lodash") });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
const installedTypings = ["@types/commander", "@types/express", "@types/jquery", "@types/moment", "@types/lodash"];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
executeCommand(this, host, installedTypings, typingFiles, cb);
|
||||
}
|
||||
})();
|
||||
|
||||
@ -495,18 +492,7 @@ namespace ts.projectSystem {
|
||||
const p = projectService.externalProjects[0];
|
||||
projectService.checkNumberOfProjects({ externalProjects: 1 });
|
||||
checkProjectActualFiles(p, [lodashJs.path, commanderJs.path, file3.path]);
|
||||
// expected 3 view requests in the queue
|
||||
installer.checkPendingCommands([TI.NpmViewRequest, TI.NpmViewRequest, TI.NpmViewRequest]);
|
||||
assert.equal(installer.pendingRunRequests.length, 2, "expected 2 pending requests");
|
||||
|
||||
// push view requests
|
||||
installer.executePendingCommands();
|
||||
// expected 2 remaining view requests in the queue
|
||||
installer.checkPendingCommands([TI.NpmViewRequest, TI.NpmViewRequest]);
|
||||
// push view requests
|
||||
installer.executePendingCommands();
|
||||
// expected one install request
|
||||
installer.checkPendingCommands([TI.NpmInstallRequest]);
|
||||
installer.checkPendingCommands(/*expectedCount*/ 1);
|
||||
installer.executePendingCommands();
|
||||
// expected all typings file to exist
|
||||
for (const f of typingFiles) {
|
||||
@ -565,22 +551,17 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost([lodashJs, commanderJs, file3]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { throttleLimit: 3 });
|
||||
super(host, { throttleLimit: 1, typesRegistry: createTypesRegistry("commander", "jquery", "lodash", "cordova", "gulp", "grunt") });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
if (requestKind === TI.NpmInstallRequest) {
|
||||
let typingFiles: (FileOrFolder & { typings: string })[] = [];
|
||||
if (args.indexOf("@types/commander") >= 0) {
|
||||
typingFiles = [commander, jquery, lodash, cordova];
|
||||
}
|
||||
else {
|
||||
typingFiles = [grunt, gulp];
|
||||
}
|
||||
executeCommand(this, host, typingFiles.map(f => f.typings), typingFiles, requestKind, cb);
|
||||
installWorker(_requestId: number, args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
let typingFiles: (FileOrFolder & { typings: string })[] = [];
|
||||
if (args.indexOf("@types/commander") >= 0) {
|
||||
typingFiles = [commander, jquery, lodash, cordova];
|
||||
}
|
||||
else {
|
||||
executeCommand(this, host, [], [], requestKind, cb);
|
||||
typingFiles = [grunt, gulp];
|
||||
}
|
||||
executeCommand(this, host, typingFiles.map(f => f.typings), typingFiles, cb);
|
||||
}
|
||||
})();
|
||||
|
||||
@ -594,8 +575,8 @@ namespace ts.projectSystem {
|
||||
typingOptions: { include: ["jquery", "cordova"] }
|
||||
});
|
||||
|
||||
installer.checkPendingCommands([TI.NpmViewRequest, TI.NpmViewRequest, TI.NpmViewRequest]);
|
||||
assert.equal(installer.pendingRunRequests.length, 1, "expect one throttled request");
|
||||
installer.checkPendingCommands(/*expectedCount*/ 1);
|
||||
assert.equal(installer.pendingRunRequests.length, 0, "expect no throttled requests");
|
||||
|
||||
// Create project #2 with 2 typings
|
||||
const projectFileName2 = "/a/app/test2.csproj";
|
||||
@ -605,7 +586,7 @@ namespace ts.projectSystem {
|
||||
rootFiles: [toExternalFile(file3.path)],
|
||||
typingOptions: { include: ["grunt", "gulp"] }
|
||||
});
|
||||
assert.equal(installer.pendingRunRequests.length, 3, "expect three throttled request");
|
||||
assert.equal(installer.pendingRunRequests.length, 1, "expect one throttled request");
|
||||
|
||||
const p1 = projectService.externalProjects[0];
|
||||
const p2 = projectService.externalProjects[1];
|
||||
@ -613,18 +594,14 @@ namespace ts.projectSystem {
|
||||
checkProjectActualFiles(p1, [lodashJs.path, commanderJs.path, file3.path]);
|
||||
checkProjectActualFiles(p2, [file3.path]);
|
||||
|
||||
|
||||
installer.executePendingCommands();
|
||||
// expected one view request from the first project and two - from the second one
|
||||
installer.checkPendingCommands([TI.NpmViewRequest, TI.NpmViewRequest, TI.NpmViewRequest]);
|
||||
|
||||
// expected one install request from the second project
|
||||
installer.checkPendingCommands(/*expectedCount*/ 1);
|
||||
assert.equal(installer.pendingRunRequests.length, 0, "expected no throttled requests");
|
||||
|
||||
installer.executePendingCommands();
|
||||
|
||||
// should be two install requests from both projects
|
||||
installer.checkPendingCommands([TI.NpmInstallRequest, TI.NpmInstallRequest]);
|
||||
installer.executePendingCommands();
|
||||
|
||||
checkProjectActualFiles(p1, [lodashJs.path, commanderJs.path, file3.path, commander.path, jquery.path, lodash.path, cordova.path]);
|
||||
checkProjectActualFiles(p2, [file3.path, grunt.path, gulp.path]);
|
||||
});
|
||||
@ -653,12 +630,12 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost([app, jsconfig, jquery, jqueryPackage]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { globalTypingsCacheLocation: "/tmp" });
|
||||
super(host, { globalTypingsCacheLocation: "/tmp", typesRegistry: createTypesRegistry("jquery") });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
const installedTypings = ["@types/jquery"];
|
||||
const typingFiles = [jqueryDTS];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
executeCommand(this, host, installedTypings, typingFiles, cb);
|
||||
}
|
||||
})();
|
||||
|
||||
@ -669,7 +646,7 @@ namespace ts.projectSystem {
|
||||
const p = projectService.configuredProjects[0];
|
||||
checkProjectActualFiles(p, [app.path]);
|
||||
|
||||
installer.installAll([TI.NpmViewRequest], [TI.NpmInstallRequest]);
|
||||
installer.installAll(/*expectedCount*/ 1);
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(p, [app.path, jqueryDTS.path]);
|
||||
@ -699,12 +676,12 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost([app, jsconfig, bowerJson]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { globalTypingsCacheLocation: "/tmp" });
|
||||
super(host, { globalTypingsCacheLocation: "/tmp", typesRegistry: createTypesRegistry("jquery") });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
const installedTypings = ["@types/jquery"];
|
||||
const typingFiles = [jqueryDTS];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
executeCommand(this, host, installedTypings, typingFiles, cb);
|
||||
}
|
||||
})();
|
||||
|
||||
@ -715,7 +692,7 @@ namespace ts.projectSystem {
|
||||
const p = projectService.configuredProjects[0];
|
||||
checkProjectActualFiles(p, [app.path]);
|
||||
|
||||
installer.installAll([TI.NpmViewRequest], [TI.NpmInstallRequest]);
|
||||
installer.installAll(/*expectedCount*/ 1);
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(p, [app.path, jqueryDTS.path]);
|
||||
@ -742,23 +719,23 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost([f, brokenPackageJson]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { globalTypingsCacheLocation: cachePath });
|
||||
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
const installedTypings = ["@types/commander"];
|
||||
const typingFiles = [commander];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
executeCommand(this, host, installedTypings, typingFiles, cb);
|
||||
}
|
||||
})();
|
||||
const service = createProjectService(host, { typingsInstaller: installer });
|
||||
service.openClientFile(f.path);
|
||||
|
||||
installer.checkPendingCommands([]);
|
||||
installer.checkPendingCommands(/*expectedCount*/ 0);
|
||||
|
||||
host.reloadFS([f, fixedPackageJson]);
|
||||
host.triggerFileWatcherCallback(fixedPackageJson.path, /*removed*/ false);
|
||||
// expected one view and one install request
|
||||
installer.installAll([TI.NpmViewRequest], [TI.NpmInstallRequest]);
|
||||
// expected install request
|
||||
installer.installAll(/*expectedCount*/ 1);
|
||||
|
||||
service.checkNumberOfProjects({ inferredProjects: 1 });
|
||||
checkProjectActualFiles(service.inferredProjects[0], [f.path, commander.path]);
|
||||
@ -783,12 +760,12 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost([file]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { globalTypingsCacheLocation: cachePath });
|
||||
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("node", "commander") });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
const installedTypings = ["@types/node", "@types/commander"];
|
||||
const typingFiles = [node, commander];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
executeCommand(this, host, installedTypings, typingFiles, cb);
|
||||
}
|
||||
})();
|
||||
const service = createProjectService(host, { typingsInstaller: installer });
|
||||
@ -797,7 +774,7 @@ namespace ts.projectSystem {
|
||||
service.checkNumberOfProjects({ inferredProjects: 1 });
|
||||
checkProjectActualFiles(service.inferredProjects[0], [file.path]);
|
||||
|
||||
installer.installAll([TI.NpmViewRequest, TI.NpmViewRequest], [TI.NpmInstallRequest]);
|
||||
installer.installAll(/*expectedCount*/1);
|
||||
|
||||
assert.isTrue(host.fileExists(node.path), "typings for 'node' should be created");
|
||||
assert.isTrue(host.fileExists(commander.path), "typings for 'commander' should be created");
|
||||
@ -822,14 +799,10 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost([f1]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { globalTypingsCacheLocation: "/tmp" });
|
||||
super(host, { globalTypingsCacheLocation: "/tmp", typesRegistry: createTypesRegistry("foo") });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
if (requestKind === TI.NpmViewRequest) {
|
||||
// args should have only non-scoped packages - scoped packages are not yet supported
|
||||
assert.deepEqual(args, ["foo"]);
|
||||
}
|
||||
executeCommand(this, host, ["foo"], [], requestKind, cb);
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
executeCommand(this, host, ["foo"], [], cb);
|
||||
}
|
||||
})();
|
||||
const projectService = createProjectService(host, { typingsInstaller: installer });
|
||||
@ -844,7 +817,7 @@ namespace ts.projectSystem {
|
||||
["foo", "foo", "foo", "@bar/router", "@bar/common", "@bar/common"]
|
||||
);
|
||||
|
||||
installer.installAll([TI.NpmViewRequest], [TI.NpmInstallRequest]);
|
||||
installer.installAll(/*expectedCount*/ 1);
|
||||
});
|
||||
|
||||
it("cached unresolved typings are not recomputed if program structure did not change", () => {
|
||||
@ -934,16 +907,16 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost([f1, packageJson]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { globalTypingsCacheLocation: "/tmp" }, { isEnabled: () => true, writeLine: msg => messages.push(msg) });
|
||||
super(host, { globalTypingsCacheLocation: "/tmp" }, /*telemetryEnabled*/ false, { isEnabled: () => true, writeLine: msg => messages.push(msg) });
|
||||
}
|
||||
executeRequest() {
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, _cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
assert(false, "runCommand should not be invoked");
|
||||
}
|
||||
})();
|
||||
const projectService = createProjectService(host, { typingsInstaller: installer });
|
||||
projectService.openClientFile(f1.path);
|
||||
|
||||
installer.checkPendingCommands([]);
|
||||
installer.checkPendingCommands(/*expectedCount*/ 0);
|
||||
assert.isTrue(messages.indexOf("Package name '; say ‘Hello from TypeScript!’ #' contains non URI safe characters") > 0, "should find package with invalid name");
|
||||
});
|
||||
});
|
||||
@ -978,4 +951,50 @@ namespace ts.projectSystem {
|
||||
assert.deepEqual(result.newTypingNames, ["bar"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("telemetry events", () => {
|
||||
it ("should be received", () => {
|
||||
const f1 = {
|
||||
path: "/a/app.js",
|
||||
content: ""
|
||||
};
|
||||
const package = {
|
||||
path: "/a/package.json",
|
||||
content: JSON.stringify({ dependencies: { "commander": "1.0.0" } })
|
||||
};
|
||||
const cachePath = "/a/cache/";
|
||||
const commander = {
|
||||
path: cachePath + "node_modules/@types/commander/index.d.ts",
|
||||
content: "export let x: number"
|
||||
};
|
||||
const host = createServerHost([f1, package]);
|
||||
let seenTelemetryEvent = false;
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") }, /*telemetryEnabled*/ true);
|
||||
}
|
||||
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
const installedTypings = ["@types/commander"];
|
||||
const typingFiles = [commander];
|
||||
executeCommand(this, host, installedTypings, typingFiles, cb);
|
||||
}
|
||||
sendResponse(response: server.SetTypings | server.InvalidateCachedTypings | server.TypingsInstallEvent) {
|
||||
if (response.kind === server.EventInstall) {
|
||||
assert.deepEqual(response.packagesToInstall, ["@types/commander"]);
|
||||
seenTelemetryEvent = true;
|
||||
return;
|
||||
}
|
||||
super.sendResponse(response);
|
||||
}
|
||||
})();
|
||||
const projectService = createProjectService(host, { typingsInstaller: installer });
|
||||
projectService.openClientFile(f1.path);
|
||||
|
||||
installer.installAll(/*expectedCount*/ 1);
|
||||
|
||||
assert.isTrue(seenTelemetryEvent);
|
||||
checkNumberOfProjects(projectService, { inferredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.inferredProjects[0], [f1.path, commander.path]);
|
||||
});
|
||||
});
|
||||
}
|
||||
4
src/lib/dom.generated.d.ts
vendored
4
src/lib/dom.generated.d.ts
vendored
@ -7586,7 +7586,7 @@ declare var IDBCursorWithValue: {
|
||||
|
||||
interface IDBDatabase extends EventTarget {
|
||||
readonly name: string;
|
||||
readonly objectStoreNames: string[];
|
||||
readonly objectStoreNames: DOMStringList;
|
||||
onabort: (this: this, ev: Event) => any;
|
||||
onerror: (this: this, ev: ErrorEvent) => any;
|
||||
version: number;
|
||||
@ -7652,7 +7652,7 @@ declare var IDBKeyRange: {
|
||||
}
|
||||
|
||||
interface IDBObjectStore {
|
||||
readonly indexNames: string[];
|
||||
readonly indexNames: DOMStringList;
|
||||
keyPath: string | string[];
|
||||
readonly name: string;
|
||||
readonly transaction: IDBTransaction;
|
||||
|
||||
3
src/lib/es2017.d.ts
vendored
3
src/lib/es2017.d.ts
vendored
@ -1,3 +1,4 @@
|
||||
/// <reference path="lib.es2016.d.ts" />
|
||||
/// <reference path="lib.es2017.object.d.ts" />
|
||||
/// <reference path="lib.es2017.sharedmemory.d.ts" />
|
||||
/// <reference path="lib.es2017.sharedmemory.d.ts" />
|
||||
/// <reference path="lib.es2017.string.d.ts" />
|
||||
|
||||
27
src/lib/es2017.string.d.ts
vendored
Normal file
27
src/lib/es2017.string.d.ts
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
interface String {
|
||||
/**
|
||||
* Pads the current string with a given string (possibly repeated) so that the resulting string reaches a given length.
|
||||
* The padding is applied from the start (left) of the current string.
|
||||
*
|
||||
* @param maxLength The length of the resulting string once the current string has been padded.
|
||||
* If this parameter is smaller than the current string's length, the current string will be returned as it is.
|
||||
*
|
||||
* @param fillString The string to pad the current string with.
|
||||
* If this string is too long, it will be truncated and the left-most part will be applied.
|
||||
* The default value for this parameter is " " (U+0020).
|
||||
*/
|
||||
padStart(maxLength: number, fillString?: string): string;
|
||||
|
||||
/**
|
||||
* Pads the current string with a given string (possibly repeated) so that the resulting string reaches a given length.
|
||||
* The padding is applied from the end (right) of the current string.
|
||||
*
|
||||
* @param maxLength The length of the resulting string once the current string has been padded.
|
||||
* If this parameter is smaller than the current string's length, the current string will be returned as it is.
|
||||
*
|
||||
* @param fillString The string to pad the current string with.
|
||||
* If this string is too long, it will be truncated and the left-most part will be applied.
|
||||
* The default value for this parameter is " " (U+0020).
|
||||
*/
|
||||
padEnd(maxLength: number, fillString?: string): string;
|
||||
}
|
||||
4
src/lib/webworker.generated.d.ts
vendored
4
src/lib/webworker.generated.d.ts
vendored
@ -341,7 +341,7 @@ declare var IDBCursorWithValue: {
|
||||
|
||||
interface IDBDatabase extends EventTarget {
|
||||
readonly name: string;
|
||||
readonly objectStoreNames: string[];
|
||||
readonly objectStoreNames: DOMStringList;
|
||||
onabort: (this: this, ev: Event) => any;
|
||||
onerror: (this: this, ev: ErrorEvent) => any;
|
||||
version: number;
|
||||
@ -407,7 +407,7 @@ declare var IDBKeyRange: {
|
||||
}
|
||||
|
||||
interface IDBObjectStore {
|
||||
readonly indexNames: string[];
|
||||
readonly indexNames: DOMStringList;
|
||||
keyPath: string | string[];
|
||||
readonly name: string;
|
||||
readonly transaction: IDBTransaction;
|
||||
|
||||
@ -5,15 +5,6 @@
|
||||
|
||||
namespace ts.server {
|
||||
|
||||
interface Hash {
|
||||
update(data: any, input_encoding?: string): Hash;
|
||||
digest(encoding: string): any;
|
||||
}
|
||||
|
||||
const crypto: {
|
||||
createHash(algorithm: string): Hash
|
||||
} = require("crypto");
|
||||
|
||||
export function shouldEmitFile(scriptInfo: ScriptInfo) {
|
||||
return !scriptInfo.hasMixedContent;
|
||||
}
|
||||
@ -49,9 +40,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private computeHash(text: string): string {
|
||||
return crypto.createHash("md5")
|
||||
.update(text)
|
||||
.digest("base64");
|
||||
return this.project.projectService.host.createHash(text);
|
||||
}
|
||||
|
||||
private getSourceFile(): SourceFile {
|
||||
|
||||
@ -250,6 +250,8 @@ namespace ts.server {
|
||||
readonly typingsInstaller: ITypingsInstaller = nullTypingsInstaller,
|
||||
private readonly eventHandler?: ProjectServiceEventHandler) {
|
||||
|
||||
Debug.assert(!!host.createHash, "'ServerHost.createHash' is required for ProjectService");
|
||||
|
||||
this.toCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames);
|
||||
this.directoryWatchers = new DirectoryWatchers(this);
|
||||
this.throttledOperations = new ThrottledOperations(host);
|
||||
@ -286,10 +288,10 @@ namespace ts.server {
|
||||
return;
|
||||
}
|
||||
switch (response.kind) {
|
||||
case "set":
|
||||
case ActionSet:
|
||||
this.typingsCache.updateTypingsForProject(response.projectName, response.compilerOptions, response.typingOptions, response.unresolvedImports, response.typings);
|
||||
break;
|
||||
case "invalidate":
|
||||
case ActionInvalidate:
|
||||
this.typingsCache.deleteTypingsForProject(response.projectName);
|
||||
break;
|
||||
}
|
||||
@ -1288,7 +1290,9 @@ namespace ts.server {
|
||||
for (const file of proj.rootFiles) {
|
||||
const normalized = toNormalizedPath(file.fileName);
|
||||
if (getBaseFileName(normalized) === "tsconfig.json") {
|
||||
(tsConfigFiles || (tsConfigFiles = [])).push(normalized);
|
||||
if (this.host.fileExists(normalized)) {
|
||||
(tsConfigFiles || (tsConfigFiles = [])).push(normalized);
|
||||
}
|
||||
}
|
||||
else {
|
||||
rootFiles.push(file);
|
||||
|
||||
@ -13,6 +13,7 @@ namespace ts.server {
|
||||
|
||||
private readonly resolveModuleName: typeof resolveModuleName;
|
||||
readonly trace: (s: string) => void;
|
||||
readonly realpath?: (path: string) => string;
|
||||
|
||||
constructor(private readonly host: ServerHost, private readonly project: Project, private readonly cancellationToken: HostCancellationToken) {
|
||||
this.getCanonicalFileName = ts.createGetCanonicalFileName(this.host.useCaseSensitiveFileNames);
|
||||
@ -39,6 +40,10 @@ namespace ts.server {
|
||||
}
|
||||
return primaryResult;
|
||||
};
|
||||
|
||||
if (this.host.realpath) {
|
||||
this.realpath = path => this.host.realpath(path);
|
||||
}
|
||||
}
|
||||
|
||||
public startRecordingFilesWithChangedResolutions() {
|
||||
|
||||
@ -161,6 +161,10 @@ namespace ts.server {
|
||||
this.compilerOptions.allowNonTsExtensions = true;
|
||||
}
|
||||
|
||||
if (this.projectKind === ProjectKind.Inferred || this.projectKind === ProjectKind.External) {
|
||||
this.compilerOptions.noEmitForJsFiles = true;
|
||||
}
|
||||
|
||||
if (languageServiceEnabled) {
|
||||
this.enableLanguageService();
|
||||
}
|
||||
@ -297,7 +301,7 @@ namespace ts.server {
|
||||
return this.getLanguageService().getEmitOutput(info.fileName, emitOnlyDtsFiles);
|
||||
}
|
||||
|
||||
getFileNames() {
|
||||
getFileNames(excludeFilesFromExternalLibraries?: boolean) {
|
||||
if (!this.program) {
|
||||
return [];
|
||||
}
|
||||
@ -313,8 +317,14 @@ namespace ts.server {
|
||||
}
|
||||
return rootFiles;
|
||||
}
|
||||
const sourceFiles = this.program.getSourceFiles();
|
||||
return sourceFiles.map(sourceFile => asNormalizedPath(sourceFile.fileName));
|
||||
const result: NormalizedPath[] = [];
|
||||
for (const f of this.program.getSourceFiles()) {
|
||||
if (excludeFilesFromExternalLibraries && this.program.isSourceFileFromExternalLibrary(f)) {
|
||||
continue;
|
||||
}
|
||||
result.push(asNormalizedPath(f.fileName));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
getAllEmittableFiles() {
|
||||
|
||||
@ -2057,6 +2057,32 @@ namespace ts.server.protocol {
|
||||
childItems?: NavigationTree[];
|
||||
}
|
||||
|
||||
export type TelemetryEventName = "telemetry";
|
||||
|
||||
export interface TelemetryEvent extends Event {
|
||||
event: TelemetryEventName;
|
||||
body: TelemetryEventBody;
|
||||
}
|
||||
|
||||
export interface TelemetryEventBody {
|
||||
telemetryEventName: string;
|
||||
payload: any;
|
||||
}
|
||||
|
||||
export type TypingsInstalledTelemetryEventName = "typingsInstalled";
|
||||
|
||||
export interface TypingsInstalledTelemetryEventBody extends TelemetryEventBody {
|
||||
telemetryEventName: TypingsInstalledTelemetryEventName;
|
||||
payload: TypingsInstalledTelemetryEventPayload;
|
||||
}
|
||||
|
||||
export interface TypingsInstalledTelemetryEventPayload {
|
||||
/**
|
||||
* Comma separated list of installed typing packages
|
||||
*/
|
||||
installedPackages: string;
|
||||
}
|
||||
|
||||
export interface NavBarResponse extends Response {
|
||||
body?: NavigationBarItem[];
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference path="shared.ts" />
|
||||
/// <reference path="session.ts" />
|
||||
// used in fs.writeSync
|
||||
/* tslint:disable:no-null-keyword */
|
||||
@ -196,8 +197,10 @@ namespace ts.server {
|
||||
private socket: NodeSocket;
|
||||
private projectService: ProjectService;
|
||||
private throttledOperations: ThrottledOperations;
|
||||
private telemetrySender: EventSender;
|
||||
|
||||
constructor(
|
||||
private readonly telemetryEnabled: boolean,
|
||||
private readonly logger: server.Logger,
|
||||
host: ServerHost,
|
||||
eventPort: number,
|
||||
@ -226,15 +229,22 @@ namespace ts.server {
|
||||
this.socket.write(formatMessage({ seq, type: "event", event, body }, this.logger, Buffer.byteLength, this.newLine), "utf8");
|
||||
}
|
||||
|
||||
setTelemetrySender(telemetrySender: EventSender) {
|
||||
this.telemetrySender = telemetrySender;
|
||||
}
|
||||
|
||||
attach(projectService: ProjectService) {
|
||||
this.projectService = projectService;
|
||||
if (this.logger.hasLevel(LogLevel.requestTime)) {
|
||||
this.logger.info("Binding...");
|
||||
}
|
||||
|
||||
const args: string[] = ["--globalTypingsCacheLocation", this.globalTypingsCacheLocation];
|
||||
const args: string[] = [Arguments.GlobalCacheLocation, this.globalTypingsCacheLocation];
|
||||
if (this.telemetryEnabled) {
|
||||
args.push(Arguments.EnableTelemetry);
|
||||
}
|
||||
if (this.logger.loggingEnabled() && this.logger.getLogFileName()) {
|
||||
args.push("--logFile", combinePaths(getDirectoryPath(normalizeSlashes(this.logger.getLogFileName())), `ti-${process.pid}.log`));
|
||||
args.push(Arguments.LogFile, combinePaths(getDirectoryPath(normalizeSlashes(this.logger.getLogFileName())), `ti-${process.pid}.log`));
|
||||
}
|
||||
const execArgv: string[] = [];
|
||||
{
|
||||
@ -280,12 +290,25 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
private handleMessage(response: SetTypings | InvalidateCachedTypings) {
|
||||
private handleMessage(response: SetTypings | InvalidateCachedTypings | TypingsInstallEvent) {
|
||||
if (this.logger.hasLevel(LogLevel.verbose)) {
|
||||
this.logger.info(`Received response: ${JSON.stringify(response)}`);
|
||||
}
|
||||
if (response.kind === EventInstall) {
|
||||
if (this.telemetrySender) {
|
||||
const body: protocol.TypingsInstalledTelemetryEventBody = {
|
||||
telemetryEventName: "typingsInstalled",
|
||||
payload: {
|
||||
installedPackages: response.packagesToInstall.join(",")
|
||||
}
|
||||
};
|
||||
const eventName: protocol.TelemetryEventName = "telemetry";
|
||||
this.telemetrySender.event(body, eventName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.projectService.updateTypingsForProject(response);
|
||||
if (response.kind == "set" && this.socket) {
|
||||
if (response.kind == ActionSet && this.socket) {
|
||||
this.sendEvent(0, "setTypings", response);
|
||||
}
|
||||
}
|
||||
@ -300,18 +323,25 @@ namespace ts.server {
|
||||
useSingleInferredProject: boolean,
|
||||
disableAutomaticTypingAcquisition: boolean,
|
||||
globalTypingsCacheLocation: string,
|
||||
telemetryEnabled: boolean,
|
||||
logger: server.Logger) {
|
||||
super(
|
||||
host,
|
||||
cancellationToken,
|
||||
useSingleInferredProject,
|
||||
disableAutomaticTypingAcquisition
|
||||
? nullTypingsInstaller
|
||||
: new NodeTypingsInstaller(logger, host, installerEventPort, globalTypingsCacheLocation, host.newLine),
|
||||
Buffer.byteLength,
|
||||
process.hrtime,
|
||||
logger,
|
||||
canUseEvents);
|
||||
const typingsInstaller = disableAutomaticTypingAcquisition
|
||||
? undefined
|
||||
: new NodeTypingsInstaller(telemetryEnabled, logger, host, installerEventPort, globalTypingsCacheLocation, host.newLine);
|
||||
|
||||
super(
|
||||
host,
|
||||
cancellationToken,
|
||||
useSingleInferredProject,
|
||||
typingsInstaller || nullTypingsInstaller,
|
||||
Buffer.byteLength,
|
||||
process.hrtime,
|
||||
logger,
|
||||
canUseEvents);
|
||||
|
||||
if (telemetryEnabled && typingsInstaller) {
|
||||
typingsInstaller.setTelemetrySender(this);
|
||||
}
|
||||
}
|
||||
|
||||
exit() {
|
||||
@ -538,17 +568,17 @@ namespace ts.server {
|
||||
|
||||
let eventPort: number;
|
||||
{
|
||||
const index = sys.args.indexOf("--eventPort");
|
||||
if (index >= 0 && index < sys.args.length - 1) {
|
||||
const v = parseInt(sys.args[index + 1]);
|
||||
if (!isNaN(v)) {
|
||||
eventPort = v;
|
||||
}
|
||||
const str = findArgument("--eventPort");
|
||||
const v = str && parseInt(str);
|
||||
if (!isNaN(v)) {
|
||||
eventPort = v;
|
||||
}
|
||||
}
|
||||
|
||||
const useSingleInferredProject = sys.args.indexOf("--useSingleInferredProject") >= 0;
|
||||
const disableAutomaticTypingAcquisition = sys.args.indexOf("--disableAutomaticTypingAcquisition") >= 0;
|
||||
const useSingleInferredProject = hasArgument("--useSingleInferredProject");
|
||||
const disableAutomaticTypingAcquisition = hasArgument("--disableAutomaticTypingAcquisition");
|
||||
const telemetryEnabled = hasArgument(Arguments.EnableTelemetry);
|
||||
|
||||
const ioSession = new IOSession(
|
||||
sys,
|
||||
cancellationToken,
|
||||
@ -557,6 +587,7 @@ namespace ts.server {
|
||||
useSingleInferredProject,
|
||||
disableAutomaticTypingAcquisition,
|
||||
getGlobalTypingsCacheLocation(),
|
||||
telemetryEnabled,
|
||||
logger);
|
||||
process.on("uncaughtException", function (err: Error) {
|
||||
ioSession.logError(err, "unknown");
|
||||
|
||||
@ -73,6 +73,10 @@ namespace ts.server {
|
||||
project: Project;
|
||||
}
|
||||
|
||||
export interface EventSender {
|
||||
event(payload: any, eventName: string): void;
|
||||
}
|
||||
|
||||
function allEditsBeforePos(edits: ts.TextChange[], pos: number) {
|
||||
for (const edit of edits) {
|
||||
if (textSpanEnd(edit.span) >= pos) {
|
||||
@ -165,7 +169,7 @@ namespace ts.server {
|
||||
return `Content-Length: ${1 + len}\r\n\r\n${json}${newLine}`;
|
||||
}
|
||||
|
||||
export class Session {
|
||||
export class Session implements EventSender {
|
||||
private readonly gcTimer: GcTimer;
|
||||
protected projectService: ProjectService;
|
||||
private errorTimer: any; /*NodeJS.Timer | number*/
|
||||
|
||||
24
src/server/shared.ts
Normal file
24
src/server/shared.ts
Normal file
@ -0,0 +1,24 @@
|
||||
/// <reference path="types.d.ts" />
|
||||
|
||||
namespace ts.server {
|
||||
export const ActionSet: ActionSet = "action::set";
|
||||
export const ActionInvalidate: ActionInvalidate = "action::invalidate";
|
||||
export const EventInstall: EventInstall = "event::install";
|
||||
|
||||
export namespace Arguments {
|
||||
export const GlobalCacheLocation = "--globalTypingsCacheLocation";
|
||||
export const LogFile = "--logFile";
|
||||
export const EnableTelemetry = "--enableTelemetry";
|
||||
}
|
||||
|
||||
export function hasArgument(argumentName: string) {
|
||||
return sys.args.indexOf(argumentName) >= 0;
|
||||
}
|
||||
|
||||
export function findArgument(argumentName: string) {
|
||||
const index = sys.args.indexOf(argumentName);
|
||||
return index >= 0 && index < sys.args.length - 1
|
||||
? sys.args[index + 1]
|
||||
: undefined;
|
||||
}
|
||||
}
|
||||
@ -18,6 +18,7 @@
|
||||
"files": [
|
||||
"../services/shims.ts",
|
||||
"../services/utilities.ts",
|
||||
"shared.ts",
|
||||
"utilities.ts",
|
||||
"scriptVersionCache.ts",
|
||||
"scriptInfo.ts",
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
"files": [
|
||||
"../services/shims.ts",
|
||||
"../services/utilities.ts",
|
||||
"shared.ts",
|
||||
"utilities.ts",
|
||||
"scriptVersionCache.ts",
|
||||
"scriptInfo.ts",
|
||||
|
||||
28
src/server/types.d.ts
vendored
28
src/server/types.d.ts
vendored
@ -41,28 +41,38 @@ declare namespace ts.server {
|
||||
readonly kind: "closeProject";
|
||||
}
|
||||
|
||||
export type SetRequest = "set";
|
||||
export type InvalidateRequest = "invalidate";
|
||||
export type ActionSet = "action::set";
|
||||
export type ActionInvalidate = "action::invalidate";
|
||||
export type EventInstall = "event::install";
|
||||
|
||||
export interface TypingInstallerResponse {
|
||||
readonly projectName: string;
|
||||
readonly kind: SetRequest | InvalidateRequest;
|
||||
readonly kind: ActionSet | ActionInvalidate | EventInstall;
|
||||
}
|
||||
|
||||
export interface SetTypings extends TypingInstallerResponse {
|
||||
export interface ProjectResponse extends TypingInstallerResponse {
|
||||
readonly projectName: string;
|
||||
}
|
||||
|
||||
export interface SetTypings extends ProjectResponse {
|
||||
readonly typingOptions: ts.TypingOptions;
|
||||
readonly compilerOptions: ts.CompilerOptions;
|
||||
readonly typings: string[];
|
||||
readonly unresolvedImports: SortedReadonlyArray<string>;
|
||||
readonly kind: SetRequest;
|
||||
readonly kind: ActionSet;
|
||||
}
|
||||
|
||||
export interface InvalidateCachedTypings extends TypingInstallerResponse {
|
||||
readonly kind: InvalidateRequest;
|
||||
export interface InvalidateCachedTypings extends ProjectResponse {
|
||||
readonly kind: ActionInvalidate;
|
||||
}
|
||||
|
||||
export interface TypingsInstallEvent extends TypingInstallerResponse {
|
||||
readonly packagesToInstall: ReadonlyArray<string>;
|
||||
readonly kind: EventInstall;
|
||||
}
|
||||
|
||||
export interface InstallTypingHost extends JsTyping.TypingResolutionHost {
|
||||
writeFile(path: string, content: string): void;
|
||||
createDirectory(path: string): void;
|
||||
watchFile?(path: string, callback: FileWatcherCallback): FileWatcher;
|
||||
watchFile?(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
}
|
||||
}
|
||||
@ -33,42 +33,81 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
type HttpGet = {
|
||||
(url: string, callback: (response: HttpResponse) => void): NodeJS.EventEmitter;
|
||||
};
|
||||
|
||||
interface HttpResponse extends NodeJS.ReadableStream {
|
||||
statusCode: number;
|
||||
statusMessage: string;
|
||||
destroy(): void;
|
||||
interface TypesRegistryFile {
|
||||
entries: MapLike<void>;
|
||||
}
|
||||
|
||||
function loadTypesRegistryFile(typesRegistryFilePath: string, host: InstallTypingHost, log: Log): Map<void> {
|
||||
if (!host.fileExists(typesRegistryFilePath)) {
|
||||
if (log.isEnabled()) {
|
||||
log.writeLine(`Types registry file '${typesRegistryFilePath}' does not exist`);
|
||||
}
|
||||
return createMap<void>();
|
||||
}
|
||||
try {
|
||||
const content = <TypesRegistryFile>JSON.parse(host.readFile(typesRegistryFilePath));
|
||||
return createMap<void>(content.entries);
|
||||
}
|
||||
catch (e) {
|
||||
if (log.isEnabled()) {
|
||||
log.writeLine(`Error when loading types registry file '${typesRegistryFilePath}': ${(<Error>e).message}, ${(<Error>e).stack}`);
|
||||
}
|
||||
return createMap<void>();
|
||||
}
|
||||
}
|
||||
|
||||
const TypesRegistryPackageName = "types-registry";
|
||||
function getTypesRegistryFileLocation(globalTypingsCacheLocation: string): string {
|
||||
return combinePaths(normalizeSlashes(globalTypingsCacheLocation), `node_modules/${TypesRegistryPackageName}/index.json`);
|
||||
}
|
||||
|
||||
|
||||
type Exec = {
|
||||
(command: string, options: { cwd: string }, callback?: (error: Error, stdout: string, stderr: string) => void): any
|
||||
};
|
||||
|
||||
type ExecSync = {
|
||||
(command: string, options: { cwd: string, stdio: "ignore" }): any
|
||||
};
|
||||
|
||||
export class NodeTypingsInstaller extends TypingsInstaller {
|
||||
private readonly exec: Exec;
|
||||
private readonly httpGet: HttpGet;
|
||||
private readonly npmPath: string;
|
||||
readonly installTypingHost: InstallTypingHost = sys;
|
||||
readonly typesRegistry: Map<void>;
|
||||
|
||||
constructor(globalTypingsCacheLocation: string, throttleLimit: number, log: Log) {
|
||||
constructor(globalTypingsCacheLocation: string, throttleLimit: number, telemetryEnabled: boolean, log: Log) {
|
||||
super(
|
||||
sys,
|
||||
globalTypingsCacheLocation,
|
||||
toPath("typingSafeList.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
|
||||
throttleLimit,
|
||||
telemetryEnabled,
|
||||
log);
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Process id: ${process.pid}`);
|
||||
}
|
||||
this.npmPath = getNPMLocation(process.argv[0]);
|
||||
this.exec = require("child_process").exec;
|
||||
this.httpGet = require("http").get;
|
||||
let execSync: ExecSync;
|
||||
({ exec: this.exec, execSync } = require("child_process"));
|
||||
|
||||
this.ensurePackageDirectoryExists(globalTypingsCacheLocation);
|
||||
|
||||
try {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Updating ${TypesRegistryPackageName} npm package...`);
|
||||
}
|
||||
execSync(`${this.npmPath} install ${TypesRegistryPackageName}`, { cwd: globalTypingsCacheLocation, stdio: "ignore" });
|
||||
}
|
||||
catch (e) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Error updating ${TypesRegistryPackageName} package: ${(<Error>e).message}`);
|
||||
}
|
||||
}
|
||||
|
||||
this.typesRegistry = loadTypesRegistryFile(getTypesRegistryFileLocation(globalTypingsCacheLocation), this.installTypingHost, this.log);
|
||||
}
|
||||
|
||||
init() {
|
||||
super.init();
|
||||
listen() {
|
||||
process.on("message", (req: DiscoverTypings | CloseProject) => {
|
||||
switch (req.kind) {
|
||||
case "discover":
|
||||
@ -90,66 +129,26 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
protected executeRequest(requestKind: RequestKind, requestId: number, args: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void {
|
||||
protected installWorker(requestId: number, args: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`#${requestId} executing ${requestKind}, arguments'${JSON.stringify(args)}'.`);
|
||||
}
|
||||
switch (requestKind) {
|
||||
case NpmViewRequest: {
|
||||
// const command = `${self.npmPath} view @types/${typing} --silent name`;
|
||||
// use http request to global npm registry instead of running npm view
|
||||
Debug.assert(args.length === 1);
|
||||
const url = `http://registry.npmjs.org/@types%2f${args[0]}`;
|
||||
const start = Date.now();
|
||||
this.httpGet(url, response => {
|
||||
let ok = false;
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`${requestKind} #${requestId} request to ${url}:: status code ${response.statusCode}, status message '${response.statusMessage}', took ${Date.now() - start} ms`);
|
||||
}
|
||||
switch (response.statusCode) {
|
||||
case 200: // OK
|
||||
case 301: // redirect - Moved - treat package as present
|
||||
case 302: // redirect - Found - treat package as present
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
response.destroy();
|
||||
onRequestCompleted(ok);
|
||||
}).on("error", (err: Error) => {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`${requestKind} #${requestId} query to npm registry failed with error ${err.message}, stack ${err.stack}`);
|
||||
}
|
||||
onRequestCompleted(/*success*/ false);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case NpmInstallRequest: {
|
||||
const command = `${this.npmPath} install ${args.join(" ")} --save-dev`;
|
||||
const start = Date.now();
|
||||
this.exec(command, { cwd }, (_err, stdout, stderr) => {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`${requestKind} #${requestId} took: ${Date.now() - start} ms${sys.newLine}stdout: ${stdout}${sys.newLine}stderr: ${stderr}`);
|
||||
}
|
||||
// treat any output on stdout as success
|
||||
onRequestCompleted(!!stdout);
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Debug.assert(false, `Unknown request kind ${requestKind}`);
|
||||
this.log.writeLine(`#${requestId} with arguments'${JSON.stringify(args)}'.`);
|
||||
}
|
||||
const command = `${this.npmPath} install ${args.join(" ")} --save-dev`;
|
||||
const start = Date.now();
|
||||
this.exec(command, { cwd }, (_err, stdout, stderr) => {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`npm install #${requestId} took: ${Date.now() - start} ms${sys.newLine}stdout: ${stdout}${sys.newLine}stderr: ${stderr}`);
|
||||
}
|
||||
// treat any output on stdout as success
|
||||
onRequestCompleted(!!stdout);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function findArgument(argumentName: string) {
|
||||
const index = sys.args.indexOf(argumentName);
|
||||
return index >= 0 && index < sys.args.length - 1
|
||||
? sys.args[index + 1]
|
||||
: undefined;
|
||||
}
|
||||
const logFilePath = findArgument(server.Arguments.LogFile);
|
||||
const globalTypingsCacheLocation = findArgument(server.Arguments.GlobalCacheLocation);
|
||||
const telemetryEnabled = hasArgument(server.Arguments.EnableTelemetry);
|
||||
|
||||
const logFilePath = findArgument("--logFile");
|
||||
const globalTypingsCacheLocation = findArgument("--globalTypingsCacheLocation");
|
||||
const log = new FileLog(logFilePath);
|
||||
if (log.isEnabled()) {
|
||||
process.on("uncaughtException", (e: Error) => {
|
||||
@ -162,6 +161,6 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
process.exit(0);
|
||||
});
|
||||
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, /*throttleLimit*/5, log);
|
||||
installer.init();
|
||||
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, /*throttleLimit*/5, telemetryEnabled, log);
|
||||
installer.listen();
|
||||
}
|
||||
@ -17,6 +17,7 @@
|
||||
},
|
||||
"files": [
|
||||
"../types.d.ts",
|
||||
"../shared.ts",
|
||||
"typingsInstaller.ts",
|
||||
"nodeTypingsInstaller.ts"
|
||||
]
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
/// <reference path="../../compiler/moduleNameResolver.ts" />
|
||||
/// <reference path="../../services/jsTyping.ts"/>
|
||||
/// <reference path="../types.d.ts"/>
|
||||
/// <reference path="../shared.ts"/>
|
||||
|
||||
namespace ts.server.typingsInstaller {
|
||||
interface NpmConfig {
|
||||
@ -63,18 +64,12 @@ namespace ts.server.typingsInstaller {
|
||||
return PackageNameValidationResult.Ok;
|
||||
}
|
||||
|
||||
export const NpmViewRequest: "npm view" = "npm view";
|
||||
export const NpmInstallRequest: "npm install" = "npm install";
|
||||
|
||||
export type RequestKind = typeof NpmViewRequest | typeof NpmInstallRequest;
|
||||
|
||||
export type RequestCompletedAction = (success: boolean) => void;
|
||||
type PendingRequest = {
|
||||
requestKind: RequestKind;
|
||||
requestId: number;
|
||||
args: string[];
|
||||
cwd: string;
|
||||
onRequestCompleted: RequestCompletedAction
|
||||
onRequestCompleted: RequestCompletedAction;
|
||||
};
|
||||
|
||||
export abstract class TypingsInstaller {
|
||||
@ -87,19 +82,18 @@ namespace ts.server.typingsInstaller {
|
||||
private installRunCount = 1;
|
||||
private inFlightRequestCount = 0;
|
||||
|
||||
abstract readonly installTypingHost: InstallTypingHost;
|
||||
abstract readonly typesRegistry: Map<void>;
|
||||
|
||||
constructor(
|
||||
readonly installTypingHost: InstallTypingHost,
|
||||
readonly globalCachePath: string,
|
||||
readonly safeListPath: Path,
|
||||
readonly throttleLimit: number,
|
||||
readonly telemetryEnabled: boolean,
|
||||
protected readonly log = nullLog) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Global cache location '${globalCachePath}', safe file path '${safeListPath}'`);
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
this.processCacheLocation(this.globalCachePath);
|
||||
}
|
||||
|
||||
@ -224,7 +218,7 @@ namespace ts.server.typingsInstaller {
|
||||
this.knownCachesSet[cacheLocation] = true;
|
||||
}
|
||||
|
||||
private filterTypings(typingsToInstall: string[]) {
|
||||
private filterAndMapToScopedName(typingsToInstall: string[]) {
|
||||
if (typingsToInstall.length === 0) {
|
||||
return typingsToInstall;
|
||||
}
|
||||
@ -235,7 +229,14 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
const validationResult = validatePackageName(typing);
|
||||
if (validationResult === PackageNameValidationResult.Ok) {
|
||||
result.push(typing);
|
||||
if (typing in this.typesRegistry) {
|
||||
result.push(`@types/${typing}`);
|
||||
}
|
||||
else {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Entry for package '${typing}' does not exist in local types registry - skipping...`);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// add typing name to missing set so we won't process it again
|
||||
@ -267,19 +268,8 @@ namespace ts.server.typingsInstaller {
|
||||
return result;
|
||||
}
|
||||
|
||||
private installTypings(req: DiscoverTypings, cachePath: string, currentlyCachedTypings: string[], typingsToInstall: string[]) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Installing typings ${JSON.stringify(typingsToInstall)}`);
|
||||
}
|
||||
typingsToInstall = this.filterTypings(typingsToInstall);
|
||||
if (typingsToInstall.length === 0) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`All typings are known to be missing or invalid - no need to go any further`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const npmConfigPath = combinePaths(cachePath, "package.json");
|
||||
protected ensurePackageDirectoryExists(directory: string) {
|
||||
const npmConfigPath = combinePaths(directory, "package.json");
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Npm config file: ${npmConfigPath}`);
|
||||
}
|
||||
@ -287,23 +277,50 @@ namespace ts.server.typingsInstaller {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Npm config file: '${npmConfigPath}' is missing, creating new one...`);
|
||||
}
|
||||
this.ensureDirectoryExists(cachePath, this.installTypingHost);
|
||||
this.ensureDirectoryExists(directory, this.installTypingHost);
|
||||
this.installTypingHost.writeFile(npmConfigPath, "{}");
|
||||
}
|
||||
}
|
||||
|
||||
private installTypings(req: DiscoverTypings, cachePath: string, currentlyCachedTypings: string[], typingsToInstall: string[]) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Installing typings ${JSON.stringify(typingsToInstall)}`);
|
||||
}
|
||||
const scopedTypings = this.filterAndMapToScopedName(typingsToInstall);
|
||||
if (scopedTypings.length === 0) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`All typings are known to be missing or invalid - no need to go any further`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this.ensurePackageDirectoryExists(cachePath);
|
||||
|
||||
const requestId = this.installRunCount;
|
||||
this.installRunCount++;
|
||||
|
||||
this.installTypingsAsync(requestId, scopedTypings, cachePath, ok => {
|
||||
if (this.telemetryEnabled) {
|
||||
this.sendResponse(<TypingsInstallEvent>{
|
||||
kind: EventInstall,
|
||||
packagesToInstall: scopedTypings
|
||||
});
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.runInstall(cachePath, typingsToInstall, installedTypings => {
|
||||
// TODO: watch project directory
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Requested to install typings ${JSON.stringify(typingsToInstall)}, installed typings ${JSON.stringify(installedTypings)}`);
|
||||
this.log.writeLine(`Requested to install typings ${JSON.stringify(scopedTypings)}, installed typings ${JSON.stringify(scopedTypings)}`);
|
||||
}
|
||||
const installedPackages: Map<true> = createMap<true>();
|
||||
const installedTypingFiles: string[] = [];
|
||||
for (const t of installedTypings) {
|
||||
for (const t of scopedTypings) {
|
||||
const packageName = getBaseFileName(t);
|
||||
if (!packageName) {
|
||||
continue;
|
||||
}
|
||||
installedPackages[packageName] = true;
|
||||
const typingFile = typingToFileName(cachePath, packageName, this.installTypingHost);
|
||||
if (!typingFile) {
|
||||
continue;
|
||||
@ -316,53 +333,11 @@ namespace ts.server.typingsInstaller {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Installed typing files ${JSON.stringify(installedTypingFiles)}`);
|
||||
}
|
||||
for (const toInstall of typingsToInstall) {
|
||||
if (!installedPackages[toInstall]) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`New missing typing package '${toInstall}'`);
|
||||
}
|
||||
this.missingTypingsSet[toInstall] = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.sendResponse(this.createSetTypings(req, currentlyCachedTypings.concat(installedTypingFiles)));
|
||||
});
|
||||
}
|
||||
|
||||
private runInstall(cachePath: string, typingsToInstall: string[], postInstallAction: (installedTypings: string[]) => void): void {
|
||||
const requestId = this.installRunCount;
|
||||
|
||||
this.installRunCount++;
|
||||
let execInstallCmdCount = 0;
|
||||
const filteredTypings: string[] = [];
|
||||
for (const typing of typingsToInstall) {
|
||||
filterExistingTypings(this, typing);
|
||||
}
|
||||
|
||||
function filterExistingTypings(self: TypingsInstaller, typing: string) {
|
||||
self.execAsync(NpmViewRequest, requestId, [typing], cachePath, ok => {
|
||||
if (ok) {
|
||||
filteredTypings.push(typing);
|
||||
}
|
||||
execInstallCmdCount++;
|
||||
if (execInstallCmdCount === typingsToInstall.length) {
|
||||
installFilteredTypings(self, filteredTypings);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function installFilteredTypings(self: TypingsInstaller, filteredTypings: string[]) {
|
||||
if (filteredTypings.length === 0) {
|
||||
postInstallAction([]);
|
||||
return;
|
||||
}
|
||||
const scopedTypings = filteredTypings.map(t => "@types/" + t);
|
||||
self.execAsync(NpmInstallRequest, requestId, scopedTypings, cachePath, ok => {
|
||||
postInstallAction(ok ? scopedTypings : []);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private ensureDirectoryExists(directory: string, host: InstallTypingHost): void {
|
||||
const directoryName = getDirectoryPath(directory);
|
||||
if (!host.directoryExists(directoryName)) {
|
||||
@ -389,10 +364,10 @@ namespace ts.server.typingsInstaller {
|
||||
this.log.writeLine(`Got FS notification for ${f}, handler is already invoked '${isInvoked}'`);
|
||||
}
|
||||
if (!isInvoked) {
|
||||
this.sendResponse({ projectName: projectName, kind: "invalidate" });
|
||||
this.sendResponse({ projectName: projectName, kind: server.ActionInvalidate });
|
||||
isInvoked = true;
|
||||
}
|
||||
});
|
||||
}, /*pollingInterval*/ 2000);
|
||||
watchers.push(w);
|
||||
}
|
||||
this.projectWatchers[projectName] = watchers;
|
||||
@ -405,12 +380,12 @@ namespace ts.server.typingsInstaller {
|
||||
compilerOptions: request.compilerOptions,
|
||||
typings,
|
||||
unresolvedImports: request.unresolvedImports,
|
||||
kind: "set"
|
||||
kind: ActionSet
|
||||
};
|
||||
}
|
||||
|
||||
private execAsync(requestKind: RequestKind, requestId: number, args: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void {
|
||||
this.pendingRunRequests.unshift({ requestKind, requestId, args, cwd, onRequestCompleted });
|
||||
private installTypingsAsync(requestId: number, args: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void {
|
||||
this.pendingRunRequests.unshift({ requestId, args, cwd, onRequestCompleted });
|
||||
this.executeWithThrottling();
|
||||
}
|
||||
|
||||
@ -418,7 +393,7 @@ namespace ts.server.typingsInstaller {
|
||||
while (this.inFlightRequestCount < this.throttleLimit && this.pendingRunRequests.length) {
|
||||
this.inFlightRequestCount++;
|
||||
const request = this.pendingRunRequests.pop();
|
||||
this.executeRequest(request.requestKind, request.requestId, request.args, request.cwd, ok => {
|
||||
this.installWorker(request.requestId, request.args, request.cwd, ok => {
|
||||
this.inFlightRequestCount--;
|
||||
request.onRequestCompleted(ok);
|
||||
this.executeWithThrottling();
|
||||
@ -426,7 +401,7 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract executeRequest(requestKind: RequestKind, requestId: number, args: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void;
|
||||
protected abstract sendResponse(response: SetTypings | InvalidateCachedTypings): void;
|
||||
protected abstract installWorker(requestId: number, args: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void;
|
||||
protected abstract sendResponse(response: SetTypings | InvalidateCachedTypings | TypingsInstallEvent): void;
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
/// <reference path="types.d.ts" />
|
||||
/// <reference path="shared.ts" />
|
||||
|
||||
namespace ts.server {
|
||||
export enum LogLevel {
|
||||
@ -10,6 +11,7 @@ namespace ts.server {
|
||||
|
||||
export const emptyArray: ReadonlyArray<any> = [];
|
||||
|
||||
|
||||
export interface Logger {
|
||||
close(): void;
|
||||
hasLevel(level: LogLevel): boolean;
|
||||
@ -48,7 +50,7 @@ namespace ts.server {
|
||||
export function createInstallTypingsRequest(project: Project, typingOptions: TypingOptions, unresolvedImports: SortedReadonlyArray<string>, cachePath?: string): DiscoverTypings {
|
||||
return {
|
||||
projectName: project.getProjectName(),
|
||||
fileNames: project.getFileNames(),
|
||||
fileNames: project.getFileNames(/*excludeFilesFromExternalLibraries*/ true),
|
||||
compilerOptions: project.getCompilerOptions(),
|
||||
typingOptions,
|
||||
unresolvedImports,
|
||||
|
||||
@ -264,7 +264,7 @@ namespace ts.BreakpointResolver {
|
||||
// a or ...c or d: x from
|
||||
// [a, b, ...c] or { a, b } or { d: x } from destructuring pattern
|
||||
if ((node.kind === SyntaxKind.Identifier ||
|
||||
node.kind == SyntaxKind.SpreadElementExpression ||
|
||||
node.kind == SyntaxKind.SpreadElement ||
|
||||
node.kind === SyntaxKind.PropertyAssignment ||
|
||||
node.kind === SyntaxKind.ShorthandPropertyAssignment) &&
|
||||
isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
|
||||
|
||||
@ -88,7 +88,7 @@ namespace ts.JsTyping {
|
||||
exclude = typingOptions.exclude || [];
|
||||
|
||||
const possibleSearchDirs = map(fileNames, getDirectoryPath);
|
||||
if (projectRootPath !== undefined) {
|
||||
if (projectRootPath) {
|
||||
possibleSearchDirs.push(projectRootPath);
|
||||
}
|
||||
searchDirs = deduplicate(possibleSearchDirs);
|
||||
|
||||
@ -48,7 +48,6 @@ namespace ts {
|
||||
public jsDocComments: JSDoc[];
|
||||
public original: Node;
|
||||
public transformFlags: TransformFlags;
|
||||
public excludeTransformFlags: TransformFlags;
|
||||
private _children: Node[];
|
||||
|
||||
constructor(kind: SyntaxKind, pos: number, end: number) {
|
||||
@ -56,7 +55,6 @@ namespace ts {
|
||||
this.end = end;
|
||||
this.flags = NodeFlags.None;
|
||||
this.transformFlags = undefined;
|
||||
this.excludeTransformFlags = undefined;
|
||||
this.parent = undefined;
|
||||
this.kind = kind;
|
||||
}
|
||||
|
||||
@ -1266,6 +1266,6 @@ namespace TypeScript.Services {
|
||||
// TODO: it should be moved into a namespace though.
|
||||
|
||||
/* @internal */
|
||||
const toolsVersion = "2.1";
|
||||
const toolsVersion = "2.2";
|
||||
|
||||
/* tslint:enable:no-unused-variable */
|
||||
|
||||
@ -557,7 +557,9 @@ namespace ts.SignatureHelp {
|
||||
addRange(prefixDisplayParts, callTargetDisplayParts);
|
||||
}
|
||||
|
||||
let isVariadic: boolean;
|
||||
if (isTypeParameterList) {
|
||||
isVariadic = false; // type parameter lists are not variadic
|
||||
prefixDisplayParts.push(punctuationPart(SyntaxKind.LessThanToken));
|
||||
const typeParameters = candidateSignature.typeParameters;
|
||||
signatureHelpParameters = typeParameters && typeParameters.length > 0 ? map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray;
|
||||
@ -567,6 +569,7 @@ namespace ts.SignatureHelp {
|
||||
addRange(suffixDisplayParts, parameterParts);
|
||||
}
|
||||
else {
|
||||
isVariadic = candidateSignature.hasRestParameter;
|
||||
const typeParameterParts = mapToDisplayParts(writer =>
|
||||
typeChecker.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, invocation));
|
||||
addRange(prefixDisplayParts, typeParameterParts);
|
||||
@ -582,7 +585,7 @@ namespace ts.SignatureHelp {
|
||||
addRange(suffixDisplayParts, returnTypeParts);
|
||||
|
||||
return {
|
||||
isVariadic: candidateSignature.hasRestParameter,
|
||||
isVariadic,
|
||||
prefixDisplayParts,
|
||||
suffixDisplayParts,
|
||||
separatorDisplayParts: [punctuationPart(SyntaxKind.CommaToken), spacePart()],
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
"../compiler/visitor.ts",
|
||||
"../compiler/transformers/ts.ts",
|
||||
"../compiler/transformers/jsx.ts",
|
||||
"../compiler/transformers/esnext.ts",
|
||||
"../compiler/transformers/es2017.ts",
|
||||
"../compiler/transformers/es2016.ts",
|
||||
"../compiler/transformers/es2015.ts",
|
||||
|
||||
@ -530,8 +530,8 @@ namespace ts {
|
||||
case SyntaxKind.DeleteExpression:
|
||||
case SyntaxKind.VoidExpression:
|
||||
case SyntaxKind.YieldExpression:
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
const unaryWordExpression = (<TypeOfExpression | DeleteExpression | VoidExpression | YieldExpression | SpreadElementExpression>n);
|
||||
case SyntaxKind.SpreadElement:
|
||||
const unaryWordExpression = n as (TypeOfExpression | DeleteExpression | VoidExpression | YieldExpression | SpreadElement);
|
||||
return isCompletedNode(unaryWordExpression.expression, sourceFile);
|
||||
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
|
||||
8
tests/baselines/reference/alwaysStrictModule3.js
Normal file
8
tests/baselines/reference/alwaysStrictModule3.js
Normal file
@ -0,0 +1,8 @@
|
||||
//// [alwaysStrictModule3.ts]
|
||||
|
||||
// module ES2015
|
||||
export const a = 1;
|
||||
|
||||
//// [alwaysStrictModule3.js]
|
||||
// module ES2015
|
||||
export var a = 1;
|
||||
6
tests/baselines/reference/alwaysStrictModule3.symbols
Normal file
6
tests/baselines/reference/alwaysStrictModule3.symbols
Normal file
@ -0,0 +1,6 @@
|
||||
=== tests/cases/compiler/alwaysStrictModule3.ts ===
|
||||
|
||||
// module ES2015
|
||||
export const a = 1;
|
||||
>a : Symbol(a, Decl(alwaysStrictModule3.ts, 2, 12))
|
||||
|
||||
7
tests/baselines/reference/alwaysStrictModule3.types
Normal file
7
tests/baselines/reference/alwaysStrictModule3.types
Normal file
@ -0,0 +1,7 @@
|
||||
=== tests/cases/compiler/alwaysStrictModule3.ts ===
|
||||
|
||||
// module ES2015
|
||||
export const a = 1;
|
||||
>a : 1
|
||||
>1 : 1
|
||||
|
||||
9
tests/baselines/reference/alwaysStrictModule4.js
Normal file
9
tests/baselines/reference/alwaysStrictModule4.js
Normal file
@ -0,0 +1,9 @@
|
||||
//// [alwaysStrictModule4.ts]
|
||||
|
||||
// Module commonjs
|
||||
export const a = 1
|
||||
|
||||
//// [alwaysStrictModule4.js]
|
||||
"use strict";
|
||||
// Module commonjs
|
||||
exports.a = 1;
|
||||
6
tests/baselines/reference/alwaysStrictModule4.symbols
Normal file
6
tests/baselines/reference/alwaysStrictModule4.symbols
Normal file
@ -0,0 +1,6 @@
|
||||
=== tests/cases/compiler/alwaysStrictModule4.ts ===
|
||||
|
||||
// Module commonjs
|
||||
export const a = 1
|
||||
>a : Symbol(a, Decl(alwaysStrictModule4.ts, 2, 12))
|
||||
|
||||
7
tests/baselines/reference/alwaysStrictModule4.types
Normal file
7
tests/baselines/reference/alwaysStrictModule4.types
Normal file
@ -0,0 +1,7 @@
|
||||
=== tests/cases/compiler/alwaysStrictModule4.ts ===
|
||||
|
||||
// Module commonjs
|
||||
export const a = 1
|
||||
>a : 1
|
||||
>1 : 1
|
||||
|
||||
8
tests/baselines/reference/alwaysStrictModule5.js
Normal file
8
tests/baselines/reference/alwaysStrictModule5.js
Normal file
@ -0,0 +1,8 @@
|
||||
//// [alwaysStrictModule5.ts]
|
||||
|
||||
// Targeting ES6
|
||||
export const a = 1;
|
||||
|
||||
//// [alwaysStrictModule5.js]
|
||||
// Targeting ES6
|
||||
export const a = 1;
|
||||
6
tests/baselines/reference/alwaysStrictModule5.symbols
Normal file
6
tests/baselines/reference/alwaysStrictModule5.symbols
Normal file
@ -0,0 +1,6 @@
|
||||
=== tests/cases/compiler/alwaysStrictModule5.ts ===
|
||||
|
||||
// Targeting ES6
|
||||
export const a = 1;
|
||||
>a : Symbol(a, Decl(alwaysStrictModule5.ts, 2, 12))
|
||||
|
||||
7
tests/baselines/reference/alwaysStrictModule5.types
Normal file
7
tests/baselines/reference/alwaysStrictModule5.types
Normal file
@ -0,0 +1,7 @@
|
||||
=== tests/cases/compiler/alwaysStrictModule5.ts ===
|
||||
|
||||
// Targeting ES6
|
||||
export const a = 1;
|
||||
>a : 1
|
||||
>1 : 1
|
||||
|
||||
9
tests/baselines/reference/alwaysStrictModule6.js
Normal file
9
tests/baselines/reference/alwaysStrictModule6.js
Normal file
@ -0,0 +1,9 @@
|
||||
//// [alwaysStrictModule6.ts]
|
||||
|
||||
// Targeting ES5
|
||||
export const a = 1;
|
||||
|
||||
//// [alwaysStrictModule6.js]
|
||||
"use strict";
|
||||
// Targeting ES5
|
||||
exports.a = 1;
|
||||
6
tests/baselines/reference/alwaysStrictModule6.symbols
Normal file
6
tests/baselines/reference/alwaysStrictModule6.symbols
Normal file
@ -0,0 +1,6 @@
|
||||
=== tests/cases/compiler/alwaysStrictModule6.ts ===
|
||||
|
||||
// Targeting ES5
|
||||
export const a = 1;
|
||||
>a : Symbol(a, Decl(alwaysStrictModule6.ts, 2, 12))
|
||||
|
||||
7
tests/baselines/reference/alwaysStrictModule6.types
Normal file
7
tests/baselines/reference/alwaysStrictModule6.types
Normal file
@ -0,0 +1,7 @@
|
||||
=== tests/cases/compiler/alwaysStrictModule6.ts ===
|
||||
|
||||
// Targeting ES5
|
||||
export const a = 1;
|
||||
>a : 1
|
||||
>1 : 1
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
//// [callWithSpread.ts]
|
||||
interface X {
|
||||
foo(x: number, y: number, ...z: string[]);
|
||||
foo(x: number, y: number, ...z: string[]): X;
|
||||
}
|
||||
|
||||
function foo(x: number, y: number, ...z: string[]) {
|
||||
@ -19,10 +19,18 @@ obj.foo(1, 2, "abc");
|
||||
obj.foo(1, 2, ...a);
|
||||
obj.foo(1, 2, ...a, "abc");
|
||||
|
||||
obj.foo(1, 2, ...a).foo(1, 2, "abc");
|
||||
obj.foo(1, 2, ...a).foo(1, 2, ...a);
|
||||
obj.foo(1, 2, ...a).foo(1, 2, ...a, "abc");
|
||||
|
||||
(obj.foo)(1, 2, "abc");
|
||||
(obj.foo)(1, 2, ...a);
|
||||
(obj.foo)(1, 2, ...a, "abc");
|
||||
|
||||
((obj.foo)(1, 2, ...a).foo)(1, 2, "abc");
|
||||
((obj.foo)(1, 2, ...a).foo)(1, 2, ...a);
|
||||
((obj.foo)(1, 2, ...a).foo)(1, 2, ...a, "abc");
|
||||
|
||||
xa[1].foo(1, 2, "abc");
|
||||
xa[1].foo(1, 2, ...a);
|
||||
xa[1].foo(1, 2, ...a, "abc");
|
||||
@ -72,13 +80,19 @@ foo.apply(void 0, [1, 2].concat(a, ["abc"]));
|
||||
obj.foo(1, 2, "abc");
|
||||
obj.foo.apply(obj, [1, 2].concat(a));
|
||||
obj.foo.apply(obj, [1, 2].concat(a, ["abc"]));
|
||||
obj.foo.apply(obj, [1, 2].concat(a)).foo(1, 2, "abc");
|
||||
(_a = obj.foo.apply(obj, [1, 2].concat(a))).foo.apply(_a, [1, 2].concat(a));
|
||||
(_b = obj.foo.apply(obj, [1, 2].concat(a))).foo.apply(_b, [1, 2].concat(a, ["abc"]));
|
||||
(obj.foo)(1, 2, "abc");
|
||||
obj.foo.apply(obj, [1, 2].concat(a));
|
||||
obj.foo.apply(obj, [1, 2].concat(a, ["abc"]));
|
||||
(obj.foo.apply(obj, [1, 2].concat(a)).foo)(1, 2, "abc");
|
||||
(_c = obj.foo.apply(obj, [1, 2].concat(a))).foo.apply(_c, [1, 2].concat(a));
|
||||
(_d = obj.foo.apply(obj, [1, 2].concat(a))).foo.apply(_d, [1, 2].concat(a, ["abc"]));
|
||||
xa[1].foo(1, 2, "abc");
|
||||
(_a = xa[1]).foo.apply(_a, [1, 2].concat(a));
|
||||
(_b = xa[1]).foo.apply(_b, [1, 2].concat(a, ["abc"]));
|
||||
(_c = xa[1]).foo.apply(_c, [1, 2, "abc"]);
|
||||
(_e = xa[1]).foo.apply(_e, [1, 2].concat(a));
|
||||
(_f = xa[1]).foo.apply(_f, [1, 2].concat(a, ["abc"]));
|
||||
(_g = xa[1]).foo.apply(_g, [1, 2, "abc"]);
|
||||
var C = (function () {
|
||||
function C(x, y) {
|
||||
var z = [];
|
||||
@ -109,4 +123,4 @@ var D = (function (_super) {
|
||||
};
|
||||
return D;
|
||||
}(C));
|
||||
var _a, _b, _c;
|
||||
var _a, _b, _c, _d, _e, _f, _g;
|
||||
|
||||
@ -2,11 +2,12 @@
|
||||
interface X {
|
||||
>X : Symbol(X, Decl(callWithSpread.ts, 0, 0))
|
||||
|
||||
foo(x: number, y: number, ...z: string[]);
|
||||
foo(x: number, y: number, ...z: string[]): X;
|
||||
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>x : Symbol(x, Decl(callWithSpread.ts, 1, 8))
|
||||
>y : Symbol(y, Decl(callWithSpread.ts, 1, 18))
|
||||
>z : Symbol(z, Decl(callWithSpread.ts, 1, 29))
|
||||
>X : Symbol(X, Decl(callWithSpread.ts, 0, 0))
|
||||
}
|
||||
|
||||
function foo(x: number, y: number, ...z: string[]) {
|
||||
@ -58,6 +59,32 @@ obj.foo(1, 2, ...a, "abc");
|
||||
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))
|
||||
|
||||
obj.foo(1, 2, ...a).foo(1, 2, "abc");
|
||||
>obj.foo(1, 2, ...a).foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>obj.foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>obj : Symbol(obj, Decl(callWithSpread.ts, 9, 3))
|
||||
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))
|
||||
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
|
||||
obj.foo(1, 2, ...a).foo(1, 2, ...a);
|
||||
>obj.foo(1, 2, ...a).foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>obj.foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>obj : Symbol(obj, Decl(callWithSpread.ts, 9, 3))
|
||||
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))
|
||||
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))
|
||||
|
||||
obj.foo(1, 2, ...a).foo(1, 2, ...a, "abc");
|
||||
>obj.foo(1, 2, ...a).foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>obj.foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>obj : Symbol(obj, Decl(callWithSpread.ts, 9, 3))
|
||||
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))
|
||||
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))
|
||||
|
||||
(obj.foo)(1, 2, "abc");
|
||||
>obj.foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>obj : Symbol(obj, Decl(callWithSpread.ts, 9, 3))
|
||||
@ -75,6 +102,32 @@ obj.foo(1, 2, ...a, "abc");
|
||||
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))
|
||||
|
||||
((obj.foo)(1, 2, ...a).foo)(1, 2, "abc");
|
||||
>(obj.foo)(1, 2, ...a).foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>obj.foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>obj : Symbol(obj, Decl(callWithSpread.ts, 9, 3))
|
||||
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))
|
||||
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
|
||||
((obj.foo)(1, 2, ...a).foo)(1, 2, ...a);
|
||||
>(obj.foo)(1, 2, ...a).foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>obj.foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>obj : Symbol(obj, Decl(callWithSpread.ts, 9, 3))
|
||||
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))
|
||||
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))
|
||||
|
||||
((obj.foo)(1, 2, ...a).foo)(1, 2, ...a, "abc");
|
||||
>(obj.foo)(1, 2, ...a).foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>obj.foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>obj : Symbol(obj, Decl(callWithSpread.ts, 9, 3))
|
||||
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))
|
||||
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))
|
||||
|
||||
xa[1].foo(1, 2, "abc");
|
||||
>xa[1].foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
>xa : Symbol(xa, Decl(callWithSpread.ts, 10, 3))
|
||||
@ -99,60 +152,60 @@ xa[1].foo(1, 2, ...a, "abc");
|
||||
>foo : Symbol(X.foo, Decl(callWithSpread.ts, 0, 13))
|
||||
|
||||
class C {
|
||||
>C : Symbol(C, Decl(callWithSpread.ts, 28, 40))
|
||||
>C : Symbol(C, Decl(callWithSpread.ts, 36, 40))
|
||||
|
||||
constructor(x: number, y: number, ...z: string[]) {
|
||||
>x : Symbol(x, Decl(callWithSpread.ts, 31, 16))
|
||||
>y : Symbol(y, Decl(callWithSpread.ts, 31, 26))
|
||||
>z : Symbol(z, Decl(callWithSpread.ts, 31, 37))
|
||||
>x : Symbol(x, Decl(callWithSpread.ts, 39, 16))
|
||||
>y : Symbol(y, Decl(callWithSpread.ts, 39, 26))
|
||||
>z : Symbol(z, Decl(callWithSpread.ts, 39, 37))
|
||||
|
||||
this.foo(x, y);
|
||||
>this.foo : Symbol(C.foo, Decl(callWithSpread.ts, 34, 5))
|
||||
>this : Symbol(C, Decl(callWithSpread.ts, 28, 40))
|
||||
>foo : Symbol(C.foo, Decl(callWithSpread.ts, 34, 5))
|
||||
>x : Symbol(x, Decl(callWithSpread.ts, 31, 16))
|
||||
>y : Symbol(y, Decl(callWithSpread.ts, 31, 26))
|
||||
>this.foo : Symbol(C.foo, Decl(callWithSpread.ts, 42, 5))
|
||||
>this : Symbol(C, Decl(callWithSpread.ts, 36, 40))
|
||||
>foo : Symbol(C.foo, Decl(callWithSpread.ts, 42, 5))
|
||||
>x : Symbol(x, Decl(callWithSpread.ts, 39, 16))
|
||||
>y : Symbol(y, Decl(callWithSpread.ts, 39, 26))
|
||||
|
||||
this.foo(x, y, ...z);
|
||||
>this.foo : Symbol(C.foo, Decl(callWithSpread.ts, 34, 5))
|
||||
>this : Symbol(C, Decl(callWithSpread.ts, 28, 40))
|
||||
>foo : Symbol(C.foo, Decl(callWithSpread.ts, 34, 5))
|
||||
>x : Symbol(x, Decl(callWithSpread.ts, 31, 16))
|
||||
>y : Symbol(y, Decl(callWithSpread.ts, 31, 26))
|
||||
>z : Symbol(z, Decl(callWithSpread.ts, 31, 37))
|
||||
>this.foo : Symbol(C.foo, Decl(callWithSpread.ts, 42, 5))
|
||||
>this : Symbol(C, Decl(callWithSpread.ts, 36, 40))
|
||||
>foo : Symbol(C.foo, Decl(callWithSpread.ts, 42, 5))
|
||||
>x : Symbol(x, Decl(callWithSpread.ts, 39, 16))
|
||||
>y : Symbol(y, Decl(callWithSpread.ts, 39, 26))
|
||||
>z : Symbol(z, Decl(callWithSpread.ts, 39, 37))
|
||||
}
|
||||
foo(x: number, y: number, ...z: string[]) {
|
||||
>foo : Symbol(C.foo, Decl(callWithSpread.ts, 34, 5))
|
||||
>x : Symbol(x, Decl(callWithSpread.ts, 35, 8))
|
||||
>y : Symbol(y, Decl(callWithSpread.ts, 35, 18))
|
||||
>z : Symbol(z, Decl(callWithSpread.ts, 35, 29))
|
||||
>foo : Symbol(C.foo, Decl(callWithSpread.ts, 42, 5))
|
||||
>x : Symbol(x, Decl(callWithSpread.ts, 43, 8))
|
||||
>y : Symbol(y, Decl(callWithSpread.ts, 43, 18))
|
||||
>z : Symbol(z, Decl(callWithSpread.ts, 43, 29))
|
||||
}
|
||||
}
|
||||
|
||||
class D extends C {
|
||||
>D : Symbol(D, Decl(callWithSpread.ts, 37, 1))
|
||||
>C : Symbol(C, Decl(callWithSpread.ts, 28, 40))
|
||||
>D : Symbol(D, Decl(callWithSpread.ts, 45, 1))
|
||||
>C : Symbol(C, Decl(callWithSpread.ts, 36, 40))
|
||||
|
||||
constructor() {
|
||||
super(1, 2);
|
||||
>super : Symbol(C, Decl(callWithSpread.ts, 28, 40))
|
||||
>super : Symbol(C, Decl(callWithSpread.ts, 36, 40))
|
||||
|
||||
super(1, 2, ...a);
|
||||
>super : Symbol(C, Decl(callWithSpread.ts, 28, 40))
|
||||
>super : Symbol(C, Decl(callWithSpread.ts, 36, 40))
|
||||
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))
|
||||
}
|
||||
foo() {
|
||||
>foo : Symbol(D.foo, Decl(callWithSpread.ts, 43, 5))
|
||||
>foo : Symbol(D.foo, Decl(callWithSpread.ts, 51, 5))
|
||||
|
||||
super.foo(1, 2);
|
||||
>super.foo : Symbol(C.foo, Decl(callWithSpread.ts, 34, 5))
|
||||
>super : Symbol(C, Decl(callWithSpread.ts, 28, 40))
|
||||
>foo : Symbol(C.foo, Decl(callWithSpread.ts, 34, 5))
|
||||
>super.foo : Symbol(C.foo, Decl(callWithSpread.ts, 42, 5))
|
||||
>super : Symbol(C, Decl(callWithSpread.ts, 36, 40))
|
||||
>foo : Symbol(C.foo, Decl(callWithSpread.ts, 42, 5))
|
||||
|
||||
super.foo(1, 2, ...a);
|
||||
>super.foo : Symbol(C.foo, Decl(callWithSpread.ts, 34, 5))
|
||||
>super : Symbol(C, Decl(callWithSpread.ts, 28, 40))
|
||||
>foo : Symbol(C.foo, Decl(callWithSpread.ts, 34, 5))
|
||||
>super.foo : Symbol(C.foo, Decl(callWithSpread.ts, 42, 5))
|
||||
>super : Symbol(C, Decl(callWithSpread.ts, 36, 40))
|
||||
>foo : Symbol(C.foo, Decl(callWithSpread.ts, 42, 5))
|
||||
>a : Symbol(a, Decl(callWithSpread.ts, 7, 3))
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,11 +2,12 @@
|
||||
interface X {
|
||||
>X : X
|
||||
|
||||
foo(x: number, y: number, ...z: string[]);
|
||||
>foo : (x: number, y: number, ...z: string[]) => any
|
||||
foo(x: number, y: number, ...z: string[]): X;
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>x : number
|
||||
>y : number
|
||||
>z : string[]
|
||||
>X : X
|
||||
}
|
||||
|
||||
function foo(x: number, y: number, ...z: string[]) {
|
||||
@ -55,29 +56,80 @@ foo(1, 2, ...a, "abc");
|
||||
>"abc" : "abc"
|
||||
|
||||
obj.foo(1, 2, "abc");
|
||||
>obj.foo(1, 2, "abc") : any
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => any
|
||||
>obj.foo(1, 2, "abc") : X
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => X
|
||||
>obj : X
|
||||
>foo : (x: number, y: number, ...z: string[]) => any
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>"abc" : "abc"
|
||||
|
||||
obj.foo(1, 2, ...a);
|
||||
>obj.foo(1, 2, ...a) : any
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => any
|
||||
>obj.foo(1, 2, ...a) : X
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => X
|
||||
>obj : X
|
||||
>foo : (x: number, y: number, ...z: string[]) => any
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>...a : string
|
||||
>a : string[]
|
||||
|
||||
obj.foo(1, 2, ...a, "abc");
|
||||
>obj.foo(1, 2, ...a, "abc") : any
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => any
|
||||
>obj.foo(1, 2, ...a, "abc") : X
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => X
|
||||
>obj : X
|
||||
>foo : (x: number, y: number, ...z: string[]) => any
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>...a : string
|
||||
>a : string[]
|
||||
>"abc" : "abc"
|
||||
|
||||
obj.foo(1, 2, ...a).foo(1, 2, "abc");
|
||||
>obj.foo(1, 2, ...a).foo(1, 2, "abc") : X
|
||||
>obj.foo(1, 2, ...a).foo : (x: number, y: number, ...z: string[]) => X
|
||||
>obj.foo(1, 2, ...a) : X
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => X
|
||||
>obj : X
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>...a : string
|
||||
>a : string[]
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>"abc" : "abc"
|
||||
|
||||
obj.foo(1, 2, ...a).foo(1, 2, ...a);
|
||||
>obj.foo(1, 2, ...a).foo(1, 2, ...a) : X
|
||||
>obj.foo(1, 2, ...a).foo : (x: number, y: number, ...z: string[]) => X
|
||||
>obj.foo(1, 2, ...a) : X
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => X
|
||||
>obj : X
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>...a : string
|
||||
>a : string[]
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>...a : string
|
||||
>a : string[]
|
||||
|
||||
obj.foo(1, 2, ...a).foo(1, 2, ...a, "abc");
|
||||
>obj.foo(1, 2, ...a).foo(1, 2, ...a, "abc") : X
|
||||
>obj.foo(1, 2, ...a).foo : (x: number, y: number, ...z: string[]) => X
|
||||
>obj.foo(1, 2, ...a) : X
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => X
|
||||
>obj : X
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>...a : string
|
||||
>a : string[]
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>...a : string
|
||||
@ -85,32 +137,89 @@ obj.foo(1, 2, ...a, "abc");
|
||||
>"abc" : "abc"
|
||||
|
||||
(obj.foo)(1, 2, "abc");
|
||||
>(obj.foo)(1, 2, "abc") : any
|
||||
>(obj.foo) : (x: number, y: number, ...z: string[]) => any
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => any
|
||||
>(obj.foo)(1, 2, "abc") : X
|
||||
>(obj.foo) : (x: number, y: number, ...z: string[]) => X
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => X
|
||||
>obj : X
|
||||
>foo : (x: number, y: number, ...z: string[]) => any
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>"abc" : "abc"
|
||||
|
||||
(obj.foo)(1, 2, ...a);
|
||||
>(obj.foo)(1, 2, ...a) : any
|
||||
>(obj.foo) : (x: number, y: number, ...z: string[]) => any
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => any
|
||||
>(obj.foo)(1, 2, ...a) : X
|
||||
>(obj.foo) : (x: number, y: number, ...z: string[]) => X
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => X
|
||||
>obj : X
|
||||
>foo : (x: number, y: number, ...z: string[]) => any
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>...a : string
|
||||
>a : string[]
|
||||
|
||||
(obj.foo)(1, 2, ...a, "abc");
|
||||
>(obj.foo)(1, 2, ...a, "abc") : any
|
||||
>(obj.foo) : (x: number, y: number, ...z: string[]) => any
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => any
|
||||
>(obj.foo)(1, 2, ...a, "abc") : X
|
||||
>(obj.foo) : (x: number, y: number, ...z: string[]) => X
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => X
|
||||
>obj : X
|
||||
>foo : (x: number, y: number, ...z: string[]) => any
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>...a : string
|
||||
>a : string[]
|
||||
>"abc" : "abc"
|
||||
|
||||
((obj.foo)(1, 2, ...a).foo)(1, 2, "abc");
|
||||
>((obj.foo)(1, 2, ...a).foo)(1, 2, "abc") : X
|
||||
>((obj.foo)(1, 2, ...a).foo) : (x: number, y: number, ...z: string[]) => X
|
||||
>(obj.foo)(1, 2, ...a).foo : (x: number, y: number, ...z: string[]) => X
|
||||
>(obj.foo)(1, 2, ...a) : X
|
||||
>(obj.foo) : (x: number, y: number, ...z: string[]) => X
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => X
|
||||
>obj : X
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>...a : string
|
||||
>a : string[]
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>"abc" : "abc"
|
||||
|
||||
((obj.foo)(1, 2, ...a).foo)(1, 2, ...a);
|
||||
>((obj.foo)(1, 2, ...a).foo)(1, 2, ...a) : X
|
||||
>((obj.foo)(1, 2, ...a).foo) : (x: number, y: number, ...z: string[]) => X
|
||||
>(obj.foo)(1, 2, ...a).foo : (x: number, y: number, ...z: string[]) => X
|
||||
>(obj.foo)(1, 2, ...a) : X
|
||||
>(obj.foo) : (x: number, y: number, ...z: string[]) => X
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => X
|
||||
>obj : X
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>...a : string
|
||||
>a : string[]
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>...a : string
|
||||
>a : string[]
|
||||
|
||||
((obj.foo)(1, 2, ...a).foo)(1, 2, ...a, "abc");
|
||||
>((obj.foo)(1, 2, ...a).foo)(1, 2, ...a, "abc") : X
|
||||
>((obj.foo)(1, 2, ...a).foo) : (x: number, y: number, ...z: string[]) => X
|
||||
>(obj.foo)(1, 2, ...a).foo : (x: number, y: number, ...z: string[]) => X
|
||||
>(obj.foo)(1, 2, ...a) : X
|
||||
>(obj.foo) : (x: number, y: number, ...z: string[]) => X
|
||||
>obj.foo : (x: number, y: number, ...z: string[]) => X
|
||||
>obj : X
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>...a : string
|
||||
>a : string[]
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>...a : string
|
||||
@ -118,35 +227,35 @@ obj.foo(1, 2, ...a, "abc");
|
||||
>"abc" : "abc"
|
||||
|
||||
xa[1].foo(1, 2, "abc");
|
||||
>xa[1].foo(1, 2, "abc") : any
|
||||
>xa[1].foo : (x: number, y: number, ...z: string[]) => any
|
||||
>xa[1].foo(1, 2, "abc") : X
|
||||
>xa[1].foo : (x: number, y: number, ...z: string[]) => X
|
||||
>xa[1] : X
|
||||
>xa : X[]
|
||||
>1 : 1
|
||||
>foo : (x: number, y: number, ...z: string[]) => any
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>"abc" : "abc"
|
||||
|
||||
xa[1].foo(1, 2, ...a);
|
||||
>xa[1].foo(1, 2, ...a) : any
|
||||
>xa[1].foo : (x: number, y: number, ...z: string[]) => any
|
||||
>xa[1].foo(1, 2, ...a) : X
|
||||
>xa[1].foo : (x: number, y: number, ...z: string[]) => X
|
||||
>xa[1] : X
|
||||
>xa : X[]
|
||||
>1 : 1
|
||||
>foo : (x: number, y: number, ...z: string[]) => any
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>...a : string
|
||||
>a : string[]
|
||||
|
||||
xa[1].foo(1, 2, ...a, "abc");
|
||||
>xa[1].foo(1, 2, ...a, "abc") : any
|
||||
>xa[1].foo : (x: number, y: number, ...z: string[]) => any
|
||||
>xa[1].foo(1, 2, ...a, "abc") : X
|
||||
>xa[1].foo : (x: number, y: number, ...z: string[]) => X
|
||||
>xa[1] : X
|
||||
>xa : X[]
|
||||
>1 : 1
|
||||
>foo : (x: number, y: number, ...z: string[]) => any
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>...a : string
|
||||
@ -158,11 +267,11 @@ xa[1].foo(1, 2, ...a, "abc");
|
||||
>(<Function>xa[1].foo) : Function
|
||||
><Function>xa[1].foo : Function
|
||||
>Function : Function
|
||||
>xa[1].foo : (x: number, y: number, ...z: string[]) => any
|
||||
>xa[1].foo : (x: number, y: number, ...z: string[]) => X
|
||||
>xa[1] : X
|
||||
>xa : X[]
|
||||
>1 : 1
|
||||
>foo : (x: number, y: number, ...z: string[]) => any
|
||||
>foo : (x: number, y: number, ...z: string[]) => X
|
||||
>...[1, 2, "abc"] : string | number
|
||||
>[1, 2, "abc"] : (string | number)[]
|
||||
>1 : 1
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
EmitSkipped: true
|
||||
Diagnostics:
|
||||
Cannot write file '/tests/cases/fourslash/b.js' because it would overwrite input file.
|
||||
Cannot write file '/tests/cases/fourslash/b.js' because it would overwrite input file.
|
||||
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
|
||||
|
||||
EmitSkipped: false
|
||||
FileName : /tests/cases/fourslash/a.js
|
||||
|
||||
@ -12,4 +12,4 @@ exports.y = function (x) { return 1; };
|
||||
//// [declarationEmitTypeAliasWithTypeParameters1.d.ts]
|
||||
export declare type Bar<X, Y> = () => [X, Y];
|
||||
export declare type Foo<Y> = Bar<any, Y>;
|
||||
export declare const y: (x: () => [any, string]) => number;
|
||||
export declare const y: (x: Bar<any, string>) => number;
|
||||
|
||||
@ -8,15 +8,15 @@ export type Bar<X, Y> = () => [X, Y];
|
||||
>Y : Y
|
||||
|
||||
export type Foo<Y> = Bar<any, Y>;
|
||||
>Foo : () => [any, Y]
|
||||
>Foo : Bar<any, Y>
|
||||
>Y : Y
|
||||
>Bar : Bar<X, Y>
|
||||
>Y : Y
|
||||
|
||||
export const y = (x: Foo<string>) => 1
|
||||
>y : (x: () => [any, string]) => number
|
||||
>(x: Foo<string>) => 1 : (x: () => [any, string]) => number
|
||||
>x : () => [any, string]
|
||||
>Foo : () => [any, Y]
|
||||
>y : (x: Bar<any, string>) => number
|
||||
>(x: Foo<string>) => 1 : (x: Bar<any, string>) => number
|
||||
>x : Bar<any, string>
|
||||
>Foo : Bar<any, Y>
|
||||
>1 : 1
|
||||
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
//// [declarationEmitTypeAliasWithTypeParameters2.ts]
|
||||
|
||||
export type Bar<X, Y, Z> = () => [X, Y, Z];
|
||||
export type Baz<M, N> = Bar<M, string, N>;
|
||||
export type Baa<Y> = Baz<boolean, Y>;
|
||||
export const y = (x: Baa<number>) => 1
|
||||
|
||||
//// [declarationEmitTypeAliasWithTypeParameters2.js]
|
||||
"use strict";
|
||||
exports.y = function (x) { return 1; };
|
||||
|
||||
|
||||
//// [declarationEmitTypeAliasWithTypeParameters2.d.ts]
|
||||
export declare type Bar<X, Y, Z> = () => [X, Y, Z];
|
||||
export declare type Baz<M, N> = Bar<M, string, N>;
|
||||
export declare type Baa<Y> = Baz<boolean, Y>;
|
||||
export declare const y: (x: Bar<boolean, string, number>) => number;
|
||||
@ -0,0 +1,30 @@
|
||||
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===
|
||||
|
||||
export type Bar<X, Y, Z> = () => [X, Y, Z];
|
||||
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
|
||||
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
|
||||
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
|
||||
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))
|
||||
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
|
||||
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
|
||||
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))
|
||||
|
||||
export type Baz<M, N> = Bar<M, string, N>;
|
||||
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
|
||||
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
|
||||
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))
|
||||
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
|
||||
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
|
||||
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))
|
||||
|
||||
export type Baa<Y> = Baz<boolean, Y>;
|
||||
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))
|
||||
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))
|
||||
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
|
||||
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))
|
||||
|
||||
export const y = (x: Baa<number>) => 1
|
||||
>y : Symbol(y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 12))
|
||||
>x : Symbol(x, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 18))
|
||||
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===
|
||||
|
||||
export type Bar<X, Y, Z> = () => [X, Y, Z];
|
||||
>Bar : Bar<X, Y, Z>
|
||||
>X : X
|
||||
>Y : Y
|
||||
>Z : Z
|
||||
>X : X
|
||||
>Y : Y
|
||||
>Z : Z
|
||||
|
||||
export type Baz<M, N> = Bar<M, string, N>;
|
||||
>Baz : Bar<M, string, N>
|
||||
>M : M
|
||||
>N : N
|
||||
>Bar : Bar<X, Y, Z>
|
||||
>M : M
|
||||
>N : N
|
||||
|
||||
export type Baa<Y> = Baz<boolean, Y>;
|
||||
>Baa : Bar<boolean, string, Y>
|
||||
>Y : Y
|
||||
>Baz : Bar<M, string, N>
|
||||
>Y : Y
|
||||
|
||||
export const y = (x: Baa<number>) => 1
|
||||
>y : (x: Bar<boolean, string, number>) => number
|
||||
>(x: Baa<number>) => 1 : (x: Bar<boolean, string, number>) => number
|
||||
>x : Bar<boolean, string, number>
|
||||
>Baa : Bar<boolean, string, Y>
|
||||
>1 : 1
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
//// [declarationEmitTypeAliasWithTypeParameters3.ts]
|
||||
|
||||
type Foo<T> = {
|
||||
foo<U>(): Foo<U>
|
||||
};
|
||||
function bar() {
|
||||
return {} as Foo<number>;
|
||||
}
|
||||
|
||||
|
||||
//// [declarationEmitTypeAliasWithTypeParameters3.js]
|
||||
function bar() {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
//// [declarationEmitTypeAliasWithTypeParameters3.d.ts]
|
||||
declare type Foo<T> = {
|
||||
foo<U>(): Foo<U>;
|
||||
};
|
||||
declare function bar(): Foo<number>;
|
||||
@ -0,0 +1,20 @@
|
||||
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===
|
||||
|
||||
type Foo<T> = {
|
||||
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 9))
|
||||
|
||||
foo<U>(): Foo<U>
|
||||
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 15))
|
||||
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))
|
||||
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
|
||||
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))
|
||||
|
||||
};
|
||||
function bar() {
|
||||
>bar : Symbol(bar, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 3, 2))
|
||||
|
||||
return {} as Foo<number>;
|
||||
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
|
||||
}
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===
|
||||
|
||||
type Foo<T> = {
|
||||
>Foo : Foo<T>
|
||||
>T : T
|
||||
|
||||
foo<U>(): Foo<U>
|
||||
>foo : <U>() => Foo<U>
|
||||
>U : U
|
||||
>Foo : Foo<T>
|
||||
>U : U
|
||||
|
||||
};
|
||||
function bar() {
|
||||
>bar : () => Foo<number>
|
||||
|
||||
return {} as Foo<number>;
|
||||
>{} as Foo<number> : Foo<number>
|
||||
>{} : {}
|
||||
>Foo : Foo<T>
|
||||
}
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
//// [declarationEmitTypeAliasWithTypeParameters4.ts]
|
||||
|
||||
type Foo<T, Y> = {
|
||||
foo<U, J>(): Foo<U, J>
|
||||
};
|
||||
type SubFoo<R> = Foo<string, R>;
|
||||
|
||||
function foo() {
|
||||
return {} as SubFoo<number>;
|
||||
}
|
||||
|
||||
|
||||
//// [declarationEmitTypeAliasWithTypeParameters4.js]
|
||||
function foo() {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
//// [declarationEmitTypeAliasWithTypeParameters4.d.ts]
|
||||
declare type Foo<T, Y> = {
|
||||
foo<U, J>(): Foo<U, J>;
|
||||
};
|
||||
declare type SubFoo<R> = Foo<string, R>;
|
||||
declare function foo(): Foo<string, number>;
|
||||
@ -0,0 +1,29 @@
|
||||
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===
|
||||
|
||||
type Foo<T, Y> = {
|
||||
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 9))
|
||||
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 11))
|
||||
|
||||
foo<U, J>(): Foo<U, J>
|
||||
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 18))
|
||||
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
|
||||
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))
|
||||
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
|
||||
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
|
||||
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))
|
||||
|
||||
};
|
||||
type SubFoo<R> = Foo<string, R>;
|
||||
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
|
||||
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))
|
||||
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
|
||||
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))
|
||||
|
||||
function foo() {
|
||||
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 32))
|
||||
|
||||
return {} as SubFoo<number>;
|
||||
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
|
||||
}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===
|
||||
|
||||
type Foo<T, Y> = {
|
||||
>Foo : Foo<T, Y>
|
||||
>T : T
|
||||
>Y : Y
|
||||
|
||||
foo<U, J>(): Foo<U, J>
|
||||
>foo : <U, J>() => Foo<U, J>
|
||||
>U : U
|
||||
>J : J
|
||||
>Foo : Foo<T, Y>
|
||||
>U : U
|
||||
>J : J
|
||||
|
||||
};
|
||||
type SubFoo<R> = Foo<string, R>;
|
||||
>SubFoo : Foo<string, R>
|
||||
>R : R
|
||||
>Foo : Foo<T, Y>
|
||||
>R : R
|
||||
|
||||
function foo() {
|
||||
>foo : () => Foo<string, number>
|
||||
|
||||
return {} as SubFoo<number>;
|
||||
>{} as SubFoo<number> : Foo<string, number>
|
||||
>{} : {}
|
||||
>SubFoo : Foo<string, R>
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts(5,25): error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts (1 errors) ====
|
||||
|
||||
type Foo<T, Y> = {
|
||||
foo<U, J>(): Foo<U, J>
|
||||
};
|
||||
export type SubFoo<R> = Foo<string, R>;
|
||||
~~~
|
||||
!!! error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.
|
||||
|
||||
function foo() {
|
||||
return {} as SubFoo<number>;
|
||||
}
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
//// [declarationEmitTypeAliasWithTypeParameters5.ts]
|
||||
|
||||
type Foo<T, Y> = {
|
||||
foo<U, J>(): Foo<U, J>
|
||||
};
|
||||
export type SubFoo<R> = Foo<string, R>;
|
||||
|
||||
function foo() {
|
||||
return {} as SubFoo<number>;
|
||||
}
|
||||
|
||||
|
||||
//// [declarationEmitTypeAliasWithTypeParameters5.js]
|
||||
"use strict";
|
||||
function foo() {
|
||||
return {};
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
//// [declarationEmitTypeAliasWithTypeParameters6.ts]
|
||||
|
||||
type Foo<T, Y> = {
|
||||
foo<U, J>(): Foo<U, J>
|
||||
};
|
||||
type SubFoo<R, S> = Foo<S, R>;
|
||||
|
||||
function foo() {
|
||||
return {} as SubFoo<number, string>;
|
||||
}
|
||||
|
||||
|
||||
//// [declarationEmitTypeAliasWithTypeParameters6.js]
|
||||
function foo() {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
//// [declarationEmitTypeAliasWithTypeParameters6.d.ts]
|
||||
declare type Foo<T, Y> = {
|
||||
foo<U, J>(): Foo<U, J>;
|
||||
};
|
||||
declare type SubFoo<R, S> = Foo<S, R>;
|
||||
declare function foo(): Foo<string, number>;
|
||||
@ -0,0 +1,31 @@
|
||||
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters6.ts ===
|
||||
|
||||
type Foo<T, Y> = {
|
||||
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 9))
|
||||
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 11))
|
||||
|
||||
foo<U, J>(): Foo<U, J>
|
||||
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 18))
|
||||
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
|
||||
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))
|
||||
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
|
||||
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
|
||||
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))
|
||||
|
||||
};
|
||||
type SubFoo<R, S> = Foo<S, R>;
|
||||
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
|
||||
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))
|
||||
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
|
||||
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
|
||||
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
|
||||
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))
|
||||
|
||||
function foo() {
|
||||
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 30))
|
||||
|
||||
return {} as SubFoo<number, string>;
|
||||
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
|
||||
}
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters6.ts ===
|
||||
|
||||
type Foo<T, Y> = {
|
||||
>Foo : Foo<T, Y>
|
||||
>T : T
|
||||
>Y : Y
|
||||
|
||||
foo<U, J>(): Foo<U, J>
|
||||
>foo : <U, J>() => Foo<U, J>
|
||||
>U : U
|
||||
>J : J
|
||||
>Foo : Foo<T, Y>
|
||||
>U : U
|
||||
>J : J
|
||||
|
||||
};
|
||||
type SubFoo<R, S> = Foo<S, R>;
|
||||
>SubFoo : Foo<S, R>
|
||||
>R : R
|
||||
>S : S
|
||||
>Foo : Foo<T, Y>
|
||||
>S : S
|
||||
>R : R
|
||||
|
||||
function foo() {
|
||||
>foo : () => Foo<string, number>
|
||||
|
||||
return {} as SubFoo<number, string>;
|
||||
>{} as SubFoo<number, string> : Foo<string, number>
|
||||
>{} : {}
|
||||
>SubFoo : Foo<S, R>
|
||||
}
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
error TS5055: Cannot write file 'tests/cases/compiler/a.d.ts' because it would overwrite input file.
|
||||
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
|
||||
|
||||
|
||||
!!! error TS5055: Cannot write file 'tests/cases/compiler/a.d.ts' because it would overwrite input file.
|
||||
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
|
||||
==== tests/cases/compiler/a.d.ts (0 errors) ====
|
||||
|
||||
declare class c {
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
error TS5055: Cannot write file 'tests/cases/compiler/out.d.ts' because it would overwrite input file.
|
||||
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
|
||||
|
||||
|
||||
!!! error TS5055: Cannot write file 'tests/cases/compiler/out.d.ts' because it would overwrite input file.
|
||||
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig
|
||||
==== tests/cases/compiler/out.d.ts (0 errors) ====
|
||||
|
||||
declare class c {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user