mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-11 10:00:13 -06:00
Merge branch 'master' into es5-emit-param-initialiser-before-object-rest
This commit is contained in:
commit
24852b6be4
1
.gitignore
vendored
1
.gitignore
vendored
@ -57,3 +57,4 @@ internal/
|
||||
!tests/cases/projects/NodeModulesSearch/**/*
|
||||
!tests/baselines/reference/project/nodeModules*/**/*
|
||||
.idea
|
||||
yarn.lock
|
||||
29
.mailmap
29
.mailmap
@ -1,13 +1,14 @@
|
||||
|
||||
AbubakerB <abubaker_bashir@hotmail.com> # Abubaker Bashir
|
||||
Alexander <alexander@kuvaev.me># Alexander Kuvaev
|
||||
Aluan Haddad <aluanh@gmail.com>
|
||||
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>
|
||||
Anders Hejlsberg <andersh@microsoft.com> unknown <andersh@AndersX1.NOE.Nokia.com> unknown <andersh@andersh-yoga.redmond.corp.microsoft.com> Anders Hejlsberg <Anders Hejlsberg>
|
||||
about-code <about-code@users.noreply.github.com> # Andreas Martin
|
||||
Andrej Baran <andrej.baran@gmail.com>
|
||||
Andrew Ochsner <andrew.ochsner@wipro.com>
|
||||
@ -24,6 +25,7 @@ Basarat Ali Syed <basaratali@gmail.com> Basarat Syed <basaratali@gmail.com> basa
|
||||
Bill Ticehurst <billti@hotmail.com> Bill Ticehurst <billti@microsoft.com>
|
||||
Ben Duffield <jebavarde@gmail.com>
|
||||
Ben Mosher <me@benmosher.com>
|
||||
Benjamin Bock <bb@users.noreply.github.com>
|
||||
Blake Embrey <hello@blakeembrey.com>
|
||||
Bowden Kelly <wilkelly@microsoft.com>
|
||||
Brett Mayen <bmayen@midnightsnacks.net>
|
||||
@ -49,6 +51,7 @@ 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>
|
||||
Erik McClenney <erikmcc@google.com>
|
||||
erictsangx <erictsangx@gmail.com> # Eric Tsang
|
||||
Ethan Rubio <ethanrubio@users.noreply.github.com>
|
||||
Evan Martin <martine@danga.com>
|
||||
@ -68,13 +71,18 @@ Guillaume Salles <guillaume.salles@me.com>
|
||||
Guy Bedford <guybedford@gmail.com> guybedford <guybedford@gmail.com>
|
||||
Harald Niesche <harald@niesche.de>
|
||||
Homa Wong <homawong@gmail.com>
|
||||
Hendrik Liebau <mail@hendrik-liebau.de>
|
||||
Iain Monro <iain.monro@softwire.com>
|
||||
IgorNovozhilov <maildrakon@gmail.com> # Igor Novozhilov
|
||||
Ingvar Stepanyan <me@rreverser.com>
|
||||
impinball <impinball@gmail.com> # Isiah Meadows
|
||||
Iwata Hidetaka <iwata0303@gmail.com>
|
||||
Ivo Gabe de Wolff <ivogabe@ivogabe.nl>
|
||||
Jakub Młokosiewicz <hckr@users.noreply.github.com>
|
||||
James Whitney <james@whitney.io>
|
||||
James Henry <james@henry.sc>
|
||||
Jason Freeman <jfreeman@microsoft.com> Jason Freeman <JsonFreeman@users.noreply.github.com>
|
||||
Jason Jarrett <jason@elegantcode.com>
|
||||
Jason Killian <jkillian@palantir.com>
|
||||
Jason Ramsay <jasonra@microsoft.com> jramsay <jramsay@users.noreply.github.com>
|
||||
Jed Mao <jed.hunsaker@gmail.com>
|
||||
@ -89,6 +97,7 @@ Jonathan Toland <toland@dnalot.com>
|
||||
Jesse Schalken <me@jesseschalken.com>
|
||||
Joel Day <joelday@gmail.com>
|
||||
Josh Abernathy <joshaber@gmail.com> joshaber <joshaber@gmail.com>
|
||||
Josh Goldberg <joshuakgoldberg@outlook.com>
|
||||
Josh Kalderimis <josh.kalderimis@gmail.com>
|
||||
Josh Soref <jsoref@users.noreply.github.com>
|
||||
Juan Luis Boya García <ntrrgc@gmail.com>
|
||||
@ -107,20 +116,26 @@ 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
|
||||
Kitson Kelly <me@kitsonkelly.com>
|
||||
Klaus Meinhardt <klaus.meinhardt1@gmail.com>
|
||||
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>
|
||||
Magnus Hiie <magnus.hiie@gmail.com>
|
||||
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>
|
||||
Matt McCutchen <rmccutch@mit.edu> Matt McCutchen <matt@mattmccutchen.net>
|
||||
Matt Bierner <matb@microsoft.com>
|
||||
MANISH-GIRI <manish.giri.me@gmail.com> # Manish Giri
|
||||
Max Deepfield <maxdeepfield@absolutefreakout.com>
|
||||
Micah Zoltu <micah@zoltu.net>
|
||||
Michael <maykelchiche@gmail.com>
|
||||
Mike Busyrev <busyrev@gmail.com>
|
||||
Mine Starks <minestarks@users.noreply.github.com> Mine Starks <mineyalc@microsoft.com>
|
||||
Mohamed Hegazy <mhegazy@microsoft.com>
|
||||
ncoley <nrcoley@gmail.com> # Natalie Coley
|
||||
Nathan Shively-Sanders <nathansa@microsoft.com>
|
||||
Nathan Yee <ny.nathan.yee@gmail.com>
|
||||
Nima Zahedi <nima.zahedee@gmail.com>
|
||||
@ -143,12 +158,14 @@ Rado Kirov <radokirov@google.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>
|
||||
Richard Karmazín <richard@karmazin.cz>
|
||||
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>
|
||||
chico <chi187@gmail.com> # Sergey Rubanov
|
||||
Sheetal Nandi <shkamat@microsoft.com>
|
||||
Shengping Zhong <zhongsp@users.noreply.github.com>
|
||||
shyyko.serhiy@gmail.com <shyyko.serhiy@gmail.com> # Shyyko Serhiy
|
||||
@ -156,6 +173,7 @@ Sam El-Husseini <samelh@microsoft.com>
|
||||
Simon Hürlimann <simon.huerlimann@cyt.ch>
|
||||
Slawomir Sadziak <slsadzia@microsoft.com>
|
||||
Solal Pirelli <solal.pirelli@gmail.com>
|
||||
Soo Jae Hwang <misoguy1985@gmail.com>
|
||||
Stan Thomas <stmsdn@norvil.net>
|
||||
Stanislav Sysoev <d4rkr00t@gmail.com>
|
||||
Steve Lucco <steveluc@users.noreply.github.com> steveluc <steveluc@microsoft.com>
|
||||
@ -173,6 +191,7 @@ 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>
|
||||
Vadi Taslim <vadz77@hotmail.com>
|
||||
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>
|
||||
@ -199,6 +218,7 @@ Aliaksandr Radzivanovich <aradzivanovich@gmail.com>
|
||||
BuildTools <FranklinWhale@users.noreply.github.com> # Franklin Tse
|
||||
ChogyDan <danielhollocher@gmail.com> # Daniel Hollocher
|
||||
Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com> Daniel Rosenwasser <drosen@microsoft.com>
|
||||
DLehenbauer <DLehenbauer@users.noreply.github.com> # Daniel Lehenbauer
|
||||
David Kmenta <david.kmenta@lmc.eu>
|
||||
E020873 <nicolas.henry-partner@arcelormittal.com> # Nicolas Henry
|
||||
Elisée Maurer <elisee@sparklinlabs.com>
|
||||
@ -225,4 +245,7 @@ Viktor Zozulyak <zozulyakviktor@gmail.com>
|
||||
rix <rix@rixs-MacBook-Pro.local> # Richard Sentino
|
||||
rohitverma007 <rohitverma@live.ca> # Rohit Verma
|
||||
rdosanjh <me@rajdeep.io> # Raj Dosanjh
|
||||
gdh1995 <gdh1995@qq.com> # Dahan Gong
|
||||
gdh1995 <gdh1995@qq.com> # Dahan Gong
|
||||
cedvdb <cedvandenbosch@gmail.com> # @cedvdb
|
||||
kpreisser <kpreisser@users.noreply.github.com> # K. Preißer
|
||||
e-cloud <saintscott119@gmail.com> # @e-cloud
|
||||
@ -17,6 +17,7 @@ branches:
|
||||
only:
|
||||
- master
|
||||
- release-2.1
|
||||
- release-2.2
|
||||
|
||||
install:
|
||||
- npm uninstall typescript
|
||||
|
||||
23
AUTHORS.md
23
AUTHORS.md
@ -10,6 +10,7 @@ TypeScript is authored by:
|
||||
* Alexander Rusakov
|
||||
* Ali Sabzevari
|
||||
* Aliaksandr Radzivanovich
|
||||
* Aluan Haddad
|
||||
* Anatoly Ressin
|
||||
* Anders Hejlsberg
|
||||
* Andreas Martin
|
||||
@ -29,6 +30,7 @@ TypeScript is authored by:
|
||||
* Basarat Ali Syed
|
||||
* Ben Duffield
|
||||
* Ben Mosher
|
||||
* Benjamin Bock
|
||||
* Bill Ticehurst
|
||||
* Blake Embrey
|
||||
* @bootstraponline
|
||||
@ -36,6 +38,7 @@ TypeScript is authored by:
|
||||
* Brett Mayen
|
||||
* Bryan Forbes
|
||||
* Caitlin Potter
|
||||
* @cedvdb
|
||||
* Charly POLY
|
||||
* Chris Bubernak
|
||||
* Christophe Vidal
|
||||
@ -49,6 +52,7 @@ TypeScript is authored by:
|
||||
* Dan Corder
|
||||
* Dan Quirk
|
||||
* Daniel Hollocher
|
||||
* Daniel Lehenbauer
|
||||
* Daniel Rosenwasser
|
||||
* David Kmenta
|
||||
* David Li
|
||||
@ -60,10 +64,12 @@ TypeScript is authored by:
|
||||
* Dirk Holtwick
|
||||
* Dom Chen
|
||||
* Doug Ilijev
|
||||
* @e-cloud
|
||||
* Elisée Maurer
|
||||
* Emilio García-Pumarino
|
||||
* Eric Tsang
|
||||
* Erik Edrosa
|
||||
* Erik McClenney
|
||||
* Ethan Resnick
|
||||
* Ethan Rubio
|
||||
* Evan Martin
|
||||
@ -84,15 +90,20 @@ TypeScript is authored by:
|
||||
* Guillaume Salles
|
||||
* Guy Bedford
|
||||
* Harald Niesche
|
||||
* Hendrik Liebau
|
||||
* Herrington Darkholme
|
||||
* Homa Wong
|
||||
* Iain Monro
|
||||
* Igor Novozhilov
|
||||
* Ingvar Stepanyan
|
||||
* Isiah Meadows
|
||||
* Ivo Gabe de Wolff
|
||||
* Iwata Hidetaka
|
||||
* Jakub Młokosiewicz
|
||||
* James Henry
|
||||
* James Whitney
|
||||
* Jason Freeman
|
||||
* Jason Jarrett
|
||||
* Jason Killian
|
||||
* Jason Ramsay
|
||||
* JBerger
|
||||
@ -110,29 +121,34 @@ TypeScript is authored by:
|
||||
* Jonathan Turner
|
||||
* Jonathon Smith
|
||||
* Josh Abernathy
|
||||
* Josh Goldberg
|
||||
* Josh Kalderimis
|
||||
* Josh Soref
|
||||
* Juan Luis Boya García
|
||||
* Julian Williams
|
||||
* Justin Bay
|
||||
* Justin Johansson
|
||||
* K. Preißer
|
||||
* Kagami Sascha Rosylight
|
||||
* Kanchalai Tanglertsampan
|
||||
* Keith Mashinter
|
||||
* Ken Howard
|
||||
* Kenji Imamula
|
||||
* Kevin Lang
|
||||
* Kitson Kelly
|
||||
* Klaus Meinhardt
|
||||
* Kyle Kelley
|
||||
* Kārlis Gaņģis
|
||||
* Lorant Pinter
|
||||
* Lucien Greathouse
|
||||
* Lukas Elmer
|
||||
* Magnus Hiie
|
||||
* Manish Giri
|
||||
* Marin Marinov
|
||||
* Marius Schulz
|
||||
* Martin Vseticka
|
||||
* Masahiro Wakame
|
||||
* Matt Bierner
|
||||
* Matt McCutchen
|
||||
* Mattias Buelens
|
||||
* Mattias Buelens
|
||||
@ -140,8 +156,11 @@ TypeScript is authored by:
|
||||
* Micah Zoltu
|
||||
* Michael
|
||||
* Michael Bromley
|
||||
* Mike Busyrev
|
||||
* Mine Starks
|
||||
* Mohamed Hegazy
|
||||
* Myles Megyesi
|
||||
* Natalie Coley
|
||||
* Nathan Shively-Sanders
|
||||
* Nathan Yee
|
||||
* Nicolas Henry
|
||||
@ -167,6 +186,7 @@ TypeScript is authored by:
|
||||
* Punya Biswal
|
||||
* Rado Kirov
|
||||
* Raj Dosanjh
|
||||
* Richard Karmazín
|
||||
* Richard Knoll
|
||||
* Richard Sentino
|
||||
* Robert Coie
|
||||
@ -178,6 +198,7 @@ TypeScript is authored by:
|
||||
* Ryohei Ikegami
|
||||
* Sam El-Husseini
|
||||
* Sarangan Rajamanickam
|
||||
* Sergey Rubanov
|
||||
* Sergey Shandar
|
||||
* Sheetal Nandi
|
||||
* Shengping Zhong
|
||||
@ -185,6 +206,7 @@ TypeScript is authored by:
|
||||
* Simon Hürlimann
|
||||
* Slawomir Sadziak
|
||||
* Solal Pirelli
|
||||
* Soo Jae Hwang
|
||||
* Stan Thomas
|
||||
* Stanislav Sysoev
|
||||
* Steve Lucco
|
||||
@ -204,6 +226,7 @@ TypeScript is authored by:
|
||||
* Tomas Grubliauskas
|
||||
* Torben Fitschen
|
||||
* TruongSinh Tran-Nguyen
|
||||
* Vadi Taslim
|
||||
* Vidar Tonaas Fauske
|
||||
* Viktor Zozulyak
|
||||
* Vilic Vane
|
||||
|
||||
151
Gulpfile.ts
151
Gulpfile.ts
@ -2,6 +2,7 @@
|
||||
import * as cp from "child_process";
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
import child_process = require("child_process");
|
||||
import originalGulp = require("gulp");
|
||||
import helpMaker = require("gulp-help");
|
||||
import runSequence = require("run-sequence");
|
||||
@ -21,10 +22,6 @@ declare module "gulp-typescript" {
|
||||
import * as insert from "gulp-insert";
|
||||
import * as sourcemaps from "gulp-sourcemaps";
|
||||
import Q = require("q");
|
||||
declare global {
|
||||
// `del` further depends on `Promise` (and is also not included), so we just, patch the global scope's Promise to Q's (which we already include in our deps because gulp depends on it)
|
||||
type Promise<T> = Q.Promise<T>;
|
||||
}
|
||||
import del = require("del");
|
||||
import mkdirP = require("mkdirp");
|
||||
import minimist = require("minimist");
|
||||
@ -41,7 +38,7 @@ const {runTestsInParallel} = mochaParallel;
|
||||
Error.stackTraceLimit = 1000;
|
||||
|
||||
const cmdLineOptions = minimist(process.argv.slice(2), {
|
||||
boolean: ["debug", "light", "colors", "lint", "soft"],
|
||||
boolean: ["debug", "inspect", "light", "colors", "lint", "soft"],
|
||||
string: ["browser", "tests", "host", "reporter", "stackTraceLimit"],
|
||||
alias: {
|
||||
d: "debug",
|
||||
@ -57,6 +54,7 @@ const cmdLineOptions = minimist(process.argv.slice(2), {
|
||||
soft: false,
|
||||
colors: process.env.colors || process.env.color || true,
|
||||
debug: process.env.debug || process.env.d,
|
||||
inspect: process.env.inspect,
|
||||
host: process.env.TYPESCRIPT_HOST || process.env.host || "node",
|
||||
browser: process.env.browser || process.env.b || "IE",
|
||||
tests: process.env.test || process.env.tests || process.env.t,
|
||||
@ -138,6 +136,14 @@ const es2017LibrarySourceMap = es2017LibrarySource.map(function(source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
});
|
||||
|
||||
const esnextLibrarySource = [
|
||||
"esnext.asynciterable.d.ts"
|
||||
];
|
||||
|
||||
const esnextLibrarySourceMap = esnextLibrarySource.map(function (source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
});
|
||||
|
||||
const hostsLibrarySources = ["dom.generated.d.ts", "webworker.importscripts.d.ts", "scripthost.d.ts"];
|
||||
|
||||
const librarySourceMap = [
|
||||
@ -152,11 +158,12 @@ const librarySourceMap = [
|
||||
{ target: "lib.es2015.d.ts", sources: ["header.d.ts", "es2015.d.ts"] },
|
||||
{ target: "lib.es2016.d.ts", sources: ["header.d.ts", "es2016.d.ts"] },
|
||||
{ target: "lib.es2017.d.ts", sources: ["header.d.ts", "es2017.d.ts"] },
|
||||
{ target: "lib.esnext.d.ts", sources: ["header.d.ts", "esnext.d.ts"] },
|
||||
|
||||
// JavaScript + all host library
|
||||
{ target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources) },
|
||||
{ target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") }
|
||||
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap);
|
||||
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap, esnextLibrarySourceMap);
|
||||
|
||||
const libraryTargets = librarySourceMap.map(function(f) {
|
||||
return path.join(builtLocalDirectory, f.target);
|
||||
@ -168,7 +175,7 @@ for (const i in libraryTargets) {
|
||||
const sources = [copyright].concat(entry.sources.map(function(s) {
|
||||
return path.join(libraryDirectory, s);
|
||||
}));
|
||||
gulp.task(target, false, [], function() {
|
||||
gulp.task(target, /*help*/ false, [], function() {
|
||||
return gulp.src(sources)
|
||||
.pipe(newer(target))
|
||||
.pipe(concat(target, { newLine: "\n\n" }))
|
||||
@ -268,7 +275,7 @@ function getCompilerSettings(base: tsc.Settings, useBuiltCompiler?: boolean): ts
|
||||
return copy;
|
||||
}
|
||||
|
||||
gulp.task(configureNightlyJs, false, [], () => {
|
||||
gulp.task(configureNightlyJs, /*help*/ false, [], () => {
|
||||
const settings: tsc.Settings = {
|
||||
declaration: false,
|
||||
removeComments: true,
|
||||
@ -297,7 +304,7 @@ const importDefinitelyTypedTestsDirectory = path.join(scriptsDirectory, "importD
|
||||
const importDefinitelyTypedTestsJs = path.join(importDefinitelyTypedTestsDirectory, "importDefinitelyTypedTests.js");
|
||||
const importDefinitelyTypedTestsTs = path.join(importDefinitelyTypedTestsDirectory, "importDefinitelyTypedTests.ts");
|
||||
|
||||
gulp.task(importDefinitelyTypedTestsJs, false, [], () => {
|
||||
gulp.task(importDefinitelyTypedTestsJs, /*help*/ false, [], () => {
|
||||
const settings: tsc.Settings = getCompilerSettings({
|
||||
declaration: false,
|
||||
removeComments: true,
|
||||
@ -328,7 +335,7 @@ const generatedDiagnosticMessagesJSON = path.join(compilerDirectory, "diagnostic
|
||||
const builtGeneratedDiagnosticMessagesJSON = path.join(builtLocalDirectory, "diagnosticMessages.generated.json");
|
||||
|
||||
// processDiagnosticMessages script
|
||||
gulp.task(processDiagnosticMessagesJs, false, [], () => {
|
||||
gulp.task(processDiagnosticMessagesJs, /*help*/ false, [], () => {
|
||||
const settings: tsc.Settings = getCompilerSettings({
|
||||
target: "es5",
|
||||
declaration: false,
|
||||
@ -376,26 +383,26 @@ function prependCopyright(outputCopyright: boolean = !useDebugMode) {
|
||||
return insert.prepend(outputCopyright ? (copyrightContent || (copyrightContent = fs.readFileSync(copyright).toString())) : "");
|
||||
}
|
||||
|
||||
gulp.task(builtLocalCompiler, false, [servicesFile], () => {
|
||||
const localCompilerProject = tsc.createProject("src/compiler/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/true));
|
||||
gulp.task(builtLocalCompiler, /*help*/ false, [servicesFile], () => {
|
||||
const localCompilerProject = tsc.createProject("src/compiler/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/ true));
|
||||
return localCompilerProject.src()
|
||||
.pipe(newer(builtLocalCompiler))
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(localCompilerProject())
|
||||
.pipe(prependCopyright())
|
||||
.pipe(sourcemaps.write("."))
|
||||
.pipe(gulp.dest("."));
|
||||
.pipe(gulp.dest("src/compiler"));
|
||||
});
|
||||
|
||||
gulp.task(servicesFile, false, ["lib", "generate-diagnostics"], () => {
|
||||
const servicesProject = tsc.createProject("src/services/tsconfig.json", getCompilerSettings({ removeComments: false }, /*useBuiltCompiler*/false));
|
||||
gulp.task(servicesFile, /*help*/ false, ["lib", "generate-diagnostics"], () => {
|
||||
const servicesProject = tsc.createProject("src/services/tsconfig.json", getCompilerSettings({ removeComments: false }, /*useBuiltCompiler*/ false));
|
||||
const {js, dts} = servicesProject.src()
|
||||
.pipe(newer(servicesFile))
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(servicesProject());
|
||||
const completedJs = js.pipe(prependCopyright())
|
||||
.pipe(sourcemaps.write("."));
|
||||
const completedDts = dts.pipe(prependCopyright(/*outputCopyright*/true))
|
||||
const completedDts = dts.pipe(prependCopyright(/*outputCopyright*/ true))
|
||||
.pipe(insert.transform((contents, file) => {
|
||||
file.path = standaloneDefinitionsFile;
|
||||
return contents.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, "$1$2enum $3 {$4");
|
||||
@ -410,19 +417,19 @@ gulp.task(servicesFile, false, ["lib", "generate-diagnostics"], () => {
|
||||
file.path = nodeDefinitionsFile;
|
||||
return content + "\r\nexport = ts;";
|
||||
}))
|
||||
.pipe(gulp.dest(".")),
|
||||
.pipe(gulp.dest("src/services")),
|
||||
completedDts.pipe(clone())
|
||||
.pipe(insert.transform((content, file) => {
|
||||
file.path = nodeStandaloneDefinitionsFile;
|
||||
return content.replace(/declare (namespace|module) ts/g, 'declare module "typescript"');
|
||||
}))
|
||||
]).pipe(gulp.dest("."));
|
||||
]).pipe(gulp.dest("src/services"));
|
||||
});
|
||||
|
||||
// cancellationToken.js
|
||||
const cancellationTokenJs = path.join(builtLocalDirectory, "cancellationToken.js");
|
||||
gulp.task(cancellationTokenJs, false, [servicesFile], () => {
|
||||
const cancellationTokenProject = tsc.createProject("src/server/cancellationToken/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/true));
|
||||
gulp.task(cancellationTokenJs, /*help*/ false, [servicesFile], () => {
|
||||
const cancellationTokenProject = tsc.createProject("src/server/cancellationToken/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/ true));
|
||||
return cancellationTokenProject.src()
|
||||
.pipe(newer(cancellationTokenJs))
|
||||
.pipe(sourcemaps.init())
|
||||
@ -434,34 +441,34 @@ gulp.task(cancellationTokenJs, false, [servicesFile], () => {
|
||||
|
||||
// typingsInstallerFile.js
|
||||
const typingsInstallerJs = path.join(builtLocalDirectory, "typingsInstaller.js");
|
||||
gulp.task(typingsInstallerJs, false, [servicesFile], () => {
|
||||
const cancellationTokenProject = tsc.createProject("src/server/typingsInstaller/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/true));
|
||||
gulp.task(typingsInstallerJs, /*help*/ false, [servicesFile], () => {
|
||||
const cancellationTokenProject = tsc.createProject("src/server/typingsInstaller/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/ true));
|
||||
return cancellationTokenProject.src()
|
||||
.pipe(newer(typingsInstallerJs))
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(cancellationTokenProject())
|
||||
.pipe(prependCopyright())
|
||||
.pipe(sourcemaps.write("."))
|
||||
.pipe(gulp.dest("."));
|
||||
.pipe(gulp.dest("src/server/typingsInstaller"));
|
||||
});
|
||||
|
||||
const serverFile = path.join(builtLocalDirectory, "tsserver.js");
|
||||
|
||||
gulp.task(serverFile, false, [servicesFile, typingsInstallerJs, cancellationTokenJs], () => {
|
||||
const serverProject = tsc.createProject("src/server/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/true));
|
||||
gulp.task(serverFile, /*help*/ false, [servicesFile, typingsInstallerJs, cancellationTokenJs], () => {
|
||||
const serverProject = tsc.createProject("src/server/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/ true));
|
||||
return serverProject.src()
|
||||
.pipe(newer(serverFile))
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(serverProject())
|
||||
.pipe(prependCopyright())
|
||||
.pipe(sourcemaps.write("."))
|
||||
.pipe(gulp.dest("."));
|
||||
.pipe(gulp.dest("src/server"));
|
||||
});
|
||||
|
||||
const tsserverLibraryFile = path.join(builtLocalDirectory, "tsserverlibrary.js");
|
||||
const tsserverLibraryDefinitionFile = path.join(builtLocalDirectory, "tsserverlibrary.d.ts");
|
||||
|
||||
gulp.task(tsserverLibraryFile, false, [servicesFile], (done) => {
|
||||
gulp.task(tsserverLibraryFile, /*help*/ false, [servicesFile], (done) => {
|
||||
const serverLibraryProject = tsc.createProject("src/server/tsconfig.library.json", getCompilerSettings({}, /*useBuiltCompiler*/ true));
|
||||
const {js, dts}: { js: NodeJS.ReadableStream, dts: NodeJS.ReadableStream } = serverLibraryProject.src()
|
||||
.pipe(sourcemaps.init())
|
||||
@ -471,12 +478,12 @@ gulp.task(tsserverLibraryFile, false, [servicesFile], (done) => {
|
||||
return merge2([
|
||||
js.pipe(prependCopyright())
|
||||
.pipe(sourcemaps.write("."))
|
||||
.pipe(gulp.dest(".")),
|
||||
dts.pipe(prependCopyright(/*outputCopyright*/true))
|
||||
.pipe(gulp.dest("src/server")),
|
||||
dts.pipe(prependCopyright(/*outputCopyright*/ true))
|
||||
.pipe(insert.transform((content) => {
|
||||
return content + "\r\nexport = ts;\r\nexport as namespace ts;";
|
||||
}))
|
||||
.pipe(gulp.dest("."))
|
||||
.pipe(gulp.dest("src/server"))
|
||||
]);
|
||||
});
|
||||
|
||||
@ -490,7 +497,7 @@ const word2mdTs = path.join(scriptsDirectory, "word2md.ts");
|
||||
const specWord = path.join(docDirectory, "TypeScript Language Specification.docx");
|
||||
const specMd = path.join(docDirectory, "spec.md");
|
||||
|
||||
gulp.task(word2mdJs, false, [], () => {
|
||||
gulp.task(word2mdJs, /*help*/ false, [], () => {
|
||||
const settings: tsc.Settings = getCompilerSettings({
|
||||
outFile: word2mdJs
|
||||
}, /*useBuiltCompiler*/ false);
|
||||
@ -502,7 +509,7 @@ gulp.task(word2mdJs, false, [], () => {
|
||||
.pipe(gulp.dest("."));
|
||||
});
|
||||
|
||||
gulp.task(specMd, false, [word2mdJs], (done) => {
|
||||
gulp.task(specMd, /*help*/ false, [word2mdJs], (done) => {
|
||||
const specWordFullPath = path.resolve(specWord);
|
||||
const specMDFullPath = path.resolve(specMd);
|
||||
const cmd = "cscript //nologo " + word2mdJs + " \"" + specWordFullPath + "\" " + "\"" + specMDFullPath + "\"";
|
||||
@ -518,10 +525,10 @@ gulp.task("clean", "Cleans the compiler output, declare files, and tests", [], (
|
||||
return del([builtDirectory]);
|
||||
});
|
||||
|
||||
gulp.task("useDebugMode", false, [], (done) => { useDebugMode = true; done(); });
|
||||
gulp.task("dontUseDebugMode", false, [], (done) => { useDebugMode = false; done(); });
|
||||
gulp.task("useDebugMode", /*help*/ false, [], (done) => { useDebugMode = true; done(); });
|
||||
gulp.task("dontUseDebugMode", /*help*/ false, [], (done) => { useDebugMode = false; done(); });
|
||||
|
||||
gulp.task("VerifyLKG", false, [], () => {
|
||||
gulp.task("VerifyLKG", /*help*/ false, [], () => {
|
||||
const expectedFiles = [builtLocalCompiler, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, typingsInstallerJs, cancellationTokenJs].concat(libraryTargets);
|
||||
const missingFiles = expectedFiles.filter(function(f) {
|
||||
return !fs.existsSync(f);
|
||||
@ -534,7 +541,7 @@ gulp.task("VerifyLKG", false, [], () => {
|
||||
return gulp.src(expectedFiles).pipe(gulp.dest(LKGDirectory));
|
||||
});
|
||||
|
||||
gulp.task("LKGInternal", false, ["lib", "local"]);
|
||||
gulp.task("LKGInternal", /*help*/ false, ["lib", "local"]);
|
||||
|
||||
gulp.task("LKG", "Makes a new LKG out of the built js files", ["clean", "dontUseDebugMode"], () => {
|
||||
return runSequence("LKGInternal", "VerifyLKG");
|
||||
@ -543,14 +550,14 @@ gulp.task("LKG", "Makes a new LKG out of the built js files", ["clean", "dontUse
|
||||
|
||||
// Task to build the tests infrastructure using the built compiler
|
||||
const run = path.join(builtLocalDirectory, "run.js");
|
||||
gulp.task(run, false, [servicesFile], () => {
|
||||
const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/true));
|
||||
gulp.task(run, /*help*/ false, [servicesFile], () => {
|
||||
const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({}, /*useBuiltCompiler*/ true));
|
||||
return testProject.src()
|
||||
.pipe(newer(run))
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(testProject())
|
||||
.pipe(sourcemaps.write(".", { includeContent: false, sourceRoot: "../../" }))
|
||||
.pipe(gulp.dest("."));
|
||||
.pipe(gulp.dest("src/harness"));
|
||||
});
|
||||
|
||||
const internalTests = "internal/";
|
||||
@ -588,6 +595,7 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
||||
cleanTestDirs((err) => {
|
||||
if (err) { console.error(err); failWithStatus(err, 1); }
|
||||
const debug = cmdLineOptions["debug"];
|
||||
const inspect = cmdLineOptions["inspect"];
|
||||
const tests = cmdLineOptions["tests"];
|
||||
const light = cmdLineOptions["light"];
|
||||
const stackTraceLimit = cmdLineOptions["stackTraceLimit"];
|
||||
@ -624,7 +632,10 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
||||
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
|
||||
if (!runInParallel) {
|
||||
const args = [];
|
||||
if (debug) {
|
||||
if (inspect) {
|
||||
args.push("--inspect");
|
||||
}
|
||||
if (inspect || debug) {
|
||||
args.push("--debug-brk");
|
||||
}
|
||||
args.push("-R", reporter);
|
||||
@ -713,7 +724,7 @@ gulp.task("runtests",
|
||||
|
||||
const nodeServerOutFile = "tests/webTestServer.js";
|
||||
const nodeServerInFile = "tests/webTestServer.ts";
|
||||
gulp.task(nodeServerOutFile, false, [servicesFile], () => {
|
||||
gulp.task(nodeServerOutFile, /*help*/ false, [servicesFile], () => {
|
||||
const settings: tsc.Settings = getCompilerSettings({ module: "commonjs" }, /*useBuiltCompiler*/ true);
|
||||
return gulp.src(nodeServerInFile)
|
||||
.pipe(newer(nodeServerOutFile))
|
||||
@ -739,14 +750,14 @@ gulp.task("browserify", "Runs browserify on run.js to produce a file suitable fo
|
||||
const originalMap = file.sourceMap;
|
||||
const prebundledContent = file.contents.toString();
|
||||
// Make paths absolute to help sorcery deal with all the terrible paths being thrown around
|
||||
originalMap.sources = originalMap.sources.map(s => path.resolve(s));
|
||||
originalMap.sources = originalMap.sources.map(s => path.resolve(path.join("src/harness", s)));
|
||||
// intoStream (below) makes browserify think the input file is named this, so this is what it puts in the sourcemap
|
||||
originalMap.file = "built/local/_stream_0.js";
|
||||
|
||||
browserify(intoStream(file.contents), { debug: true })
|
||||
.bundle((err, res) => {
|
||||
// assumes file.contents is a Buffer
|
||||
const maps = JSON.parse(convertMap.fromSource(res.toString(), /*largeSource*/true).toJSON());
|
||||
const maps = JSON.parse(convertMap.fromSource(res.toString(), /*largeSource*/ true).toJSON());
|
||||
delete maps.sourceRoot;
|
||||
maps.sources = maps.sources.map(s => path.resolve(s === "_stream_0.js" ? "built/local/_stream_0.js" : s));
|
||||
// Strip browserify's inline comments away (could probably just let sorcery do this, but then we couldn't fix the paths)
|
||||
@ -764,11 +775,11 @@ gulp.task("browserify", "Runs browserify on run.js to produce a file suitable fo
|
||||
});
|
||||
const finalMap = chain.apply();
|
||||
file.sourceMap = finalMap;
|
||||
next(undefined, file);
|
||||
next(/*err*/ undefined, file);
|
||||
});
|
||||
}))
|
||||
.pipe(sourcemaps.write(".", { includeContent: false }))
|
||||
.pipe(gulp.dest("."));
|
||||
.pipe(gulp.dest("src/harness"));
|
||||
});
|
||||
|
||||
|
||||
@ -878,7 +889,7 @@ gulp.task("baseline-accept-test262", "Makes the most recent test262 test results
|
||||
// Webhost
|
||||
const webhostPath = "tests/webhost/webtsc.ts";
|
||||
const webhostJsPath = "tests/webhost/webtsc.js";
|
||||
gulp.task(webhostJsPath, false, [servicesFile], () => {
|
||||
gulp.task(webhostJsPath, /*help*/ false, [servicesFile], () => {
|
||||
const settings: tsc.Settings = getCompilerSettings({
|
||||
outFile: webhostJsPath
|
||||
}, /*useBuiltCompiler*/ true);
|
||||
@ -898,7 +909,7 @@ gulp.task("webhost", "Builds the tsc web host", [webhostJsPath], () => {
|
||||
// Perf compiler
|
||||
const perftscPath = "tests/perftsc.ts";
|
||||
const perftscJsPath = "built/local/perftsc.js";
|
||||
gulp.task(perftscJsPath, false, [servicesFile], () => {
|
||||
gulp.task(perftscJsPath, /*help*/ false, [servicesFile], () => {
|
||||
const settings: tsc.Settings = getCompilerSettings({
|
||||
outFile: perftscJsPath
|
||||
}, /*useBuiltCompiler*/ true);
|
||||
@ -916,10 +927,10 @@ gulp.task("perftsc", "Builds augmented version of the compiler for perf tests",
|
||||
// Instrumented compiler
|
||||
const loggedIOpath = path.join(harnessDirectory, "loggedIO.ts");
|
||||
const loggedIOJsPath = path.join(builtLocalDirectory, "loggedIO.js");
|
||||
gulp.task(loggedIOJsPath, false, [], (done) => {
|
||||
gulp.task(loggedIOJsPath, /*help*/ false, [], (done) => {
|
||||
const temp = path.join(builtLocalDirectory, "temp");
|
||||
mkdirP(temp, (err) => {
|
||||
if (err) { console.error(err); done(err); process.exit(1); };
|
||||
if (err) { console.error(err); done(err); process.exit(1); }
|
||||
exec(host, [LKGCompiler, "--types --outdir", temp, loggedIOpath], () => {
|
||||
fs.renameSync(path.join(temp, "/harness/loggedIO.js"), loggedIOJsPath);
|
||||
del(temp).then(() => done(), done);
|
||||
@ -929,7 +940,7 @@ gulp.task(loggedIOJsPath, false, [], (done) => {
|
||||
|
||||
const instrumenterPath = path.join(harnessDirectory, "instrumenter.ts");
|
||||
const instrumenterJsPath = path.join(builtLocalDirectory, "instrumenter.js");
|
||||
gulp.task(instrumenterJsPath, false, [servicesFile], () => {
|
||||
gulp.task(instrumenterJsPath, /*help*/ false, [servicesFile], () => {
|
||||
const settings: tsc.Settings = getCompilerSettings({
|
||||
outFile: instrumenterJsPath
|
||||
}, /*useBuiltCompiler*/ true);
|
||||
@ -950,7 +961,7 @@ gulp.task("update-sublime", "Updates the sublime plugin's tsserver", ["local", s
|
||||
});
|
||||
|
||||
gulp.task("build-rules", "Compiles tslint rules to js", () => {
|
||||
const settings: tsc.Settings = getCompilerSettings({ module: "commonjs" }, /*useBuiltCompiler*/ false);
|
||||
const settings: tsc.Settings = getCompilerSettings({ module: "commonjs", "lib": ["es6"] }, /*useBuiltCompiler*/ false);
|
||||
const dest = path.join(builtLocalDirectory, "tslint");
|
||||
return gulp.src("scripts/tslint/**/*.ts")
|
||||
.pipe(newer({
|
||||
@ -1009,40 +1020,16 @@ function spawnLintWorker(files: {path: string}[], callback: (failures: number) =
|
||||
}
|
||||
|
||||
gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are: --f[iles]=regex", ["build-rules"], () => {
|
||||
const fileMatcher = RegExp(cmdLineOptions["files"]);
|
||||
if (fold.isTravis()) console.log(fold.start("lint"));
|
||||
|
||||
let files: {stat: fs.Stats, path: string}[] = [];
|
||||
return gulp.src(lintTargets, { read: false })
|
||||
.pipe(through2.obj((chunk, enc, cb) => {
|
||||
files.push(chunk);
|
||||
cb();
|
||||
}, (cb) => {
|
||||
files = files.filter(file => fileMatcher.test(file.path)).sort((filea, fileb) => filea.stat.size - fileb.stat.size);
|
||||
const workerCount = cmdLineOptions["workers"];
|
||||
for (let i = 0; i < workerCount; i++) {
|
||||
spawnLintWorker(files, finished);
|
||||
}
|
||||
|
||||
let completed = 0;
|
||||
let failures = 0;
|
||||
function finished(fails) {
|
||||
completed++;
|
||||
failures += fails;
|
||||
if (completed === workerCount) {
|
||||
if (fold.isTravis()) console.log(fold.end("lint"));
|
||||
if (failures > 0) {
|
||||
throw new Error(`Linter errors: ${failures}`);
|
||||
}
|
||||
else {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
const fileMatcher = cmdLineOptions["files"];
|
||||
const files = fileMatcher
|
||||
? `src/**/${fileMatcher}`
|
||||
: "Gulpfile.ts 'scripts/tslint/*.ts' 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts'";
|
||||
const cmd = `node node_modules/tslint/bin/tslint ${files} --format stylish`;
|
||||
console.log("Linting: " + cmd);
|
||||
child_process.execSync(cmd, { stdio: [0, 1, 2] });
|
||||
});
|
||||
|
||||
|
||||
gulp.task("default", "Runs 'local'", ["local"]);
|
||||
|
||||
gulp.task("watch", "Watches the src/ directory for changes and executes runtests-parallel.", [], () => {
|
||||
|
||||
188
Jakefile.js
188
Jakefile.js
@ -11,10 +11,7 @@ var ts = require("./lib/typescript");
|
||||
|
||||
// Variables
|
||||
var compilerDirectory = "src/compiler/";
|
||||
var servicesDirectory = "src/services/";
|
||||
var serverDirectory = "src/server/";
|
||||
var typingsInstallerDirectory = "src/server/typingsInstaller";
|
||||
var cancellationTokenDirectory = "src/server/cancellationToken";
|
||||
var harnessDirectory = "src/harness/";
|
||||
var libraryDirectory = "src/lib/";
|
||||
var scriptsDirectory = "scripts/";
|
||||
@ -32,7 +29,8 @@ var thirdParty = "ThirdPartyNoticeText.txt";
|
||||
var nodeModulesPathPrefix = path.resolve("./node_modules/.bin/") + path.delimiter;
|
||||
if (process.env.path !== undefined) {
|
||||
process.env.path = nodeModulesPathPrefix + process.env.path;
|
||||
} else if (process.env.PATH !== undefined) {
|
||||
}
|
||||
else if (process.env.PATH !== undefined) {
|
||||
process.env.PATH = nodeModulesPathPrefix + process.env.PATH;
|
||||
}
|
||||
|
||||
@ -80,6 +78,7 @@ var compilerSources = filesFromConfig("./src/compiler/tsconfig.json");
|
||||
var servicesSources = filesFromConfig("./src/services/tsconfig.json");
|
||||
var cancellationTokenSources = filesFromConfig(path.join(serverDirectory, "cancellationToken/tsconfig.json"));
|
||||
var typingsInstallerSources = filesFromConfig(path.join(serverDirectory, "typingsInstaller/tsconfig.json"));
|
||||
var watchGuardSources = filesFromConfig(path.join(serverDirectory, "watchGuard/tsconfig.json"));
|
||||
var serverSources = filesFromConfig(path.join(serverDirectory, "tsconfig.json"))
|
||||
var languageServiceLibrarySources = filesFromConfig(path.join(serverDirectory, "tsconfig.library.json"));
|
||||
|
||||
@ -129,6 +128,9 @@ var harnessSources = harnessCoreSources.concat([
|
||||
"matchFiles.ts",
|
||||
"initializeTSConfig.ts",
|
||||
"printer.ts",
|
||||
"textChanges.ts",
|
||||
"transform.ts",
|
||||
"customTransforms.ts",
|
||||
].map(function (f) {
|
||||
return path.join(unittestsDirectory, f);
|
||||
})).concat([
|
||||
@ -170,13 +172,21 @@ var es2016LibrarySourceMap = es2016LibrarySource.map(function (source) {
|
||||
var es2017LibrarySource = [
|
||||
"es2017.object.d.ts",
|
||||
"es2017.sharedmemory.d.ts",
|
||||
"es2017.string.d.ts",
|
||||
"es2017.string.d.ts"
|
||||
];
|
||||
|
||||
var es2017LibrarySourceMap = es2017LibrarySource.map(function (source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
});
|
||||
|
||||
var esnextLibrarySource = [
|
||||
"esnext.asynciterable.d.ts"
|
||||
];
|
||||
|
||||
var esnextLibrarySourceMap = esnextLibrarySource.map(function (source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
});
|
||||
|
||||
var hostsLibrarySources = ["dom.generated.d.ts", "webworker.importscripts.d.ts", "scripthost.d.ts"];
|
||||
|
||||
var librarySourceMap = [
|
||||
@ -191,11 +201,12 @@ var librarySourceMap = [
|
||||
{ target: "lib.es2015.d.ts", sources: ["header.d.ts", "es2015.d.ts"] },
|
||||
{ target: "lib.es2016.d.ts", sources: ["header.d.ts", "es2016.d.ts"] },
|
||||
{ target: "lib.es2017.d.ts", sources: ["header.d.ts", "es2017.d.ts"] },
|
||||
{ target: "lib.esnext.d.ts", sources: ["header.d.ts", "esnext.d.ts"] },
|
||||
|
||||
// JavaScript + all host library
|
||||
{ target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources) },
|
||||
{ target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") }
|
||||
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap);
|
||||
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap, esnextLibrarySourceMap);
|
||||
|
||||
var libraryTargets = librarySourceMap.map(function (f) {
|
||||
return path.join(builtLocalDirectory, f.target);
|
||||
@ -302,21 +313,29 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts
|
||||
if (useDebugMode) {
|
||||
if (opts.inlineSourceMap) {
|
||||
options += " --inlineSourceMap --inlineSources";
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
options += " -sourcemap";
|
||||
if (!opts.noMapRoot) {
|
||||
options += " -mapRoot file:///" + path.resolve(path.dirname(outFile));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
options += " --newLine LF";
|
||||
}
|
||||
|
||||
if (opts.stripInternal) {
|
||||
options += " --stripInternal";
|
||||
}
|
||||
|
||||
options += " --target es5 --lib es5,scripthost --noUnusedLocals --noUnusedParameters";
|
||||
options += " --target es5";
|
||||
if (opts.lib) {
|
||||
options += " --lib " + opts.lib
|
||||
}
|
||||
else {
|
||||
options += " --lib es5"
|
||||
}
|
||||
options += " --noUnusedLocals --noUnusedParameters";
|
||||
|
||||
var cmd = host + " " + compilerPath + " " + options + " ";
|
||||
cmd = cmd + sources.join(" ");
|
||||
@ -403,7 +422,7 @@ compileFile(buildProtocolJs,
|
||||
[buildProtocolTs],
|
||||
[],
|
||||
/*useBuiltCompiler*/ false,
|
||||
{noOutFile: true});
|
||||
{ noOutFile: true, lib: "es6" });
|
||||
|
||||
file(buildProtocolDts, [buildProtocolTs, buildProtocolJs, typescriptServicesDts], function() {
|
||||
|
||||
@ -565,13 +584,16 @@ compileFile(
|
||||
file(typescriptServicesDts, [servicesFile]);
|
||||
|
||||
var cancellationTokenFile = path.join(builtLocalDirectory, "cancellationToken.js");
|
||||
compileFile(cancellationTokenFile, cancellationTokenSources, [builtLocalDirectory].concat(cancellationTokenSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { outDir: builtLocalDirectory, noOutFile: true });
|
||||
compileFile(cancellationTokenFile, cancellationTokenSources, [builtLocalDirectory].concat(cancellationTokenSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { types: ["node"], outDir: builtLocalDirectory, noOutFile: true, lib: "es6" });
|
||||
|
||||
var typingsInstallerFile = path.join(builtLocalDirectory, "typingsInstaller.js");
|
||||
compileFile(typingsInstallerFile, typingsInstallerSources, [builtLocalDirectory].concat(typingsInstallerSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { outDir: builtLocalDirectory, noOutFile: false });
|
||||
compileFile(typingsInstallerFile, typingsInstallerSources, [builtLocalDirectory].concat(typingsInstallerSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { types: ["node"], outDir: builtLocalDirectory, noOutFile: false, lib: "es6" });
|
||||
|
||||
var watchGuardFile = path.join(builtLocalDirectory, "watchGuard.js");
|
||||
compileFile(watchGuardFile, watchGuardSources, [builtLocalDirectory].concat(watchGuardSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { types: ["node"], outDir: builtLocalDirectory, noOutFile: false, lib: "es6" });
|
||||
|
||||
var serverFile = path.join(builtLocalDirectory, "tsserver.js");
|
||||
compileFile(serverFile, serverSources, [builtLocalDirectory, copyright, cancellationTokenFile, typingsInstallerFile].concat(serverSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { types: ["node"] });
|
||||
compileFile(serverFile, serverSources, [builtLocalDirectory, copyright, cancellationTokenFile, typingsInstallerFile, watchGuardFile].concat(serverSources).concat(servicesSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { types: ["node"], preserveConstEnums: true, lib: "es6" });
|
||||
var tsserverLibraryFile = path.join(builtLocalDirectory, "tsserverlibrary.js");
|
||||
var tsserverLibraryDefinitionFile = path.join(builtLocalDirectory, "tsserverlibrary.d.ts");
|
||||
compileFile(
|
||||
@ -580,7 +602,7 @@ compileFile(
|
||||
[builtLocalDirectory, copyright, builtLocalCompiler].concat(languageServiceLibrarySources).concat(libraryTargets),
|
||||
/*prefixes*/[copyright],
|
||||
/*useBuiltCompiler*/ true,
|
||||
{ noOutFile: false, generateDeclarations: true, stripInternal: true },
|
||||
{ noOutFile: false, generateDeclarations: true, stripInternal: true, preserveConstEnums: true },
|
||||
/*callback*/ function () {
|
||||
prependFile(copyright, tsserverLibraryDefinitionFile);
|
||||
|
||||
@ -665,7 +687,7 @@ task("generate-spec", [specMd]);
|
||||
// Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory
|
||||
desc("Makes a new LKG out of the built js files");
|
||||
task("LKG", ["clean", "release", "local"].concat(libraryTargets), function () {
|
||||
var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile, buildProtocolDts].concat(libraryTargets);
|
||||
var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile, buildProtocolDts, watchGuardFile].concat(libraryTargets);
|
||||
var missingFiles = expectedFiles.filter(function (f) {
|
||||
return !fs.existsSync(f);
|
||||
});
|
||||
@ -695,7 +717,7 @@ compileFile(
|
||||
/*prereqs*/[builtLocalDirectory, tscFile].concat(libraryTargets).concat(servicesSources).concat(harnessSources),
|
||||
/*prefixes*/[],
|
||||
/*useBuiltCompiler:*/ true,
|
||||
/*opts*/ { inlineSourceMap: true, types: ["node", "mocha", "chai"] });
|
||||
/*opts*/ { inlineSourceMap: true, types: ["node", "mocha", "chai"], lib: "es6" });
|
||||
|
||||
var internalTests = "internal/";
|
||||
|
||||
@ -729,7 +751,8 @@ function exec(cmd, completeHandler, errorHandler) {
|
||||
ex.addListener("error", function (e, status) {
|
||||
if (errorHandler) {
|
||||
errorHandler(e, status);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
fail("Process exited with code " + status);
|
||||
}
|
||||
});
|
||||
@ -778,6 +801,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
}
|
||||
|
||||
var debug = process.env.debug || process.env.d;
|
||||
var inspect = process.env.inspect;
|
||||
tests = process.env.test || process.env.tests || process.env.t;
|
||||
var light = process.env.light || false;
|
||||
var stackTraceLimit = process.env.stackTraceLimit;
|
||||
@ -807,18 +831,39 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
testTimeout = 800000;
|
||||
}
|
||||
|
||||
colors = process.env.colors || process.env.color;
|
||||
colors = colors ? ' --no-colors ' : ' --colors ';
|
||||
reporter = process.env.reporter || process.env.r || defaultReporter;
|
||||
var bail = (process.env.bail || process.env.b) ? "--bail" : "";
|
||||
var colors = process.env.colors || process.env.color || true;
|
||||
var reporter = process.env.reporter || process.env.r || defaultReporter;
|
||||
var bail = process.env.bail || process.env.b;
|
||||
var lintFlag = process.env.lint !== 'false';
|
||||
|
||||
// timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally
|
||||
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
|
||||
if (!runInParallel) {
|
||||
var startTime = mark();
|
||||
tests = tests ? ' -g "' + tests + '"' : '';
|
||||
var cmd = "mocha" + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + bail + ' -t ' + testTimeout + ' ' + run;
|
||||
var args = [];
|
||||
if (inspect) {
|
||||
args.push("--inspect");
|
||||
}
|
||||
if (inspect || debug) {
|
||||
args.push("--debug-brk");
|
||||
}
|
||||
args.push("-R", reporter);
|
||||
if (tests) {
|
||||
args.push("-g", `"${tests}"`);
|
||||
}
|
||||
if (colors) {
|
||||
args.push("--colors");
|
||||
}
|
||||
else {
|
||||
args.push("--no-colors");
|
||||
}
|
||||
if (bail) {
|
||||
args.push("--bail");
|
||||
}
|
||||
args.push("-t", testTimeout);
|
||||
args.push(run);
|
||||
|
||||
var cmd = "mocha " + args.join(" ");
|
||||
console.log(cmd);
|
||||
|
||||
var savedNodeEnv = process.env.NODE_ENV;
|
||||
@ -839,7 +884,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
var savedNodeEnv = process.env.NODE_ENV;
|
||||
process.env.NODE_ENV = "development";
|
||||
var startTime = mark();
|
||||
runTestsInParallel(taskConfigsFolder, run, { testTimeout: testTimeout, noColors: colors === " --no-colors " }, function (err) {
|
||||
runTestsInParallel(taskConfigsFolder, run, { testTimeout: testTimeout, noColors: !colors }, function (err) {
|
||||
process.env.NODE_ENV = savedNodeEnv;
|
||||
measure(startTime);
|
||||
// last worker clean everything and runs linter in case if there were no errors
|
||||
@ -901,7 +946,7 @@ task("generate-code-coverage", ["tests", builtLocalDirectory], function () {
|
||||
// Browser tests
|
||||
var nodeServerOutFile = "tests/webTestServer.js";
|
||||
var nodeServerInFile = "tests/webTestServer.ts";
|
||||
compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, { noOutFile: true });
|
||||
compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, { noOutFile: true, lib: "es6" });
|
||||
|
||||
desc("Runs browserify on run.js to produce a file suitable for running tests in the browser");
|
||||
task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function() {
|
||||
@ -965,21 +1010,32 @@ task("baseline-accept", function () {
|
||||
|
||||
function acceptBaseline(sourceFolder, targetFolder) {
|
||||
console.log('Accept baselines from ' + sourceFolder + ' to ' + targetFolder);
|
||||
var files = fs.readdirSync(sourceFolder);
|
||||
var deleteEnding = '.delete';
|
||||
for (var i in files) {
|
||||
var filename = files[i];
|
||||
var fullLocalPath = path.join(sourceFolder, filename);
|
||||
if (fs.statSync(fullLocalPath).isFile()) {
|
||||
if (filename.substr(filename.length - deleteEnding.length) === deleteEnding) {
|
||||
filename = filename.substr(0, filename.length - deleteEnding.length);
|
||||
fs.unlinkSync(path.join(targetFolder, filename));
|
||||
} else {
|
||||
var target = path.join(targetFolder, filename);
|
||||
if (fs.existsSync(target)) {
|
||||
fs.unlinkSync(target);
|
||||
|
||||
acceptBaselineFolder(sourceFolder, targetFolder);
|
||||
|
||||
function acceptBaselineFolder(sourceFolder, targetFolder) {
|
||||
var files = fs.readdirSync(sourceFolder);
|
||||
|
||||
for (var i in files) {
|
||||
var filename = files[i];
|
||||
var fullLocalPath = path.join(sourceFolder, filename);
|
||||
var stat = fs.statSync(fullLocalPath);
|
||||
if (stat.isFile()) {
|
||||
if (filename.substr(filename.length - deleteEnding.length) === deleteEnding) {
|
||||
filename = filename.substr(0, filename.length - deleteEnding.length);
|
||||
fs.unlinkSync(path.join(targetFolder, filename));
|
||||
}
|
||||
fs.renameSync(path.join(sourceFolder, filename), target);
|
||||
else {
|
||||
var target = path.join(targetFolder, filename);
|
||||
if (fs.existsSync(target)) {
|
||||
fs.unlinkSync(target);
|
||||
}
|
||||
fs.renameSync(path.join(sourceFolder, filename), target);
|
||||
}
|
||||
}
|
||||
else if (stat.isDirectory()) {
|
||||
acceptBaselineFolder(fullLocalPath, path.join(targetFolder, filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1060,7 +1116,8 @@ var tslintRules = [
|
||||
"noInOperatorRule",
|
||||
"noIncrementDecrementRule",
|
||||
"objectLiteralSurroundingSpaceRule",
|
||||
"noTypeAssertionWhitespaceRule"
|
||||
"noTypeAssertionWhitespaceRule",
|
||||
"noBomRule"
|
||||
];
|
||||
var tslintRulesFiles = tslintRules.map(function (p) {
|
||||
return path.join(tslintRuleDir, p + ".ts");
|
||||
@ -1072,7 +1129,7 @@ desc("Compiles tslint rules to js");
|
||||
task("build-rules", ["build-rules-start"].concat(tslintRulesOutFiles).concat(["build-rules-end"]));
|
||||
tslintRulesFiles.forEach(function (ruleFile, i) {
|
||||
compileFile(tslintRulesOutFiles[i], [ruleFile], [ruleFile], [], /*useBuiltCompiler*/ false,
|
||||
{ noOutFile: true, generateDeclarations: false, outDir: path.join(builtLocalDirectory, "tslint") });
|
||||
{ noOutFile: true, generateDeclarations: false, outDir: path.join(builtLocalDirectory, "tslint"), lib: "es6" });
|
||||
});
|
||||
|
||||
desc("Emit the start of the build-rules fold");
|
||||
@ -1135,43 +1192,16 @@ function spawnLintWorker(files, callback) {
|
||||
}
|
||||
|
||||
desc("Runs tslint on the compiler sources. Optional arguments are: f[iles]=regex");
|
||||
task("lint", ["build-rules"], function () {
|
||||
task("lint", ["build-rules"], () => {
|
||||
if (fold.isTravis()) console.log(fold.start("lint"));
|
||||
var startTime = mark();
|
||||
var failed = 0;
|
||||
var fileMatcher = RegExp(process.env.f || process.env.file || process.env.files || "");
|
||||
var done = {};
|
||||
for (var i in lintTargets) {
|
||||
var target = lintTargets[i];
|
||||
if (!done[target] && fileMatcher.test(target)) {
|
||||
done[target] = fs.statSync(target).size;
|
||||
}
|
||||
}
|
||||
|
||||
var workerCount = (process.env.workerCount && +process.env.workerCount) || os.cpus().length;
|
||||
|
||||
var names = Object.keys(done).sort(function (namea, nameb) {
|
||||
return done[namea] - done[nameb];
|
||||
const fileMatcher = process.env.f || process.env.file || process.env.files;
|
||||
const files = fileMatcher
|
||||
? `src/**/${fileMatcher}`
|
||||
: "Gulpfile.ts 'scripts/tslint/*.ts' 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts'";
|
||||
const cmd = `node node_modules/tslint/bin/tslint ${files} --format stylish`;
|
||||
console.log("Linting: " + cmd);
|
||||
jake.exec([cmd], { interactive: true }, () => {
|
||||
if (fold.isTravis()) console.log(fold.end("lint"));
|
||||
complete();
|
||||
});
|
||||
|
||||
for (var i = 0; i < workerCount; i++) {
|
||||
spawnLintWorker(names, finished);
|
||||
}
|
||||
|
||||
var completed = 0;
|
||||
var failures = 0;
|
||||
function finished(fails) {
|
||||
completed++;
|
||||
failures += fails;
|
||||
if (completed === workerCount) {
|
||||
measure(startTime);
|
||||
if (fold.isTravis()) console.log(fold.end("lint"));
|
||||
if (failures > 0) {
|
||||
fail('Linter errors.', failed);
|
||||
}
|
||||
else {
|
||||
complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, { async: true });
|
||||
});
|
||||
|
||||
@ -39,8 +39,8 @@ with any additional questions or comments.
|
||||
|
||||
## Documentation
|
||||
|
||||
* [Quick tutorial](http://www.typescriptlang.org/Tutorial)
|
||||
* [Programming handbook](http://www.typescriptlang.org/Handbook)
|
||||
* [Quick tutorial](http://www.typescriptlang.org/docs/tutorial.html)
|
||||
* [Programming handbook](http://www.typescriptlang.org/docs/handbook/basic-types.html)
|
||||
* [Language specification](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)
|
||||
* [Homepage](http://www.typescriptlang.org/)
|
||||
|
||||
@ -95,4 +95,4 @@ node built/local/tsc.js hello.ts
|
||||
|
||||
## Roadmap
|
||||
|
||||
For details on our planned features and future direction please refer to our [roadmap](https://github.com/Microsoft/TypeScript/wiki/Roadmap).
|
||||
For details on our planned features and future direction please refer to our [roadmap](https://github.com/Microsoft/TypeScript/wiki/Roadmap).
|
||||
|
||||
25
doc/logo.svg
25
doc/logo.svg
@ -1,15 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" id="logo-typescript" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 283.09 69.57">
|
||||
<g fill="#007ACC">
|
||||
<path d="M34.98 7.56H20.43v45.07h-5.91V7.56H0V2.21h34.98V7.56z"/>
|
||||
<path d="M57.94 16.63L41.38 58.39c-2.95 7.45-7.1 11.18-12.45 11.18 -1.5 0-2.75-0.15-3.76-0.46v-5.17c1.24 0.42 2.38 0.63 3.41 0.63 2.91 0 5.09-1.73 6.54-5.2l2.88-6.82L23.94 16.63h6.4l9.74 27.7c0.12 0.35 0.36 1.27 0.74 2.74h0.21c0.12-0.56 0.35-1.45 0.7-2.67l10.23-27.77H57.94z"/>
|
||||
<path d="M67.37 47.43h-0.14v21.76h-5.77V16.63h5.77v6.33h0.14c2.84-4.78 6.98-7.17 12.45-7.17 4.64 0 8.26 1.61 10.86 4.83 2.6 3.22 3.9 7.54 3.9 12.96 0 6.02-1.46 10.85-4.39 14.47 -2.93 3.62-6.94 5.43-12.02 5.43C73.5 53.47 69.9 51.46 67.37 47.43zM67.23 32.91v5.03c0 2.98 0.97 5.5 2.9 7.58s4.39 3.11 7.37 3.11c3.49 0 6.23-1.34 8.21-4.01 1.98-2.67 2.97-6.39 2.97-11.14 0-4.01-0.93-7.15-2.78-9.42 -1.85-2.27-4.36-3.41-7.52-3.41 -3.35 0-6.05 1.17-8.09 3.5C68.25 26.47 67.23 29.39 67.23 32.91z"/>
|
||||
<path d="M129.56 36.07h-25.42c0.09 4.01 1.17 7.1 3.23 9.28 2.06 2.18 4.9 3.27 8.51 3.27 4.05 0 7.78-1.34 11.18-4.01v5.41c-3.16 2.3-7.35 3.45-12.55 3.45 -5.09 0-9.08-1.63-11.99-4.9 -2.91-3.27-4.36-7.87-4.36-13.8 0-5.6 1.59-10.17 4.76-13.69 3.18-3.53 7.12-5.29 11.83-5.29s8.35 1.52 10.93 4.57c2.58 3.05 3.87 7.28 3.87 12.69V36.07zM123.65 31.18c-0.02-3.33-0.83-5.92-2.41-7.77 -1.58-1.85-3.78-2.78-6.59-2.78 -2.72 0-5.03 0.97-6.93 2.92 -1.9 1.95-3.07 4.49-3.52 7.63H123.65z"/>
|
||||
<path d="M134.6 50.59v-6.96c0.73 0.7 1.6 1.34 2.62 1.9 1.02 0.56 2.09 1.04 3.22 1.42s2.26 0.69 3.39 0.9c1.14 0.21 2.19 0.32 3.15 0.32 3.32 0 5.81-0.67 7.45-2.02 1.64-1.35 2.46-3.29 2.46-5.82 0-1.36-0.27-2.54-0.82-3.55 -0.55-1.01-1.3-1.93-2.27-2.76s-2.11-1.63-3.43-2.39c-1.32-0.76-2.74-1.56-4.26-2.41 -1.61-0.89-3.11-1.79-4.5-2.71 -1.39-0.91-2.61-1.92-3.63-3.02 -1.03-1.1-1.84-2.35-2.43-3.74 -0.59-1.39-0.88-3.03-0.88-4.9 0-2.3 0.46-4.29 1.38-5.99 0.92-1.7 2.13-3.1 3.64-4.2 1.5-1.1 3.21-1.92 5.13-2.46 1.92-0.54 3.88-0.81 5.87-0.81 4.55 0 7.86 0.6 9.94 1.79v6.64c-2.72-2.06-6.22-3.09-10.49-3.09 -1.18 0-2.36 0.14-3.54 0.4 -1.18 0.27-2.23 0.71-3.15 1.32 -0.92 0.61-1.67 1.39-2.25 2.36 -0.58 0.96-0.87 2.13-0.87 3.52 0 1.29 0.22 2.4 0.66 3.34 0.44 0.94 1.09 1.79 1.95 2.57 0.86 0.77 1.9 1.52 3.14 2.25 1.23 0.73 2.65 1.52 4.26 2.39 1.65 0.89 3.22 1.83 4.7 2.81s2.78 2.07 3.89 3.27c1.11 1.2 2 2.52 2.65 3.97 0.65 1.45 0.98 3.12 0.98 4.99 0 2.48-0.45 4.59-1.33 6.31 -0.89 1.72-2.09 3.12-3.6 4.2 -1.51 1.08-3.25 1.86-5.23 2.34 -1.97 0.48-4.05 0.72-6.24 0.72 -0.73 0-1.63-0.06-2.7-0.19s-2.17-0.32-3.28-0.56c-1.12-0.25-2.17-0.55-3.17-0.91C136 51.44 135.21 51.03 134.6 50.59z"/>
|
||||
<path d="M193.25 50.98c-2.77 1.66-6.05 2.5-9.84 2.5 -5.13 0-9.28-1.67-12.43-5.01s-4.73-7.67-4.73-12.99c0-5.93 1.7-10.69 5.1-14.29 3.4-3.6 7.93-5.4 13.61-5.4 3.16 0 5.95 0.59 8.37 1.76v5.91c-2.67-1.88-5.53-2.81-8.58-2.81 -3.68 0-6.7 1.32-9.05 3.96s-3.53 6.1-3.53 10.39c0 4.22 1.11 7.55 3.32 9.98s5.19 3.66 8.91 3.66c3.14 0 6.09-1.04 8.86-3.13V50.98z"/>
|
||||
<path d="M215.56 22.46c-1.01-0.77-2.46-1.16-4.36-1.16 -2.46 0-4.52 1.16-6.17 3.48s-2.48 5.48-2.48 9.49v18.35h-5.77v-36h5.77v7.42h0.14c0.82-2.53 2.07-4.51 3.76-5.92 1.69-1.42 3.57-2.13 5.66-2.13 1.5 0 2.65 0.16 3.45 0.49V22.46z"/>
|
||||
<path d="M222.18 7.49c-1.03 0-1.91-0.35-2.64-1.05s-1.09-1.59-1.09-2.67c0-1.08 0.36-1.97 1.09-2.69 0.73-0.71 1.61-1.07 2.64-1.07 1.05 0 1.95 0.36 2.69 1.07 0.74 0.72 1.11 1.61 1.11 2.69 0 1.03-0.37 1.91-1.11 2.64C224.13 7.12 223.23 7.49 222.18 7.49zM224.99 52.63h-5.77v-36h5.77V52.63z"/>
|
||||
<path d="M234.29 47.43h-0.14v21.76h-5.77V16.63h5.77v6.33h0.14c2.84-4.78 6.98-7.17 12.45-7.17 4.64 0 8.26 1.61 10.86 4.83 2.6 3.22 3.9 7.54 3.9 12.96 0 6.02-1.46 10.85-4.39 14.47s-6.94 5.43-12.02 5.43C240.42 53.47 236.82 51.46 234.29 47.43zM234.15 32.91v5.03c0 2.98 0.97 5.5 2.9 7.58s4.39 3.11 7.37 3.11c3.49 0 6.23-1.34 8.21-4.01s2.97-6.39 2.97-11.14c0-4.01-0.93-7.15-2.78-9.42 -1.85-2.27-4.36-3.41-7.52-3.41 -3.35 0-6.05 1.17-8.09 3.5C235.17 26.47 234.15 29.39 234.15 32.91z"/>
|
||||
<path d="M283.09 52.28c-1.36 0.75-3.15 1.12-5.38 1.12 -6.3 0-9.46-3.52-9.46-10.55v-21.3h-6.19v-4.92h6.19V7.84l5.77-1.86v10.65h9.07v4.92h-9.07v20.28c0 2.41 0.41 4.14 1.23 5.17s2.18 1.55 4.08 1.55c1.45 0 2.71-0.4 3.76-1.2V52.28z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg id="logo-typescript" xmlns="http://www.w3.org/2000/svg" viewBox="-64.9 417 216.5 51.9">
|
||||
<style>
|
||||
.st0 {
|
||||
fill: #000
|
||||
}
|
||||
</style>
|
||||
<path class="st0" d="M-38.2 421.7h-11.1V456h-4.5v-34.3h-11.1v-4.1h26.6v4.1h.1z" />
|
||||
<path class="st0" d="M-16.9 428.6l-12.6 31.8c-2.3 5.7-5.4 8.5-9.5 8.5-1.1 0-2.1-.1-2.9-.3v-3.9c.9.3 1.8.5 2.6.5 2.2 0 3.9-1.3 5-4l2.2-5.2-10.7-27.4h4.9l7.4 21.1c.1.3.3 1 .6 2.1h.2c.1-.4.3-1.1.5-2l7.8-21.2h4.5zM-9.5 452.1h-.1v16.6H-14v-40h4.4v4.8h.1c2.2-3.6 5.3-5.5 9.5-5.5 3.5 0 6.3 1.2 8.3 3.7s3 5.7 3 9.9c0 4.6-1.1 8.3-3.3 11s-5.3 4.1-9.2 4.1c-3.6 0-6.3-1.5-8.3-4.6zm-.1-11.1v3.8c0 2.3.7 4.2 2.2 5.8s3.3 2.4 5.6 2.4c2.7 0 4.7-1 6.3-3.1 1.6-2.1 2.3-4.9 2.3-8.5 0-3.1-.7-5.4-2.1-7.2-1.4-1.7-3.3-2.6-5.7-2.6-2.6 0-4.6.9-6.2 2.7-1.6 1.8-2.4 4-2.4 6.7zM38.4 443.4H19c.1 3.1.9 5.4 2.5 7.1s3.7 2.5 6.5 2.5c3.1 0 5.9-1 8.5-3.1v4.1c-2.4 1.8-5.6 2.6-9.6 2.6-3.9 0-6.9-1.2-9.1-3.7-2.2-2.5-3.3-6-3.3-10.5 0-4.3 1.2-7.7 3.6-10.4 2.4-2.7 5.4-4 9-4s6.4 1.2 8.3 3.5c2 2.3 2.9 5.5 2.9 9.7v2.2h.1zm-4.5-3.7c0-2.5-.6-4.5-1.8-5.9-1.2-1.4-2.9-2.1-5-2.1s-3.8.7-5.3 2.2c-1.4 1.5-2.3 3.4-2.7 5.8h14.8zM40.8 454.7v-3c2.8 1.8 5.5 2.6 8.4 2.6 3 0 5.3-.6 6.8-1.9 1.6-1.2 2.3-3 2.3-5.2 0-2-.5-3.5-1.6-4.7-1-1.2-3.3-2.8-6.8-4.8-3.9-2.3-6.4-4.2-7.4-5.7s-1.6-3.3-1.6-5.3c0-2.7 1.1-5 3.2-6.9 2.1-1.9 4.9-2.8 8.4-2.8 2.3 0 4.6.4 6.9 1.2v2.8c-2.3-1-4.7-1.5-7.2-1.5-2.6 0-4.7.7-6.2 2s-2.3 3-2.3 5 .5 3.5 1.6 4.7c1 1.2 3.3 2.7 6.8 4.7 3.6 2 6 3.8 7.2 5.4 1.2 1.6 1.8 3.4 1.8 5.5 0 2.9-1 5.3-3.1 7.2-2 1.9-4.9 2.8-8.7 2.8-1.3 0-2.8-.2-4.6-.6-1.6-.5-2.9-1-3.9-1.5zM84.3 454.8c-2 1.2-4.5 1.9-7.3 1.9-3.7 0-6.7-1.3-9-3.8-2.3-2.6-3.4-5.9-3.4-10.1 0-4.4 1.3-7.9 3.9-10.7 2.6-2.8 5.9-4.2 9.9-4.2 2.1 0 4.1.4 6.1 1.3v2.8c-2-1.2-4.1-1.8-6.5-1.8-3.2 0-5.8 1.2-7.8 3.5s-3 5.3-3 9c0 3.6.9 6.4 2.7 8.6 1.8 2.2 4.2 3.2 7.2 3.2 2.7 0 5.1-.7 7.2-2.2v2.5zM100.9 431.2c-.8-.6-1.8-.9-2.9-.9-2.2 0-4 1.1-5.4 3.3-1.5 2.2-2.2 5.4-2.2 9.5V456H88v-27.4h2.4v6.1h.1c.6-2.1 1.6-3.7 3-4.9 1.4-1.2 2.9-1.7 4.7-1.7 1 0 1.9.2 2.7.5v2.6zM105.1 421.7c-.5 0-1-.2-1.4-.6s-.6-.9-.6-1.5.2-1.1.6-1.4c.4-.4.9-.5 1.4-.5.6 0 1 .2 1.5.5.4.4.6.8.6 1.4s-.2 1.1-.6 1.5c-.5.4-.9.6-1.5.6zm-1.2 34.4v-27.4h2.5v27.4h-2.5zM115 451.2h-.1v17.5h-2.5v-40h2.5v5.7h.1c1-2 2.4-3.6 4.2-4.7 1.8-1.1 3.8-1.6 6-1.6 3.5 0 6.2 1.2 8.2 3.6 2 2.4 2.9 5.7 2.9 9.8 0 4.6-1.1 8.3-3.4 11.1-2.2 2.8-5.2 4.2-8.9 4.2-4-.1-7-1.9-9-5.6zm-.1-10.2v3.5c0 2.8.9 5.1 2.6 7.1s4 3 6.8 3 5.1-1.2 6.8-3.6c1.7-2.4 2.6-5.6 2.6-9.5 0-3.4-.8-6.2-2.4-8.2s-3.8-3-6.4-3c-3.2 0-5.7 1.1-7.4 3.2-1.7 2.1-2.6 4.6-2.6 7.5zM151.6 455.7c-1.3.6-2.5.9-3.6.9-4.1 0-6.1-2.4-6.1-7.3v-18.4H137v-2.3h4.9v-7.1c.4-.1.8-.3 1.2-.4.4-.1.8-.3 1.2-.4v8h7.2v2.3h-7.2v18.1c0 1.9.3 3.3.9 4.1.6.8 1.6 1.3 3 1.3 1 0 2.1-.3 3.3-1v2.2h.1z"
|
||||
/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 2.7 KiB |
@ -2,7 +2,7 @@
|
||||
<!-- QUESTIONS: This is not a general support forum! Ask Qs at http://stackoverflow.com/questions/tagged/typescript -->
|
||||
<!-- SUGGESTIONS: See https://github.com/Microsoft/TypeScript-wiki/blob/master/Writing-Good-Design-Proposals.md -->
|
||||
|
||||
**TypeScript Version:** 2.1.1 / nightly (2.2.0-dev.201xxxxx)
|
||||
**TypeScript Version:** 2.2.1 / nightly (2.2.0-dev.201xxxxx)
|
||||
|
||||
**Code**
|
||||
|
||||
|
||||
@ -15,6 +15,15 @@ and limitations under the License.
|
||||
|
||||
"use strict";
|
||||
var fs = require("fs");
|
||||
function pipeExists(name) {
|
||||
try {
|
||||
fs.statSync(name);
|
||||
return true;
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function createCancellationToken(args) {
|
||||
var cancellationPipeName;
|
||||
for (var i = 0; i < args.length - 1; i++) {
|
||||
@ -24,18 +33,39 @@ function createCancellationToken(args) {
|
||||
}
|
||||
}
|
||||
if (!cancellationPipeName) {
|
||||
return { isCancellationRequested: function () { return false; } };
|
||||
return {
|
||||
isCancellationRequested: function () { return false; },
|
||||
setRequest: function (_requestId) { return void 0; },
|
||||
resetRequest: function (_requestId) { return void 0; }
|
||||
};
|
||||
}
|
||||
return {
|
||||
isCancellationRequested: function () {
|
||||
try {
|
||||
fs.statSync(cancellationPipeName);
|
||||
return true;
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
if (cancellationPipeName.charAt(cancellationPipeName.length - 1) === "*") {
|
||||
var namePrefix_1 = cancellationPipeName.slice(0, -1);
|
||||
if (namePrefix_1.length === 0 || namePrefix_1.indexOf("*") >= 0) {
|
||||
throw new Error("Invalid name for template cancellation pipe: it should have length greater than 2 characters and contain only one '*'.");
|
||||
}
|
||||
};
|
||||
var perRequestPipeName_1;
|
||||
var currentRequestId_1;
|
||||
return {
|
||||
isCancellationRequested: function () { return perRequestPipeName_1 !== undefined && pipeExists(perRequestPipeName_1); },
|
||||
setRequest: function (requestId) {
|
||||
currentRequestId_1 = currentRequestId_1;
|
||||
perRequestPipeName_1 = namePrefix_1 + requestId;
|
||||
},
|
||||
resetRequest: function (requestId) {
|
||||
if (currentRequestId_1 !== requestId) {
|
||||
throw new Error("Mismatched request id, expected " + currentRequestId_1 + ", actual " + requestId);
|
||||
}
|
||||
perRequestPipeName_1 = undefined;
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
isCancellationRequested: function () { return pipeExists(cancellationPipeName); },
|
||||
setRequest: function (_requestId) { return void 0; },
|
||||
resetRequest: function (_requestId) { return void 0; }
|
||||
};
|
||||
}
|
||||
}
|
||||
module.exports = createCancellationToken;
|
||||
|
||||
2017
lib/lib.d.ts
vendored
2017
lib/lib.d.ts
vendored
File diff suppressed because it is too large
Load Diff
1967
lib/lib.dom.d.ts
vendored
1967
lib/lib.dom.d.ts
vendored
File diff suppressed because it is too large
Load Diff
8
lib/lib.es2015.collection.d.ts
vendored
8
lib/lib.es2015.collection.d.ts
vendored
@ -24,7 +24,7 @@ interface Map<K, V> {
|
||||
forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
|
||||
get(key: K): V | undefined;
|
||||
has(key: K): boolean;
|
||||
set(key: K, value?: V): this;
|
||||
set(key: K, value: V): this;
|
||||
readonly size: number;
|
||||
}
|
||||
|
||||
@ -42,16 +42,16 @@ interface ReadonlyMap<K, V> {
|
||||
readonly size: number;
|
||||
}
|
||||
|
||||
interface WeakMap<K, V> {
|
||||
interface WeakMap<K extends object, V> {
|
||||
delete(key: K): boolean;
|
||||
get(key: K): V | undefined;
|
||||
has(key: K): boolean;
|
||||
set(key: K, value?: V): this;
|
||||
set(key: K, value: V): this;
|
||||
}
|
||||
|
||||
interface WeakMapConstructor {
|
||||
new (): WeakMap<any, any>;
|
||||
new <K, V>(entries?: [K, V][]): WeakMap<K, V>;
|
||||
new <K extends object, V>(entries?: [K, V][]): WeakMap<K, V>;
|
||||
readonly prototype: WeakMap<any, any>;
|
||||
}
|
||||
declare var WeakMap: WeakMapConstructor;
|
||||
|
||||
2
lib/lib.es2015.core.d.ts
vendored
2
lib/lib.es2015.core.d.ts
vendored
@ -345,7 +345,7 @@ interface ObjectConstructor {
|
||||
* @param o The object to change its prototype.
|
||||
* @param proto The value of the new prototype or null.
|
||||
*/
|
||||
setPrototypeOf(o: any, proto: any): any;
|
||||
setPrototypeOf(o: any, proto: object | null): any;
|
||||
|
||||
/**
|
||||
* Gets the own property descriptor of the specified object.
|
||||
|
||||
6
lib/lib.es2015.iterable.d.ts
vendored
6
lib/lib.es2015.iterable.d.ts
vendored
@ -119,10 +119,10 @@ interface MapConstructor {
|
||||
new <K, V>(iterable: Iterable<[K, V]>): Map<K, V>;
|
||||
}
|
||||
|
||||
interface WeakMap<K, V> { }
|
||||
interface WeakMap<K extends object, V> { }
|
||||
|
||||
interface WeakMapConstructor {
|
||||
new <K, V>(iterable: Iterable<[K, V]>): WeakMap<K, V>;
|
||||
new <K extends object, V>(iterable: Iterable<[K, V]>): WeakMap<K, V>;
|
||||
}
|
||||
|
||||
interface Set<T> {
|
||||
@ -462,4 +462,4 @@ interface Float64ArrayConstructor {
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Float64Array;
|
||||
}
|
||||
}
|
||||
|
||||
51
lib/lib.es2015.promise.d.ts
vendored
51
lib/lib.es2015.promise.d.ts
vendored
@ -18,57 +18,6 @@ and limitations under the License.
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
/**
|
||||
* Represents the completion of an asynchronous operation
|
||||
*/
|
||||
interface Promise<T> {
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then(onfulfilled?: ((value: T) => T | PromiseLike<T>) | undefined | null, onrejected?: ((reason: any) => T | PromiseLike<T>) | undefined | null): Promise<T>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(onfulfilled: ((value: T) => T | PromiseLike<T>) | undefined | null, onrejected: (reason: any) => TResult | PromiseLike<TResult>): Promise<T | TResult>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(onfulfilled: (value: T) => TResult | PromiseLike<TResult>, onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<TResult>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult1, TResult2>(onfulfilled: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected: (reason: any) => TResult2 | PromiseLike<TResult2>): Promise<TResult1 | TResult2>;
|
||||
|
||||
/**
|
||||
* Attaches a callback for only the rejection of the Promise.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of the callback.
|
||||
*/
|
||||
catch(onrejected?: ((reason: any) => T | PromiseLike<T>) | undefined | null): Promise<T>;
|
||||
|
||||
/**
|
||||
* Attaches a callback for only the rejection of the Promise.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of the callback.
|
||||
*/
|
||||
catch<TResult>(onrejected: (reason: any) => TResult | PromiseLike<TResult>): Promise<T | TResult>;
|
||||
}
|
||||
|
||||
interface PromiseConstructor {
|
||||
/**
|
||||
* A reference to the prototype.
|
||||
|
||||
4
lib/lib.es2015.proxy.d.ts
vendored
4
lib/lib.es2015.proxy.d.ts
vendored
@ -19,7 +19,7 @@ and limitations under the License.
|
||||
|
||||
|
||||
interface ProxyHandler<T> {
|
||||
getPrototypeOf? (target: T): {} | null;
|
||||
getPrototypeOf? (target: T): object | null;
|
||||
setPrototypeOf? (target: T, v: any): boolean;
|
||||
isExtensible? (target: T): boolean;
|
||||
preventExtensions? (target: T): boolean;
|
||||
@ -32,7 +32,7 @@ interface ProxyHandler<T> {
|
||||
enumerate? (target: T): PropertyKey[];
|
||||
ownKeys? (target: T): PropertyKey[];
|
||||
apply? (target: T, thisArg: any, argArray?: any): any;
|
||||
construct? (target: T, argArray: any, newTarget?: any): {};
|
||||
construct? (target: T, argArray: any, newTarget?: any): object
|
||||
}
|
||||
|
||||
interface ProxyConstructor {
|
||||
|
||||
2
lib/lib.es2015.symbol.d.ts
vendored
2
lib/lib.es2015.symbol.d.ts
vendored
@ -23,7 +23,7 @@ interface Symbol {
|
||||
toString(): string;
|
||||
|
||||
/** Returns the primitive value of the specified object. */
|
||||
valueOf(): Object;
|
||||
valueOf(): symbol;
|
||||
}
|
||||
|
||||
interface SymbolConstructor {
|
||||
|
||||
4
lib/lib.es2015.symbol.wellknown.d.ts
vendored
4
lib/lib.es2015.symbol.wellknown.d.ts
vendored
@ -130,7 +130,7 @@ interface Map<K, V> {
|
||||
readonly [Symbol.toStringTag]: "Map";
|
||||
}
|
||||
|
||||
interface WeakMap<K, V>{
|
||||
interface WeakMap<K extends object, V>{
|
||||
readonly [Symbol.toStringTag]: "WeakMap";
|
||||
}
|
||||
|
||||
@ -344,4 +344,4 @@ interface Float32Array {
|
||||
*/
|
||||
interface Float64Array {
|
||||
readonly [Symbol.toStringTag]: "Float64Array";
|
||||
}
|
||||
}
|
||||
|
||||
50
lib/lib.es5.d.ts
vendored
50
lib/lib.es5.d.ts
vendored
@ -157,23 +157,17 @@ interface ObjectConstructor {
|
||||
getOwnPropertyNames(o: any): string[];
|
||||
|
||||
/**
|
||||
* Creates an object that has null prototype.
|
||||
* @param o Object to use as a prototype. May be null
|
||||
* Creates an object that has the specified prototype or that has null prototype.
|
||||
* @param o Object to use as a prototype. May be null.
|
||||
*/
|
||||
create(o: null): any;
|
||||
|
||||
/**
|
||||
* Creates an object that has the specified prototype, and that optionally contains specified properties.
|
||||
* @param o Object to use as a prototype. May be null
|
||||
*/
|
||||
create<T>(o: T): T;
|
||||
create<T extends object>(o: T | null): T | object;
|
||||
|
||||
/**
|
||||
* Creates an object that has the specified prototype, and that optionally contains specified properties.
|
||||
* @param o Object to use as a prototype. May be null
|
||||
* @param properties JavaScript object that contains one or more property descriptors.
|
||||
*/
|
||||
create(o: any, properties: PropertyDescriptorMap): any;
|
||||
create(o: object | null, properties: PropertyDescriptorMap): any;
|
||||
|
||||
/**
|
||||
* Adds a property to an object, or modifies attributes of an existing property.
|
||||
@ -361,14 +355,14 @@ interface String {
|
||||
|
||||
/**
|
||||
* Replaces text in a string, using a regular expression or search string.
|
||||
* @param searchValue A string that represents the regular expression.
|
||||
* @param searchValue A string to search for.
|
||||
* @param replaceValue A string containing the text to replace for every successful match of searchValue in this string.
|
||||
*/
|
||||
replace(searchValue: string, replaceValue: string): string;
|
||||
|
||||
/**
|
||||
* Replaces text in a string, using a regular expression or search string.
|
||||
* @param searchValue A string that represents the regular expression.
|
||||
* @param searchValue A string to search for.
|
||||
* @param replacer A function that returns the replacement text.
|
||||
*/
|
||||
replace(searchValue: string, replacer: (substring: string, ...args: any[]) => string): string;
|
||||
@ -1336,39 +1330,27 @@ interface PromiseLike<T> {
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then(
|
||||
onfulfilled?: ((value: T) => T | PromiseLike<T>) | undefined | null,
|
||||
onrejected?: ((reason: any) => T | PromiseLike<T>) | undefined | null): PromiseLike<T>;
|
||||
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): PromiseLike<TResult1 | TResult2>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the completion of an asynchronous operation
|
||||
*/
|
||||
interface Promise<T> {
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(
|
||||
onfulfilled: ((value: T) => T | PromiseLike<T>) | undefined | null,
|
||||
onrejected: (reason: any) => TResult | PromiseLike<TResult>): PromiseLike<T | TResult>;
|
||||
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* Attaches a callback for only the rejection of the Promise.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
* @returns A Promise for the completion of the callback.
|
||||
*/
|
||||
then<TResult>(
|
||||
onfulfilled: (value: T) => TResult | PromiseLike<TResult>,
|
||||
onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): PromiseLike<TResult>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult1, TResult2>(
|
||||
onfulfilled: (value: T) => TResult1 | PromiseLike<TResult1>,
|
||||
onrejected: (reason: any) => TResult2 | PromiseLike<TResult2>): PromiseLike<TResult1 | TResult2>;
|
||||
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>;
|
||||
}
|
||||
|
||||
interface ArrayLike<T> {
|
||||
|
||||
2090
lib/lib.es6.d.ts
vendored
2090
lib/lib.es6.d.ts
vendored
File diff suppressed because it is too large
Load Diff
797
lib/lib.webworker.d.ts
vendored
797
lib/lib.webworker.d.ts
vendored
File diff suppressed because it is too large
Load Diff
38
lib/protocol.d.ts
vendored
38
lib/protocol.d.ts
vendored
@ -734,9 +734,9 @@ declare namespace ts.server.protocol {
|
||||
*/
|
||||
formatOptions?: FormatCodeSettings;
|
||||
/**
|
||||
* The host's additional supported file extensions
|
||||
* The host's additional supported .js file extensions
|
||||
*/
|
||||
extraFileExtensions?: FileExtensionInfo[];
|
||||
extraFileExtensions?: JsFileExtensionInfo[];
|
||||
}
|
||||
/**
|
||||
* Configure request; value of command field is "configure". Specifies
|
||||
@ -905,6 +905,10 @@ declare namespace ts.server.protocol {
|
||||
* List of files names that should be recompiled
|
||||
*/
|
||||
fileNames: string[];
|
||||
/**
|
||||
* true if project uses outFile or out compiler option
|
||||
*/
|
||||
projectUsesOutFile: boolean;
|
||||
}
|
||||
/**
|
||||
* Response for CompileOnSaveAffectedFileListRequest request;
|
||||
@ -1352,6 +1356,17 @@ declare namespace ts.server.protocol {
|
||||
command: CommandTypes.Geterr;
|
||||
arguments: GeterrRequestArgs;
|
||||
}
|
||||
type RequestCompletedEventName = "requestCompleted";
|
||||
/**
|
||||
* Event that is sent when server have finished processing request with specified id.
|
||||
*/
|
||||
interface RequestCompletedEvent extends Event {
|
||||
event: RequestCompletedEventName;
|
||||
body: RequestCompletedEventBody;
|
||||
}
|
||||
interface RequestCompletedEventBody {
|
||||
request_seq: number;
|
||||
}
|
||||
/**
|
||||
* Item of diagnostic information found in a DiagnosticEvent message.
|
||||
*/
|
||||
@ -1727,6 +1742,7 @@ declare namespace ts.server.protocol {
|
||||
insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
|
||||
insertSpaceBeforeFunctionParenthesis?: boolean;
|
||||
@ -1775,6 +1791,7 @@ declare namespace ts.server.protocol {
|
||||
outDir?: string;
|
||||
outFile?: string;
|
||||
paths?: MapLike<string[]>;
|
||||
plugins?: PluginImport[];
|
||||
preserveConstEnums?: boolean;
|
||||
project?: string;
|
||||
reactNamespace?: string;
|
||||
@ -1798,9 +1815,10 @@ declare namespace ts.server.protocol {
|
||||
namespace JsxEmit {
|
||||
type None = "None";
|
||||
type Preserve = "Preserve";
|
||||
type ReactNative = "ReactNative";
|
||||
type React = "React";
|
||||
}
|
||||
type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React;
|
||||
type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.ReactNative;
|
||||
namespace ModuleKind {
|
||||
type None = "None";
|
||||
type CommonJS = "CommonJS";
|
||||
@ -1856,17 +1874,25 @@ declare namespace ts.server.protocol {
|
||||
[option: string]: string[] | boolean | undefined;
|
||||
}
|
||||
|
||||
interface FileExtensionInfo {
|
||||
interface JsFileExtensionInfo {
|
||||
extension: string;
|
||||
scriptKind: ScriptKind;
|
||||
isMixedContent: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of objects whose values are all of the same type.
|
||||
* The `in` and `for-in` operators can *not* be safely used,
|
||||
* since `Object.prototype` may be modified by outside code.
|
||||
*/
|
||||
interface MapLike<T> {
|
||||
[index: string]: T;
|
||||
}
|
||||
|
||||
type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]>;
|
||||
interface PluginImport {
|
||||
name: string;
|
||||
}
|
||||
|
||||
type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[];
|
||||
}
|
||||
declare namespace ts {
|
||||
// these types are empty stubs for types from services and should not be used directly
|
||||
|
||||
16590
lib/tsc.js
16590
lib/tsc.js
File diff suppressed because it is too large
Load Diff
42501
lib/tsserver.js
42501
lib/tsserver.js
File diff suppressed because it is too large
Load Diff
1521
lib/tsserverlibrary.d.ts
vendored
1521
lib/tsserverlibrary.d.ts
vendored
File diff suppressed because it is too large
Load Diff
26650
lib/tsserverlibrary.js
26650
lib/tsserverlibrary.js
File diff suppressed because it is too large
Load Diff
960
lib/typescript.d.ts
vendored
960
lib/typescript.d.ts
vendored
File diff suppressed because it is too large
Load Diff
25718
lib/typescript.js
25718
lib/typescript.js
File diff suppressed because it is too large
Load Diff
960
lib/typescriptServices.d.ts
vendored
960
lib/typescriptServices.d.ts
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -60,7 +60,7 @@
|
||||
"gulp-insert": "latest",
|
||||
"gulp-newer": "latest",
|
||||
"gulp-sourcemaps": "latest",
|
||||
"gulp-typescript": "3.1.3",
|
||||
"gulp-typescript": "3.1.5",
|
||||
"into-stream": "latest",
|
||||
"istanbul": "latest",
|
||||
"jake": "latest",
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
var tslint = require("tslint");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
|
||||
function getLinterOptions() {
|
||||
return {
|
||||
@ -9,7 +10,7 @@ function getLinterOptions() {
|
||||
};
|
||||
}
|
||||
function getLinterConfiguration() {
|
||||
return require("../tslint.json");
|
||||
return tslint.Configuration.loadConfigurationFromPath(path.join(__dirname, "../tslint.json"));
|
||||
}
|
||||
|
||||
function lintFileContents(options, configuration, path, contents) {
|
||||
|
||||
@ -2,52 +2,94 @@ import * as Lint from "tslint/lib";
|
||||
import * as ts from "typescript";
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static FAILURE_STRING_FACTORY = (name: string, currently: string) => `Tag boolean argument as '${name}' (currently '${currently}')`;
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
const program = ts.createProgram([sourceFile.fileName], Lint.createCompilerOptions());
|
||||
const checker = program.getTypeChecker();
|
||||
return this.applyWithWalker(new BooleanTriviaWalker(checker, program.getSourceFile(sourceFile.fileName), this.getOptions()));
|
||||
return this.applyWithFunction(sourceFile, ctx => walk(ctx));
|
||||
}
|
||||
}
|
||||
|
||||
class BooleanTriviaWalker extends Lint.RuleWalker {
|
||||
constructor(private checker: ts.TypeChecker, file: ts.SourceFile, opts: Lint.IOptions) {
|
||||
super(file, opts);
|
||||
}
|
||||
function walk(ctx: Lint.WalkContext<void>): void {
|
||||
const { sourceFile } = ctx;
|
||||
ts.forEachChild(sourceFile, function recur(node: ts.Node): void {
|
||||
if (node.kind === ts.SyntaxKind.CallExpression) {
|
||||
checkCall(node as ts.CallExpression);
|
||||
}
|
||||
ts.forEachChild(node, recur);
|
||||
});
|
||||
|
||||
visitCallExpression(node: ts.CallExpression) {
|
||||
super.visitCallExpression(node);
|
||||
if (node.arguments && node.arguments.some(arg => arg.kind === ts.SyntaxKind.TrueKeyword || arg.kind === ts.SyntaxKind.FalseKeyword)) {
|
||||
const targetCallSignature = this.checker.getResolvedSignature(node);
|
||||
if (!!targetCallSignature) {
|
||||
const targetParameters = targetCallSignature.getParameters();
|
||||
const source = this.getSourceFile();
|
||||
for (let index = 0; index < targetParameters.length; index++) {
|
||||
const param = targetParameters[index];
|
||||
const arg = node.arguments[index];
|
||||
if (!(arg && param)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const argType = this.checker.getContextualType(arg);
|
||||
if (argType && (argType.getFlags() & ts.TypeFlags.Boolean)) {
|
||||
if (arg.kind !== ts.SyntaxKind.TrueKeyword && arg.kind !== ts.SyntaxKind.FalseKeyword) {
|
||||
continue;
|
||||
}
|
||||
let triviaContent: string;
|
||||
const ranges = ts.getLeadingCommentRanges(arg.getFullText(), 0);
|
||||
if (ranges && ranges.length === 1 && ranges[0].kind === ts.SyntaxKind.MultiLineCommentTrivia) {
|
||||
triviaContent = arg.getFullText().slice(ranges[0].pos + 2, ranges[0].end - 2); // +/-2 to remove /**/
|
||||
}
|
||||
|
||||
const paramName = param.getName();
|
||||
if (triviaContent !== paramName && triviaContent !== paramName + ":") {
|
||||
this.addFailure(this.createFailure(arg.getStart(source), arg.getWidth(source), Rule.FAILURE_STRING_FACTORY(param.getName(), triviaContent)));
|
||||
}
|
||||
}
|
||||
}
|
||||
function checkCall(node: ts.CallExpression): void {
|
||||
if (!shouldIgnoreCalledExpression(node.expression)) {
|
||||
for (const arg of node.arguments) {
|
||||
checkArg(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Skip certain function/method names whose parameter names are not informative. */
|
||||
function shouldIgnoreCalledExpression(expression: ts.Expression): boolean {
|
||||
if (expression.kind === ts.SyntaxKind.PropertyAccessExpression) {
|
||||
const methodName = (expression as ts.PropertyAccessExpression).name.text;
|
||||
if (methodName.indexOf("set") === 0) {
|
||||
return true;
|
||||
}
|
||||
switch (methodName) {
|
||||
case "apply":
|
||||
case "assert":
|
||||
case "call":
|
||||
case "equal":
|
||||
case "fail":
|
||||
case "isTrue":
|
||||
case "output":
|
||||
case "stringify":
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (expression.kind === ts.SyntaxKind.Identifier) {
|
||||
const functionName = (expression as ts.Identifier).text;
|
||||
if (functionName.indexOf("set") === 0) {
|
||||
return true;
|
||||
}
|
||||
switch (functionName) {
|
||||
case "assert":
|
||||
case "contains":
|
||||
case "createAnonymousType":
|
||||
case "createImportSpecifier":
|
||||
case "createProperty":
|
||||
case "createSignature":
|
||||
case "resolveName":
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkArg(arg: ts.Expression): void {
|
||||
if (!isTrivia(arg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ranges = ts.getTrailingCommentRanges(sourceFile.text, arg.pos) || ts.getLeadingCommentRanges(sourceFile.text, arg.pos);
|
||||
if (ranges === undefined || ranges.length !== 1 || ranges[0].kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
|
||||
ctx.addFailureAtNode(arg, "Tag boolean argument with parameter name");
|
||||
return;
|
||||
}
|
||||
|
||||
const range = ranges[0];
|
||||
const argStart = arg.getStart(sourceFile);
|
||||
if (range.end + 1 !== argStart && sourceFile.text.slice(range.end, argStart).indexOf("\n") === -1) {
|
||||
ctx.addFailureAtNode(arg, "There should be 1 space between an argument and its comment.");
|
||||
}
|
||||
}
|
||||
|
||||
function isTrivia(arg: ts.Expression): boolean {
|
||||
switch (arg.kind) {
|
||||
case ts.SyntaxKind.TrueKeyword:
|
||||
case ts.SyntaxKind.FalseKeyword:
|
||||
case ts.SyntaxKind.NullKeyword:
|
||||
return true;
|
||||
case ts.SyntaxKind.Identifier:
|
||||
return (arg as ts.Identifier).originalKeywordKind === ts.SyntaxKind.UndefinedKeyword;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,50 +9,56 @@ export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static ELSE_FAILURE_STRING = "'else' should not be on the same line as the preceeding block's curly brace";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new NextLineWalker(sourceFile, this.getOptions()));
|
||||
const options = this.getOptions().ruleArguments;
|
||||
const checkCatch = options.indexOf(OPTION_CATCH) !== -1;
|
||||
const checkElse = options.indexOf(OPTION_ELSE) !== -1;
|
||||
return this.applyWithFunction(sourceFile, ctx => walk(ctx, checkCatch, checkElse));
|
||||
}
|
||||
}
|
||||
|
||||
class NextLineWalker extends Lint.RuleWalker {
|
||||
public visitIfStatement(node: ts.IfStatement) {
|
||||
const sourceFile = node.getSourceFile();
|
||||
const thenStatement = node.thenStatement;
|
||||
|
||||
const elseStatement = node.elseStatement;
|
||||
if (!!elseStatement) {
|
||||
// find the else keyword
|
||||
const elseKeyword = getFirstChildOfKind(node, ts.SyntaxKind.ElseKeyword);
|
||||
if (this.hasOption(OPTION_ELSE) && !!elseKeyword) {
|
||||
const thenStatementEndLoc = sourceFile.getLineAndCharacterOfPosition(thenStatement.getEnd());
|
||||
const elseKeywordLoc = sourceFile.getLineAndCharacterOfPosition(elseKeyword.getStart(sourceFile));
|
||||
if (thenStatementEndLoc.line === elseKeywordLoc.line) {
|
||||
const failure = this.createFailure(elseKeyword.getStart(sourceFile), elseKeyword.getWidth(sourceFile), Rule.ELSE_FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
}
|
||||
}
|
||||
function walk(ctx: Lint.WalkContext<void>, checkCatch: boolean, checkElse: boolean): void {
|
||||
const { sourceFile } = ctx;
|
||||
function recur(node: ts.Node): void {
|
||||
switch (node.kind) {
|
||||
case ts.SyntaxKind.IfStatement:
|
||||
checkIf(node as ts.IfStatement);
|
||||
break;
|
||||
case ts.SyntaxKind.TryStatement:
|
||||
checkTry(node as ts.TryStatement);
|
||||
break;
|
||||
}
|
||||
|
||||
super.visitIfStatement(node);
|
||||
ts.forEachChild(node, recur);
|
||||
}
|
||||
|
||||
public visitTryStatement(node: ts.TryStatement) {
|
||||
const sourceFile = node.getSourceFile();
|
||||
const catchClause = node.catchClause;
|
||||
function checkIf(node: ts.IfStatement): void {
|
||||
const { thenStatement, elseStatement } = node;
|
||||
if (!elseStatement) {
|
||||
return;
|
||||
}
|
||||
|
||||
// "visit" try block
|
||||
const tryBlock = node.tryBlock;
|
||||
|
||||
if (this.hasOption(OPTION_CATCH) && !!catchClause) {
|
||||
const tryClosingBrace = tryBlock.getLastToken(sourceFile);
|
||||
const catchKeyword = catchClause.getFirstToken(sourceFile);
|
||||
const tryClosingBraceLoc = sourceFile.getLineAndCharacterOfPosition(tryClosingBrace.getEnd());
|
||||
const catchKeywordLoc = sourceFile.getLineAndCharacterOfPosition(catchKeyword.getStart(sourceFile));
|
||||
if (tryClosingBraceLoc.line === catchKeywordLoc.line) {
|
||||
const failure = this.createFailure(catchKeyword.getStart(sourceFile), catchKeyword.getWidth(sourceFile), Rule.CATCH_FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
// find the else keyword
|
||||
const elseKeyword = getFirstChildOfKind(node, ts.SyntaxKind.ElseKeyword);
|
||||
if (checkElse && !!elseKeyword) {
|
||||
const thenStatementEndLoc = sourceFile.getLineAndCharacterOfPosition(thenStatement.getEnd());
|
||||
const elseKeywordLoc = sourceFile.getLineAndCharacterOfPosition(elseKeyword.getStart(sourceFile));
|
||||
if (thenStatementEndLoc.line === elseKeywordLoc.line) {
|
||||
ctx.addFailureAtNode(elseKeyword, Rule.ELSE_FAILURE_STRING);
|
||||
}
|
||||
}
|
||||
super.visitTryStatement(node);
|
||||
}
|
||||
|
||||
function checkTry({ tryBlock, catchClause }: ts.TryStatement): void {
|
||||
if (!checkCatch || !catchClause) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tryClosingBrace = tryBlock.getLastToken(sourceFile);
|
||||
const catchKeyword = catchClause.getFirstToken(sourceFile);
|
||||
const tryClosingBraceLoc = sourceFile.getLineAndCharacterOfPosition(tryClosingBrace.getEnd());
|
||||
const catchKeywordLoc = sourceFile.getLineAndCharacterOfPosition(catchKeyword.getStart(sourceFile));
|
||||
if (tryClosingBraceLoc.line === catchKeywordLoc.line) {
|
||||
ctx.addFailureAtNode(catchKeyword, Rule.CATCH_FAILURE_STRING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
16
scripts/tslint/noBomRule.ts
Normal file
16
scripts/tslint/noBomRule.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import * as Lint from "tslint/lib";
|
||||
import * as ts from "typescript";
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static FAILURE_STRING = "This file has a BOM.";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
return this.applyWithFunction(sourceFile, walk);
|
||||
}
|
||||
}
|
||||
|
||||
function walk(ctx: Lint.WalkContext<void>): void {
|
||||
if (ctx.sourceFile.text[0] === "\ufeff") {
|
||||
ctx.addFailure(0, 1, Rule.FAILURE_STRING);
|
||||
}
|
||||
}
|
||||
@ -1,20 +1,19 @@
|
||||
import * as Lint from "tslint/lib";
|
||||
import * as ts from "typescript";
|
||||
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static FAILURE_STRING = "Don't use the 'in' keyword - use 'hasProperty' to check for key presence instead";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new InWalker(sourceFile, this.getOptions()));
|
||||
return this.applyWithFunction(sourceFile, walk);
|
||||
}
|
||||
}
|
||||
|
||||
class InWalker extends Lint.RuleWalker {
|
||||
visitNode(node: ts.Node) {
|
||||
super.visitNode(node);
|
||||
if (node.kind === ts.SyntaxKind.InKeyword && node.parent && node.parent.kind === ts.SyntaxKind.BinaryExpression) {
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING));
|
||||
function walk(ctx: Lint.WalkContext<void>): void {
|
||||
ts.forEachChild(ctx.sourceFile, recur);
|
||||
function recur(node: ts.Node): void {
|
||||
if (node.kind === ts.SyntaxKind.InKeyword && node.parent.kind === ts.SyntaxKind.BinaryExpression) {
|
||||
ctx.addFailureAtNode(node, Rule.FAILURE_STRING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,44 +1,55 @@
|
||||
import * as Lint from "tslint/lib";
|
||||
import * as ts from "typescript";
|
||||
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static POSTFIX_FAILURE_STRING = "Don't use '++' or '--' postfix operators outside statements or for loops.";
|
||||
public static PREFIX_FAILURE_STRING = "Don't use '++' or '--' prefix operators.";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new IncrementDecrementWalker(sourceFile, this.getOptions()));
|
||||
return this.applyWithFunction(sourceFile, walk);
|
||||
}
|
||||
}
|
||||
|
||||
class IncrementDecrementWalker extends Lint.RuleWalker {
|
||||
function walk(ctx: Lint.WalkContext<void>): void {
|
||||
ts.forEachChild(ctx.sourceFile, recur);
|
||||
function recur(node: ts.Node): void {
|
||||
switch (node.kind) {
|
||||
case ts.SyntaxKind.PrefixUnaryExpression:
|
||||
const { operator } = node as ts.PrefixUnaryExpression;
|
||||
if (operator === ts.SyntaxKind.PlusPlusToken || operator === ts.SyntaxKind.MinusMinusToken) {
|
||||
check(node as ts.PrefixUnaryExpression);
|
||||
}
|
||||
break;
|
||||
|
||||
visitPostfixUnaryExpression(node: ts.PostfixUnaryExpression) {
|
||||
super.visitPostfixUnaryExpression(node);
|
||||
if (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator == ts.SyntaxKind.MinusMinusToken) {
|
||||
this.visitIncrementDecrement(node);
|
||||
case ts.SyntaxKind.PostfixUnaryExpression:
|
||||
check(node as ts.PostfixUnaryExpression);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
visitPrefixUnaryExpression(node: ts.PrefixUnaryExpression) {
|
||||
super.visitPrefixUnaryExpression(node);
|
||||
if (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator == ts.SyntaxKind.MinusMinusToken) {
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.PREFIX_FAILURE_STRING));
|
||||
function check(node: ts.UnaryExpression): void {
|
||||
if (!isAllowedLocation(node.parent!)) {
|
||||
ctx.addFailureAtNode(node, Rule.POSTFIX_FAILURE_STRING);
|
||||
}
|
||||
}
|
||||
|
||||
visitIncrementDecrement(node: ts.UnaryExpression) {
|
||||
if (node.parent && (
|
||||
// Can be a statement
|
||||
node.parent.kind === ts.SyntaxKind.ExpressionStatement ||
|
||||
// Can be directly in a for-statement
|
||||
node.parent.kind === ts.SyntaxKind.ForStatement ||
|
||||
// Can be in a comma operator in a for statement (`for (let a = 0, b = 10; a < b; a++, b--)`)
|
||||
node.parent.kind === ts.SyntaxKind.BinaryExpression &&
|
||||
(<ts.BinaryExpression>node.parent).operatorToken.kind === ts.SyntaxKind.CommaToken &&
|
||||
node.parent.parent.kind === ts.SyntaxKind.ForStatement)) {
|
||||
return;
|
||||
}
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.POSTFIX_FAILURE_STRING));
|
||||
}
|
||||
}
|
||||
|
||||
function isAllowedLocation(node: ts.Node): boolean {
|
||||
switch (node.kind) {
|
||||
// Can be a statement
|
||||
case ts.SyntaxKind.ExpressionStatement:
|
||||
return true;
|
||||
|
||||
// Can be directly in a for-statement
|
||||
case ts.SyntaxKind.ForStatement:
|
||||
return true;
|
||||
|
||||
// Can be in a comma operator in a for statement (`for (let a = 0, b = 10; a < b; a++, b--)`)
|
||||
case ts.SyntaxKind.BinaryExpression:
|
||||
return (node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.CommaToken &&
|
||||
node.parent!.kind === ts.SyntaxKind.ForStatement;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,25 +1,25 @@
|
||||
import * as Lint from "tslint/lib";
|
||||
import * as ts from "typescript";
|
||||
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static TRAILING_FAILURE_STRING = "Excess trailing whitespace found around type assertion.";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new TypeAssertionWhitespaceWalker(sourceFile, this.getOptions()));
|
||||
return this.applyWithFunction(sourceFile, walk);
|
||||
}
|
||||
}
|
||||
|
||||
class TypeAssertionWhitespaceWalker extends Lint.RuleWalker {
|
||||
public visitNode(node: ts.Node) {
|
||||
function walk(ctx: Lint.WalkContext<void>): void {
|
||||
ts.forEachChild(ctx.sourceFile, recur);
|
||||
function recur(node: ts.Node) {
|
||||
if (node.kind === ts.SyntaxKind.TypeAssertionExpression) {
|
||||
const refined = node as ts.TypeAssertion;
|
||||
const leftSideWhitespaceStart = refined.type.getEnd() + 1;
|
||||
const rightSideWhitespaceEnd = refined.expression.getStart();
|
||||
if (leftSideWhitespaceStart !== rightSideWhitespaceEnd) {
|
||||
this.addFailure(this.createFailure(leftSideWhitespaceStart, rightSideWhitespaceEnd, Rule.TRAILING_FAILURE_STRING));
|
||||
ctx.addFailure(leftSideWhitespaceStart, rightSideWhitespaceEnd, Rule.TRAILING_FAILURE_STRING);
|
||||
}
|
||||
}
|
||||
super.visitNode(node);
|
||||
ts.forEachChild(node, recur);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import * as Lint from "tslint/lib";
|
||||
import * as ts from "typescript";
|
||||
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static LEADING_FAILURE_STRING = "No leading whitespace found on single-line object literal.";
|
||||
public static TRAILING_FAILURE_STRING = "No trailing whitespace found on single-line object literal.";
|
||||
@ -9,34 +8,37 @@ export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static TRAILING_EXCESS_FAILURE_STRING = "Excess trailing whitespace found on single-line object literal.";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new ObjectLiteralSpaceWalker(sourceFile, this.getOptions()));
|
||||
return this.applyWithFunction(sourceFile, walk);
|
||||
}
|
||||
}
|
||||
|
||||
class ObjectLiteralSpaceWalker extends Lint.RuleWalker {
|
||||
public visitNode(node: ts.Node) {
|
||||
function walk(ctx: Lint.WalkContext<void>): void {
|
||||
const { sourceFile } = ctx;
|
||||
ts.forEachChild(sourceFile, recur);
|
||||
function recur(node: ts.Node): void {
|
||||
if (node.kind === ts.SyntaxKind.ObjectLiteralExpression) {
|
||||
const literal = node as ts.ObjectLiteralExpression;
|
||||
const text = literal.getText();
|
||||
if (text.match(/^{[^\n]+}$/g)) {
|
||||
if (text.charAt(1) !== " ") {
|
||||
const failure = this.createFailure(node.pos, node.getWidth(), Rule.LEADING_FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
}
|
||||
if (text.charAt(2) === " ") {
|
||||
const failure = this.createFailure(node.pos + 2, 1, Rule.LEADING_EXCESS_FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
}
|
||||
if (text.charAt(text.length - 2) !== " ") {
|
||||
const failure = this.createFailure(node.pos, node.getWidth(), Rule.TRAILING_FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
}
|
||||
if (text.charAt(text.length - 3) === " ") {
|
||||
const failure = this.createFailure(node.pos + node.getWidth() - 3, 1, Rule.TRAILING_EXCESS_FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
}
|
||||
}
|
||||
check(node as ts.ObjectLiteralExpression);
|
||||
}
|
||||
ts.forEachChild(node, recur);
|
||||
}
|
||||
|
||||
function check(node: ts.ObjectLiteralExpression): void {
|
||||
const text = node.getText(sourceFile);
|
||||
if (!text.match(/^{[^\n]+}$/g)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (text.charAt(1) !== " ") {
|
||||
ctx.addFailureAtNode(node, Rule.LEADING_FAILURE_STRING);
|
||||
}
|
||||
if (text.charAt(2) === " ") {
|
||||
ctx.addFailureAt(node.pos + 2, 1, Rule.LEADING_EXCESS_FAILURE_STRING);
|
||||
}
|
||||
if (text.charAt(text.length - 2) !== " ") {
|
||||
ctx.addFailureAtNode(node, Rule.TRAILING_FAILURE_STRING);
|
||||
}
|
||||
if (text.charAt(text.length - 3) === " ") {
|
||||
ctx.addFailureAt(node.pos + node.getWidth() - 3, 1, Rule.TRAILING_EXCESS_FAILURE_STRING);
|
||||
}
|
||||
super.visitNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"strictNullChecks": true,
|
||||
"module": "commonjs",
|
||||
"outDir": "../../built/local/tslint"
|
||||
}
|
||||
|
||||
@ -1,34 +1,36 @@
|
||||
import * as Lint from "tslint/lib";
|
||||
import * as ts from "typescript";
|
||||
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static FAILURE_STRING = "The '|' and '&' operators must be surrounded by single spaces";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new TypeOperatorSpacingWalker(sourceFile, this.getOptions()));
|
||||
return this.applyWithFunction(sourceFile, walk);
|
||||
}
|
||||
}
|
||||
|
||||
class TypeOperatorSpacingWalker extends Lint.RuleWalker {
|
||||
public visitNode(node: ts.Node) {
|
||||
function walk(ctx: Lint.WalkContext<void>): void {
|
||||
const { sourceFile } = ctx;
|
||||
ts.forEachChild(sourceFile, recur);
|
||||
function recur(node: ts.Node): void {
|
||||
if (node.kind === ts.SyntaxKind.UnionType || node.kind === ts.SyntaxKind.IntersectionType) {
|
||||
const types = (<ts.UnionOrIntersectionTypeNode>node).types;
|
||||
let expectedStart = types[0].end + 2; // space, | or &
|
||||
for (let i = 1; i < types.length; i++) {
|
||||
const currentType = types[i];
|
||||
if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) {
|
||||
const sourceFile = currentType.getSourceFile();
|
||||
const previousTypeEndPos = sourceFile.getLineAndCharacterOfPosition(types[i - 1].end);
|
||||
const currentTypeStartPos = sourceFile.getLineAndCharacterOfPosition(currentType.pos);
|
||||
if (previousTypeEndPos.line === currentTypeStartPos.line) {
|
||||
const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
}
|
||||
}
|
||||
expectedStart = currentType.end + 2;
|
||||
}
|
||||
check((node as ts.UnionOrIntersectionTypeNode).types);
|
||||
}
|
||||
ts.forEachChild(node, recur);
|
||||
}
|
||||
|
||||
function check(types: ts.TypeNode[]): void {
|
||||
let expectedStart = types[0].end + 2; // space, | or &
|
||||
for (let i = 1; i < types.length; i++) {
|
||||
const currentType = types[i];
|
||||
if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) {
|
||||
const previousTypeEndPos = sourceFile.getLineAndCharacterOfPosition(types[i - 1].end);
|
||||
const currentTypeStartPos = sourceFile.getLineAndCharacterOfPosition(currentType.pos);
|
||||
if (previousTypeEndPos.line === currentTypeStartPos.line) {
|
||||
ctx.addFailureAtNode(currentType, Rule.FAILURE_STRING);
|
||||
}
|
||||
}
|
||||
expectedStart = currentType.end + 2;
|
||||
}
|
||||
super.visitNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,7 +182,7 @@ namespace ts {
|
||||
return bindSourceFile;
|
||||
|
||||
function bindInStrictMode(file: SourceFile, opts: CompilerOptions): boolean {
|
||||
if (opts.alwaysStrict && !isDeclarationFile(file)) {
|
||||
if ((opts.alwaysStrict === undefined ? opts.strict : opts.alwaysStrict) && !isDeclarationFile(file)) {
|
||||
// bind in strict mode source files with alwaysStrict option
|
||||
return true;
|
||||
}
|
||||
@ -259,12 +259,13 @@ namespace ts {
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return (<ExportAssignment>node).isExportEquals ? "export=" : "default";
|
||||
case SyntaxKind.BinaryExpression:
|
||||
switch (getSpecialPropertyAssignmentKind(node)) {
|
||||
switch (getSpecialPropertyAssignmentKind(node as BinaryExpression)) {
|
||||
case SpecialPropertyAssignmentKind.ModuleExports:
|
||||
// module.exports = ...
|
||||
return "export=";
|
||||
case SpecialPropertyAssignmentKind.ExportsProperty:
|
||||
case SpecialPropertyAssignmentKind.ThisProperty:
|
||||
case SpecialPropertyAssignmentKind.Property:
|
||||
// exports.x = ... or this.y = ...
|
||||
return ((node as BinaryExpression).left as PropertyAccessExpression).name.text;
|
||||
case SpecialPropertyAssignmentKind.PrototypeProperty:
|
||||
@ -417,7 +418,7 @@ namespace ts {
|
||||
return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
else {
|
||||
return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
|
||||
return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -446,13 +447,13 @@ namespace ts {
|
||||
(symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) |
|
||||
(symbolFlags & SymbolFlags.Type ? SymbolFlags.ExportType : 0) |
|
||||
(symbolFlags & SymbolFlags.Namespace ? SymbolFlags.ExportNamespace : 0);
|
||||
const local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes);
|
||||
const local = declareSymbol(container.locals, /*parent*/ undefined, node, exportKind, symbolExcludes);
|
||||
local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
|
||||
node.localSymbol = local;
|
||||
return local;
|
||||
}
|
||||
else {
|
||||
return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes);
|
||||
return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -669,6 +670,12 @@ namespace ts {
|
||||
case SyntaxKind.CallExpression:
|
||||
bindCallExpressionFlow(<CallExpression>node);
|
||||
break;
|
||||
case SyntaxKind.JSDocComment:
|
||||
bindJSDocComment(<JSDoc>node);
|
||||
break;
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
bindJSDocTypedefTag(<JSDocTypedefTag>node);
|
||||
break;
|
||||
default:
|
||||
bindEachChild(node);
|
||||
break;
|
||||
@ -696,6 +703,7 @@ namespace ts {
|
||||
function isNarrowableReference(expr: Expression): boolean {
|
||||
return expr.kind === SyntaxKind.Identifier ||
|
||||
expr.kind === SyntaxKind.ThisKeyword ||
|
||||
expr.kind === SyntaxKind.SuperKeyword ||
|
||||
expr.kind === SyntaxKind.PropertyAccessExpression && isNarrowableReference((<PropertyAccessExpression>expr).expression);
|
||||
}
|
||||
|
||||
@ -956,6 +964,9 @@ namespace ts {
|
||||
const postLoopLabel = createBranchLabel();
|
||||
addAntecedent(preLoopLabel, currentFlow);
|
||||
currentFlow = preLoopLabel;
|
||||
if (node.kind === SyntaxKind.ForOfStatement) {
|
||||
bind(node.awaitModifier);
|
||||
}
|
||||
bind(node.expression);
|
||||
addAntecedent(postLoopLabel, currentFlow);
|
||||
bind(node.initializer);
|
||||
@ -1051,8 +1062,8 @@ namespace ts {
|
||||
// second -> edge that represents post-finally flow.
|
||||
// these edges are used in following scenario:
|
||||
// let a; (1)
|
||||
// try { a = someOperation(); (2)}
|
||||
// finally { (3) console.log(a) } (4)
|
||||
// try { a = someOperation(); (2)}
|
||||
// finally { (3) console.log(a) } (4)
|
||||
// (5) a
|
||||
|
||||
// flow graph for this case looks roughly like this (arrows show ):
|
||||
@ -1064,11 +1075,11 @@ namespace ts {
|
||||
// In case when we walk the flow starting from inside the finally block we want to take edge '*****' into account
|
||||
// since it ensures that finally is always reachable. However when we start outside the finally block and go through label (5)
|
||||
// then edge '*****' should be discarded because label 4 is only reachable if post-finally label-4 is reachable
|
||||
// Simply speaking code inside finally block is treated as reachable as pre-try-flow
|
||||
// Simply speaking code inside finally block is treated as reachable as pre-try-flow
|
||||
// since we conservatively assume that any line in try block can throw or return in which case we'll enter finally.
|
||||
// However code after finally is reachable only if control flow was not abrupted in try/catch or finally blocks - it should be composed from
|
||||
// final flows of these blocks without taking pre-try flow into account.
|
||||
//
|
||||
//
|
||||
// extra edges that we inject allows to control this behavior
|
||||
// if when walking the flow we step on post-finally edge - we can mark matching pre-finally edge as locked so it will be skipped.
|
||||
const preFinallyFlow: PreFinallyFlow = { flags: FlowFlags.PreFinally, antecedent: preTryFlow, lock: {} };
|
||||
@ -1331,6 +1342,26 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function bindJSDocComment(node: JSDoc) {
|
||||
forEachChild(node, n => {
|
||||
if (n.kind !== SyntaxKind.JSDocTypedefTag) {
|
||||
bind(n);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function bindJSDocTypedefTag(node: JSDocTypedefTag) {
|
||||
forEachChild(node, n => {
|
||||
// if the node has a fullName "A.B.C", that means symbol "C" was already bound
|
||||
// when we visit "fullName"; so when we visit the name "C" as the next child of
|
||||
// the jsDocTypedefTag, we should skip binding it.
|
||||
if (node.fullName && n === node.name && node.fullName.kind !== SyntaxKind.Identifier) {
|
||||
return;
|
||||
}
|
||||
bind(n);
|
||||
});
|
||||
}
|
||||
|
||||
function bindCallExpressionFlow(node: CallExpression) {
|
||||
// If the target of the call expression is a function expression or arrow function we have
|
||||
// an immediately invoked function expression (IIFE). Initialize the flowNode property to
|
||||
@ -1364,6 +1395,7 @@ namespace ts {
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
case SyntaxKind.JSDocRecordType:
|
||||
case SyntaxKind.JsxAttributes:
|
||||
return ContainerFlags.IsContainer;
|
||||
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
@ -1470,6 +1502,7 @@ namespace ts {
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.JSDocRecordType:
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
case SyntaxKind.JsxAttributes:
|
||||
// Interface/Object-types always have their children added to the 'members' of
|
||||
// their container. They are only accessible through an instance of their
|
||||
// container, and are never in scope otherwise (even inside the body of the
|
||||
@ -1512,7 +1545,7 @@ namespace ts {
|
||||
function declareSourceFileMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
return isExternalModule(file)
|
||||
? declareModuleMember(node, symbolFlags, symbolExcludes)
|
||||
: declareSymbol(file.locals, undefined, node, symbolFlags, symbolExcludes);
|
||||
: declareSymbol(file.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
|
||||
function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean {
|
||||
@ -1659,6 +1692,14 @@ namespace ts {
|
||||
return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object");
|
||||
}
|
||||
|
||||
function bindJsxAttributes(node: JsxAttributes) {
|
||||
return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__jsxAttributes");
|
||||
}
|
||||
|
||||
function bindJsxAttribute(node: JsxAttribute, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
return declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
|
||||
function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string) {
|
||||
const symbol = createSymbol(symbolFlags, name);
|
||||
addDeclarationToSymbol(symbol, node, symbolFlags);
|
||||
@ -1680,7 +1721,7 @@ namespace ts {
|
||||
blockScopeContainer.locals = createMap<Symbol>();
|
||||
addToContainerChain(blockScopeContainer);
|
||||
}
|
||||
declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes);
|
||||
declareSymbol(blockScopeContainer.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1814,7 +1855,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkStrictModeNumericLiteral(node: NumericLiteral) {
|
||||
if (inStrictMode && node.isOctalLiteral) {
|
||||
if (inStrictMode && node.numericLiteralFlags & NumericLiteralFlags.Octal) {
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Octal_literals_are_not_allowed_in_strict_mode));
|
||||
}
|
||||
}
|
||||
@ -1860,6 +1901,20 @@ namespace ts {
|
||||
}
|
||||
node.parent = parent;
|
||||
const saveInStrictMode = inStrictMode;
|
||||
|
||||
// Even though in the AST the jsdoc @typedef node belongs to the current node,
|
||||
// its symbol might be in the same scope with the current node's symbol. Consider:
|
||||
//
|
||||
// /** @typedef {string | number} MyType */
|
||||
// function foo();
|
||||
//
|
||||
// Here the current node is "foo", which is a container, but the scope of "MyType" should
|
||||
// not be inside "foo". Therefore we always bind @typedef before bind the parent node,
|
||||
// and skip binding this tag later when binding all the other jsdoc tags.
|
||||
if (isInJavaScriptFile(node)) {
|
||||
bindJSDocTypedefTagIfAny(node);
|
||||
}
|
||||
|
||||
// First we bind declaration nodes to a symbol if possible. We'll both create a symbol
|
||||
// and then potentially add the symbol to an appropriate symbol table. Possible
|
||||
// destination symbol tables are:
|
||||
@ -1894,6 +1949,27 @@ namespace ts {
|
||||
inStrictMode = saveInStrictMode;
|
||||
}
|
||||
|
||||
function bindJSDocTypedefTagIfAny(node: Node) {
|
||||
if (!node.jsDoc) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const jsDoc of node.jsDoc) {
|
||||
if (!jsDoc.tags) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const tag of jsDoc.tags) {
|
||||
if (tag.kind === SyntaxKind.JSDocTypedefTag) {
|
||||
const savedParent = parent;
|
||||
parent = jsDoc;
|
||||
bind(tag);
|
||||
parent = savedParent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateStrictModeStatementList(statements: NodeArray<Statement>) {
|
||||
if (!inStrictMode) {
|
||||
for (const statement of statements) {
|
||||
@ -1944,27 +2020,28 @@ namespace ts {
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.BinaryExpression:
|
||||
if (isInJavaScriptFile(node)) {
|
||||
const specialKind = getSpecialPropertyAssignmentKind(node);
|
||||
switch (specialKind) {
|
||||
case SpecialPropertyAssignmentKind.ExportsProperty:
|
||||
bindExportsPropertyAssignment(<BinaryExpression>node);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.ModuleExports:
|
||||
bindModuleExportsAssignment(<BinaryExpression>node);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.PrototypeProperty:
|
||||
bindPrototypePropertyAssignment(<BinaryExpression>node);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.ThisProperty:
|
||||
bindThisPropertyAssignment(<BinaryExpression>node);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.None:
|
||||
// Nothing to do
|
||||
break;
|
||||
default:
|
||||
Debug.fail("Unknown special property assignment kind");
|
||||
}
|
||||
const specialKind = getSpecialPropertyAssignmentKind(node as BinaryExpression);
|
||||
switch (specialKind) {
|
||||
case SpecialPropertyAssignmentKind.ExportsProperty:
|
||||
bindExportsPropertyAssignment(<BinaryExpression>node);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.ModuleExports:
|
||||
bindModuleExportsAssignment(<BinaryExpression>node);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.PrototypeProperty:
|
||||
bindPrototypePropertyAssignment(<BinaryExpression>node);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.ThisProperty:
|
||||
bindThisPropertyAssignment(<BinaryExpression>node);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.Property:
|
||||
bindStaticPropertyAssignment(<BinaryExpression>node);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.None:
|
||||
// Nothing to do
|
||||
break;
|
||||
default:
|
||||
Debug.fail("Unknown special property assignment kind");
|
||||
}
|
||||
return checkStrictModeBinaryExpression(<BinaryExpression>node);
|
||||
case SyntaxKind.CatchClause:
|
||||
@ -2080,6 +2157,12 @@ namespace ts {
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return bindModuleDeclaration(<ModuleDeclaration>node);
|
||||
|
||||
// Jsx-attributes
|
||||
case SyntaxKind.JsxAttributes:
|
||||
return bindJsxAttributes(<JsxAttributes>node);
|
||||
case SyntaxKind.JsxAttribute:
|
||||
return bindJsxAttribute(<JsxAttribute>node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
|
||||
|
||||
// Imports and exports
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.NamespaceImport:
|
||||
@ -2207,7 +2290,42 @@ namespace ts {
|
||||
declareSymbol(file.symbol.exports, file.symbol, <PropertyAccessExpression>node.left, SymbolFlags.Property | SymbolFlags.Export, SymbolFlags.None);
|
||||
}
|
||||
|
||||
function isExportsOrModuleExportsOrAlias(node: Node): boolean {
|
||||
return isExportsIdentifier(node) ||
|
||||
isModuleExportsPropertyAccessExpression(node) ||
|
||||
isNameOfExportsOrModuleExportsAliasDeclaration(node);
|
||||
}
|
||||
|
||||
function isNameOfExportsOrModuleExportsAliasDeclaration(node: Node) {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
const symbol = container.locals.get((<Identifier>node).text);
|
||||
if (symbol && symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.VariableDeclaration) {
|
||||
const declaration = symbol.valueDeclaration as VariableDeclaration;
|
||||
if (declaration.initializer) {
|
||||
return isExportsOrModuleExportsOrAliasOrAssignemnt(declaration.initializer);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isExportsOrModuleExportsOrAliasOrAssignemnt(node: Node): boolean {
|
||||
return isExportsOrModuleExportsOrAlias(node) ||
|
||||
(isAssignmentExpression(node, /*excludeCompoundAssignements*/ true) && (isExportsOrModuleExportsOrAliasOrAssignemnt(node.left) || isExportsOrModuleExportsOrAliasOrAssignemnt(node.right)));
|
||||
}
|
||||
|
||||
function bindModuleExportsAssignment(node: BinaryExpression) {
|
||||
// A common practice in node modules is to set 'export = module.exports = {}', this ensures that 'exports'
|
||||
// is still pointing to 'module.exports'.
|
||||
// We do not want to consider this as 'export=' since a module can have only one of these.
|
||||
// Similarlly we do not want to treat 'module.exports = exports' as an 'export='.
|
||||
const assignedExpression = getRightMostAssignedExpression(node.right);
|
||||
if (isEmptyObjectLiteral(assignedExpression) || isExportsOrModuleExportsOrAlias(assignedExpression)) {
|
||||
// Mark it as a module in case there are no other exports in the file
|
||||
setCommonJsModuleIndicator(node);
|
||||
return;
|
||||
}
|
||||
|
||||
// 'module.exports = expr' assignment
|
||||
setCommonJsModuleIndicator(node);
|
||||
declareSymbol(file.symbol.exports, file.symbol, node, SymbolFlags.Property | SymbolFlags.Export | SymbolFlags.ValueModule, SymbolFlags.None);
|
||||
@ -2215,23 +2333,30 @@ namespace ts {
|
||||
|
||||
function bindThisPropertyAssignment(node: BinaryExpression) {
|
||||
Debug.assert(isInJavaScriptFile(node));
|
||||
// Declare a 'member' if the container is an ES5 class or ES6 constructor
|
||||
if (container.kind === SyntaxKind.FunctionDeclaration || container.kind === SyntaxKind.FunctionExpression) {
|
||||
container.symbol.members = container.symbol.members || createMap<Symbol>();
|
||||
// It's acceptable for multiple 'this' assignments of the same identifier to occur
|
||||
declareSymbol(container.symbol.members, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property);
|
||||
}
|
||||
else if (container.kind === SyntaxKind.Constructor) {
|
||||
// this.foo assignment in a JavaScript class
|
||||
// Bind this property to the containing class
|
||||
const saveContainer = container;
|
||||
container = container.parent;
|
||||
const symbol = bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property, SymbolFlags.None);
|
||||
if (symbol) {
|
||||
// constructor-declared symbols can be overwritten by subsequent method declarations
|
||||
(symbol as Symbol).isReplaceableByMethod = true;
|
||||
}
|
||||
container = saveContainer;
|
||||
const container = getThisContainer(node, /*includeArrowFunctions*/ false);
|
||||
switch (container.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
// Declare a 'member' if the container is an ES5 class or ES6 constructor
|
||||
container.symbol.members = container.symbol.members || createMap<Symbol>();
|
||||
// It's acceptable for multiple 'this' assignments of the same identifier to occur
|
||||
declareSymbol(container.symbol.members, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property);
|
||||
break;
|
||||
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
// this.foo assignment in a JavaScript class
|
||||
// Bind this property to the containing class
|
||||
const containingClass = container.parent;
|
||||
const symbol = declareSymbol(hasModifier(container, ModifierFlags.Static) ? containingClass.symbol.exports : containingClass.symbol.members, containingClass.symbol, node, SymbolFlags.Property, SymbolFlags.None);
|
||||
if (symbol) {
|
||||
// symbols declared through 'this' property assignements can be overwritten by subsequent method declarations
|
||||
(symbol as Symbol).isReplaceableByMethod = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2249,24 +2374,56 @@ namespace ts {
|
||||
constructorFunction.parent = classPrototype;
|
||||
classPrototype.parent = leftSideOfAssignment;
|
||||
|
||||
const funcSymbol = container.locals.get(constructorFunction.text);
|
||||
if (!funcSymbol || !(funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) {
|
||||
bindPropertyAssignment(constructorFunction.text, leftSideOfAssignment, /*isPrototypeProperty*/ true);
|
||||
}
|
||||
|
||||
function bindStaticPropertyAssignment(node: BinaryExpression) {
|
||||
// We saw a node of the form 'x.y = z'. Declare a 'member' y on x if x was a function.
|
||||
|
||||
// Look up the function in the local scope, since prototype assignments should
|
||||
// follow the function declaration
|
||||
const leftSideOfAssignment = node.left as PropertyAccessExpression;
|
||||
const target = leftSideOfAssignment.expression as Identifier;
|
||||
|
||||
// Fix up parent pointers since we're going to use these nodes before we bind into them
|
||||
leftSideOfAssignment.parent = node;
|
||||
target.parent = leftSideOfAssignment;
|
||||
|
||||
if (isNameOfExportsOrModuleExportsAliasDeclaration(target)) {
|
||||
// This can be an alias for the 'exports' or 'module.exports' names, e.g.
|
||||
// var util = module.exports;
|
||||
// util.property = function ...
|
||||
bindExportsPropertyAssignment(node);
|
||||
}
|
||||
else {
|
||||
bindPropertyAssignment(target.text, leftSideOfAssignment, /*isPrototypeProperty*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
function bindPropertyAssignment(functionName: string, propertyAccessExpression: PropertyAccessExpression, isPrototypeProperty: boolean) {
|
||||
let targetSymbol = container.locals.get(functionName);
|
||||
|
||||
if (targetSymbol && isDeclarationOfFunctionOrClassExpression(targetSymbol)) {
|
||||
targetSymbol = (targetSymbol.valueDeclaration as VariableDeclaration).initializer.symbol;
|
||||
}
|
||||
|
||||
if (!targetSymbol || !(targetSymbol.flags & (SymbolFlags.Function | SymbolFlags.Class))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up the members collection if it doesn't exist already
|
||||
if (!funcSymbol.members) {
|
||||
funcSymbol.members = createMap<Symbol>();
|
||||
}
|
||||
const symbolTable = isPrototypeProperty ?
|
||||
(targetSymbol.members || (targetSymbol.members = createMap<Symbol>())) :
|
||||
(targetSymbol.exports || (targetSymbol.exports = createMap<Symbol>()));
|
||||
|
||||
// Declare the method/property
|
||||
declareSymbol(funcSymbol.members, funcSymbol, leftSideOfAssignment, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
|
||||
declareSymbol(symbolTable, targetSymbol, propertyAccessExpression, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
|
||||
}
|
||||
|
||||
function bindCallExpression(node: CallExpression) {
|
||||
// We're only inspecting call expressions to detect CommonJS modules, so we can skip
|
||||
// this check if we've already seen the module indicator
|
||||
if (!file.commonJsModuleIndicator && isRequireCall(node, /*checkArgumentIsStringLiteral*/false)) {
|
||||
if (!file.commonJsModuleIndicator && isRequireCall(node, /*checkArgumentIsStringLiteral*/ false)) {
|
||||
setCommonJsModuleIndicator(node);
|
||||
}
|
||||
}
|
||||
@ -2364,7 +2521,7 @@ namespace ts {
|
||||
|
||||
function bindFunctionDeclaration(node: FunctionDeclaration) {
|
||||
if (!isDeclarationFile(file) && !isInAmbientContext(node)) {
|
||||
if (isAsyncFunctionLike(node)) {
|
||||
if (isAsyncFunction(node)) {
|
||||
emitFlags |= NodeFlags.HasAsyncFunctions;
|
||||
}
|
||||
}
|
||||
@ -2381,7 +2538,7 @@ namespace ts {
|
||||
|
||||
function bindFunctionExpression(node: FunctionExpression) {
|
||||
if (!isDeclarationFile(file) && !isInAmbientContext(node)) {
|
||||
if (isAsyncFunctionLike(node)) {
|
||||
if (isAsyncFunction(node)) {
|
||||
emitFlags |= NodeFlags.HasAsyncFunctions;
|
||||
}
|
||||
}
|
||||
@ -2395,7 +2552,7 @@ namespace ts {
|
||||
|
||||
function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
if (!isDeclarationFile(file) && !isInAmbientContext(node)) {
|
||||
if (isAsyncFunctionLike(node)) {
|
||||
if (isAsyncFunction(node)) {
|
||||
emitFlags |= NodeFlags.HasAsyncFunctions;
|
||||
}
|
||||
}
|
||||
@ -2829,11 +2986,10 @@ namespace ts {
|
||||
|
||||
// An async method declaration is ES2017 syntax.
|
||||
if (hasModifier(node, ModifierFlags.Async)) {
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
transformFlags |= node.asteriskToken ? TransformFlags.AssertESNext : TransformFlags.AssertES2017;
|
||||
}
|
||||
|
||||
// Currently, we only support generators that were originally async function bodies.
|
||||
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
if (node.asteriskToken) {
|
||||
transformFlags |= TransformFlags.AssertGenerator;
|
||||
}
|
||||
|
||||
@ -2899,7 +3055,7 @@ namespace ts {
|
||||
|
||||
// An async function declaration is ES2017 syntax.
|
||||
if (modifierFlags & ModifierFlags.Async) {
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
transformFlags |= node.asteriskToken ? TransformFlags.AssertESNext : TransformFlags.AssertES2017;
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
@ -2919,7 +3075,7 @@ namespace ts {
|
||||
// down-level generator.
|
||||
// Currently we do not support transforming any other generator fucntions
|
||||
// down level.
|
||||
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
if (node.asteriskToken) {
|
||||
transformFlags |= TransformFlags.AssertGenerator;
|
||||
}
|
||||
}
|
||||
@ -2941,7 +3097,7 @@ namespace ts {
|
||||
|
||||
// An async function expression is ES2017 syntax.
|
||||
if (hasModifier(node, ModifierFlags.Async)) {
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
transformFlags |= node.asteriskToken ? TransformFlags.AssertESNext : TransformFlags.AssertES2017;
|
||||
}
|
||||
|
||||
// function expressions with object rest destructuring are ES Next syntax
|
||||
@ -2960,9 +3116,7 @@ namespace ts {
|
||||
// If a FunctionExpression is generator function and is the body of a
|
||||
// transformed async function, then this node can be transformed to a
|
||||
// down-level generator.
|
||||
// Currently we do not support transforming any other generator fucntions
|
||||
// down level.
|
||||
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
if (node.asteriskToken) {
|
||||
transformFlags |= TransformFlags.AssertGenerator;
|
||||
}
|
||||
|
||||
@ -3130,8 +3284,8 @@ namespace ts {
|
||||
switch (kind) {
|
||||
case SyntaxKind.AsyncKeyword:
|
||||
case SyntaxKind.AwaitExpression:
|
||||
// async/await is ES2017 syntax
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
// async/await is ES2017 syntax, but may be ESNext syntax (for async generators)
|
||||
transformFlags |= TransformFlags.AssertESNext | TransformFlags.AssertES2017;
|
||||
break;
|
||||
|
||||
case SyntaxKind.PublicKeyword:
|
||||
@ -3156,16 +3310,13 @@ namespace ts {
|
||||
case SyntaxKind.JsxText:
|
||||
case SyntaxKind.JsxClosingElement:
|
||||
case SyntaxKind.JsxAttribute:
|
||||
case SyntaxKind.JsxAttributes:
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
case SyntaxKind.JsxExpression:
|
||||
// These nodes are Jsx syntax.
|
||||
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:
|
||||
@ -3179,9 +3330,30 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
break;
|
||||
|
||||
case SyntaxKind.StringLiteral:
|
||||
if ((<StringLiteral>node).hasExtendedUnicodeEscape) {
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.NumericLiteral:
|
||||
if ((<NumericLiteral>node).numericLiteralFlags & NumericLiteralFlags.BinaryOrOctalSpecifier) {
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.ForOfStatement:
|
||||
// This node is either ES2015 syntax or ES2017 syntax (if it is a for-await-of).
|
||||
if ((<ForOfStatement>node).awaitModifier) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
break;
|
||||
|
||||
case SyntaxKind.YieldExpression:
|
||||
// This node is ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsYield;
|
||||
// This node is either ES2015 syntax (in a generator) or ES2017 syntax (in an async
|
||||
// generator).
|
||||
transformFlags |= TransformFlags.AssertESNext | TransformFlags.AssertES2015 | TransformFlags.ContainsYield;
|
||||
break;
|
||||
|
||||
case SyntaxKind.AnyKeyword:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -43,18 +43,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (node) {
|
||||
const { pos, end } = getCommentRange(node);
|
||||
const emitFlags = getEmitFlags(node);
|
||||
hasWrittenComment = false;
|
||||
|
||||
const emitNode = node.emitNode;
|
||||
const emitFlags = emitNode && emitNode.flags;
|
||||
const { pos, end } = emitNode && emitNode.commentRange || node;
|
||||
if ((pos < 0 && end < 0) || (pos === end)) {
|
||||
// Both pos and end are synthesized, so just emit the node without comments.
|
||||
if (emitFlags & EmitFlags.NoNestedComments) {
|
||||
disabled = true;
|
||||
emitCallback(hint, node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback);
|
||||
}
|
||||
else {
|
||||
if (extendedDiagnostics) {
|
||||
@ -94,17 +90,10 @@ namespace ts {
|
||||
performance.measure("commentTime", "preEmitNodeWithComment");
|
||||
}
|
||||
|
||||
if (emitFlags & EmitFlags.NoNestedComments) {
|
||||
disabled = true;
|
||||
emitCallback(hint, node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback);
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("beginEmitNodeWithComment");
|
||||
performance.mark("postEmitNodeWithComment");
|
||||
}
|
||||
|
||||
// Restore previous container state.
|
||||
@ -119,12 +108,88 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "beginEmitNodeWithComment");
|
||||
performance.measure("commentTime", "postEmitNodeWithComment");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitNodeWithSynthesizedComments(hint: EmitHint, node: Node, emitNode: EmitNode, emitFlags: EmitFlags, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
const leadingComments = emitNode && emitNode.leadingComments;
|
||||
if (some(leadingComments)) {
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("preEmitNodeWithSynthesizedComments");
|
||||
}
|
||||
|
||||
forEach(leadingComments, emitLeadingSynthesizedComment);
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "preEmitNodeWithSynthesizedComments");
|
||||
}
|
||||
}
|
||||
|
||||
emitNodeWithNestedComments(hint, node, emitFlags, emitCallback);
|
||||
|
||||
const trailingComments = emitNode && emitNode.trailingComments;
|
||||
if (some(trailingComments)) {
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("postEmitNodeWithSynthesizedComments");
|
||||
}
|
||||
|
||||
forEach(trailingComments, emitTrailingSynthesizedComment);
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "postEmitNodeWithSynthesizedComments");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitLeadingSynthesizedComment(comment: SynthesizedComment) {
|
||||
if (comment.kind === SyntaxKind.SingleLineCommentTrivia) {
|
||||
writer.writeLine();
|
||||
}
|
||||
writeSynthesizedComment(comment);
|
||||
if (comment.hasTrailingNewLine || comment.kind === SyntaxKind.SingleLineCommentTrivia) {
|
||||
writer.writeLine();
|
||||
}
|
||||
else {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
|
||||
function emitTrailingSynthesizedComment(comment: SynthesizedComment) {
|
||||
if (!writer.isAtStartOfLine()) {
|
||||
writer.write(" ");
|
||||
}
|
||||
writeSynthesizedComment(comment);
|
||||
if (comment.hasTrailingNewLine) {
|
||||
writer.writeLine();
|
||||
}
|
||||
}
|
||||
|
||||
function writeSynthesizedComment(comment: SynthesizedComment) {
|
||||
const text = formatSynthesizedComment(comment);
|
||||
const lineMap = comment.kind === SyntaxKind.MultiLineCommentTrivia ? computeLineStarts(text) : undefined;
|
||||
writeCommentRange(text, lineMap, writer, 0, text.length, newLine);
|
||||
}
|
||||
|
||||
function formatSynthesizedComment(comment: SynthesizedComment) {
|
||||
return comment.kind === SyntaxKind.MultiLineCommentTrivia
|
||||
? `/*${comment.text}*/`
|
||||
: `//${comment.text}`;
|
||||
}
|
||||
|
||||
function emitNodeWithNestedComments(hint: EmitHint, node: Node, emitFlags: EmitFlags, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (emitFlags & EmitFlags.NoNestedComments) {
|
||||
disabled = true;
|
||||
emitCallback(hint, node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
}
|
||||
|
||||
function emitBodyWithDetachedComments(node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void) {
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("preEmitBodyWithDetachedComments");
|
||||
@ -346,7 +411,7 @@ namespace ts {
|
||||
* Determine if the given comment is a triple-slash
|
||||
*
|
||||
* @return true if the comment is a triple-slash comment else false
|
||||
**/
|
||||
*/
|
||||
function isTripleSlashComment(commentPos: number, commentEnd: number) {
|
||||
// Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text
|
||||
// so that we don't end up computing comment string and doing match for all // comments
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/// <reference path="types.ts"/>
|
||||
/// <reference path="types.ts"/>
|
||||
/// <reference path="performance.ts" />
|
||||
|
||||
namespace ts {
|
||||
@ -30,7 +30,7 @@ namespace ts {
|
||||
|
||||
/** Create a MapLike with good performance. */
|
||||
function createDictionaryObject<T>(): MapLike<T> {
|
||||
const map = Object.create(null); // tslint:disable-line:no-null-keyword
|
||||
const map = Object.create(/*prototype*/ null); // tslint:disable-line:no-null-keyword
|
||||
|
||||
// Using 'delete' on an object causes V8 to put the object in dictionary mode.
|
||||
// This disables creation of hidden classes, which are expensive when an object is
|
||||
@ -84,7 +84,7 @@ namespace ts {
|
||||
this.index++;
|
||||
return { value: this.selector(this.data, this.keys[index]), done: false };
|
||||
}
|
||||
return { value: undefined as never, done: true }
|
||||
return { value: undefined as never, done: true };
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,7 +140,7 @@ namespace ts {
|
||||
action(this.data[key], key);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function createFileMap<T>(keyMapper?: (key: string) => string): FileMap<T> {
|
||||
@ -1358,7 +1358,7 @@ namespace ts {
|
||||
|
||||
/**
|
||||
* Returns length of path root (i.e. length of "/", "x:/", "//server/share/, file:///user/files")
|
||||
*/
|
||||
*/
|
||||
export function getRootLength(path: string): number {
|
||||
if (path.charCodeAt(0) === CharacterCodes.slash) {
|
||||
if (path.charCodeAt(1) !== CharacterCodes.slash) return 1;
|
||||
@ -1455,7 +1455,7 @@ namespace ts {
|
||||
return /^\.\.?($|[\\/])/.test(moduleName);
|
||||
}
|
||||
|
||||
export function getEmitScriptTarget(compilerOptions: CompilerOptions | PrinterOptions) {
|
||||
export function getEmitScriptTarget(compilerOptions: CompilerOptions) {
|
||||
return compilerOptions.target || ScriptTarget.ES3;
|
||||
}
|
||||
|
||||
@ -2360,4 +2360,8 @@ namespace ts {
|
||||
return Extension.Jsx;
|
||||
}
|
||||
}
|
||||
|
||||
export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) {
|
||||
return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs;
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,6 +190,7 @@ namespace ts {
|
||||
const writer = <EmitTextWriterWithSymbolWriter>createTextWriter(newLine);
|
||||
writer.trackSymbol = trackSymbol;
|
||||
writer.reportInaccessibleThisError = reportInaccessibleThisError;
|
||||
writer.reportIllegalExtends = reportIllegalExtends;
|
||||
writer.writeKeyword = writer.write;
|
||||
writer.writeOperator = writer.write;
|
||||
writer.writePunctuation = writer.write;
|
||||
@ -313,6 +314,14 @@ namespace ts {
|
||||
recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForSymbol(symbol, meaning));
|
||||
}
|
||||
|
||||
function reportIllegalExtends() {
|
||||
if (errorNameNode) {
|
||||
reportedDeclarationError = true;
|
||||
emitterDiagnostics.add(createDiagnosticForNode(errorNameNode, Diagnostics.extends_clause_of_exported_class_0_refers_to_a_type_whose_name_cannot_be_referenced,
|
||||
declarationNameToString(errorNameNode)));
|
||||
}
|
||||
}
|
||||
|
||||
function reportInaccessibleThisError() {
|
||||
if (errorNameNode) {
|
||||
reportedDeclarationError = true;
|
||||
@ -581,7 +590,7 @@ namespace ts {
|
||||
currentIdentifiers = node.identifiers;
|
||||
isCurrentFileExternalModule = isExternalModule(node);
|
||||
enclosingDeclaration = node;
|
||||
emitDetachedComments(currentText, currentLineMap, writer, writeCommentRange, node, newLine, true /* remove comments */);
|
||||
emitDetachedComments(currentText, currentLineMap, writer, writeCommentRange, node, newLine, /*removeComents*/ true);
|
||||
emitLines(node.statements);
|
||||
}
|
||||
|
||||
@ -1010,6 +1019,23 @@ namespace ts {
|
||||
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.constraint, getTypeParameterConstraintVisibilityError);
|
||||
}
|
||||
}
|
||||
if (node.default && !isPrivateMethodTypeParameter(node)) {
|
||||
write(" = ");
|
||||
if (node.parent.kind === SyntaxKind.FunctionType ||
|
||||
node.parent.kind === SyntaxKind.ConstructorType ||
|
||||
(node.parent.parent && node.parent.parent.kind === SyntaxKind.TypeLiteral)) {
|
||||
Debug.assert(node.parent.kind === SyntaxKind.MethodDeclaration ||
|
||||
node.parent.kind === SyntaxKind.MethodSignature ||
|
||||
node.parent.kind === SyntaxKind.FunctionType ||
|
||||
node.parent.kind === SyntaxKind.ConstructorType ||
|
||||
node.parent.kind === SyntaxKind.CallSignature ||
|
||||
node.parent.kind === SyntaxKind.ConstructSignature);
|
||||
emitType(node.default);
|
||||
}
|
||||
else {
|
||||
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.default, getTypeParameterConstraintVisibilityError);
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeParameterConstraintVisibilityError(): SymbolAccessibilityDiagnostic {
|
||||
// Type parameter constraints are named by user so we should always be able to name it
|
||||
@ -1071,7 +1097,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitHeritageClause(typeReferences: ExpressionWithTypeArguments[], isImplementsList: boolean) {
|
||||
function emitHeritageClause(className: Identifier, typeReferences: ExpressionWithTypeArguments[], isImplementsList: boolean) {
|
||||
if (typeReferences) {
|
||||
write(isImplementsList ? " implements " : " extends ");
|
||||
emitCommaList(typeReferences, emitTypeOfTypeReference);
|
||||
@ -1086,7 +1112,9 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
writer.getSymbolAccessibilityDiagnostic = getHeritageClauseVisibilityError;
|
||||
errorNameNode = className;
|
||||
resolver.writeBaseConstructorTypeOfClass(<ClassLikeDeclaration>enclosingDeclaration, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer);
|
||||
errorNameNode = undefined;
|
||||
}
|
||||
|
||||
function getHeritageClauseVisibilityError(): SymbolAccessibilityDiagnostic {
|
||||
@ -1096,11 +1124,11 @@ namespace ts {
|
||||
// Class or Interface implemented/extended is inaccessible
|
||||
diagnosticMessage = isImplementsList ?
|
||||
Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 :
|
||||
Diagnostics.Extends_clause_of_exported_class_0_has_or_is_using_private_name_1;
|
||||
Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1;
|
||||
}
|
||||
else {
|
||||
// interface is inaccessible
|
||||
diagnosticMessage = Diagnostics.Extends_clause_of_exported_interface_0_has_or_is_using_private_name_1;
|
||||
diagnosticMessage = Diagnostics.extends_clause_of_exported_interface_0_has_or_is_using_private_name_1;
|
||||
}
|
||||
|
||||
return {
|
||||
@ -1136,9 +1164,10 @@ namespace ts {
|
||||
emitTypeParameters(node.typeParameters);
|
||||
const baseTypeNode = getClassExtendsHeritageClauseElement(node);
|
||||
if (baseTypeNode) {
|
||||
emitHeritageClause([baseTypeNode], /*isImplementsList*/ false);
|
||||
node.name;
|
||||
emitHeritageClause(node.name, [baseTypeNode], /*isImplementsList*/ false);
|
||||
}
|
||||
emitHeritageClause(getClassImplementsHeritageClauseElements(node), /*isImplementsList*/ true);
|
||||
emitHeritageClause(node.name, getClassImplementsHeritageClauseElements(node), /*isImplementsList*/ true);
|
||||
write(" {");
|
||||
writeLine();
|
||||
increaseIndent();
|
||||
@ -1160,7 +1189,7 @@ namespace ts {
|
||||
emitTypeParameters(node.typeParameters);
|
||||
const interfaceExtendsTypes = filter(getInterfaceBaseTypeNodes(node), base => isEntityNameExpression(base.expression));
|
||||
if (interfaceExtendsTypes && interfaceExtendsTypes.length) {
|
||||
emitHeritageClause(interfaceExtendsTypes, /*isImplementsList*/ false);
|
||||
emitHeritageClause(node.name, interfaceExtendsTypes, /*isImplementsList*/ false);
|
||||
}
|
||||
write(" {");
|
||||
writeLine();
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
{
|
||||
{
|
||||
"Unterminated string literal.": {
|
||||
"category": "Error",
|
||||
"code": 1002
|
||||
@ -175,15 +175,15 @@
|
||||
"category": "Error",
|
||||
"code": 1057
|
||||
},
|
||||
"Operand for 'await' does not have a valid callable 'then' member.": {
|
||||
"Type used as operand to 'await' or the return type of an async function must either be a valid promise or must not contain a callable 'then' member.": {
|
||||
"category": "Error",
|
||||
"code": 1058
|
||||
},
|
||||
"Return expression in async function does not have a valid callable 'then' member.": {
|
||||
"A promise must have a 'then' method.": {
|
||||
"category": "Error",
|
||||
"code": 1059
|
||||
},
|
||||
"Expression body for async arrow function does not have a valid callable 'then' member.": {
|
||||
"The first parameter of the 'then' method of a promise must be a callback.": {
|
||||
"category": "Error",
|
||||
"code": 1060
|
||||
},
|
||||
@ -191,7 +191,7 @@
|
||||
"category": "Error",
|
||||
"code": 1061
|
||||
},
|
||||
"{0} is referenced directly or indirectly in the fulfillment callback of its own 'then' method.": {
|
||||
"Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method.": {
|
||||
"category": "Error",
|
||||
"code": 1062
|
||||
},
|
||||
@ -291,6 +291,10 @@
|
||||
"category": "Error",
|
||||
"code": 1102
|
||||
},
|
||||
"A 'for-await-of' statement is only allowed within an async function or async generator.": {
|
||||
"category": "Error",
|
||||
"code": 1103
|
||||
},
|
||||
"A 'continue' statement can only be used within an enclosing iteration statement.": {
|
||||
"category": "Error",
|
||||
"code": 1104
|
||||
@ -319,7 +323,7 @@
|
||||
"category": "Error",
|
||||
"code": 1113
|
||||
},
|
||||
"Duplicate label '{0}'": {
|
||||
"Duplicate label '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 1114
|
||||
},
|
||||
@ -447,7 +451,7 @@
|
||||
"category": "Error",
|
||||
"code": 1148
|
||||
},
|
||||
"File name '{0}' differs from already included file name '{1}' only in casing": {
|
||||
"File name '{0}' differs from already included file name '{1}' only in casing.": {
|
||||
"category": "Error",
|
||||
"code": 1149
|
||||
},
|
||||
@ -455,7 +459,7 @@
|
||||
"category": "Error",
|
||||
"code": 1150
|
||||
},
|
||||
"'const' declarations must be initialized": {
|
||||
"'const' declarations must be initialized.": {
|
||||
"category": "Error",
|
||||
"code": 1155
|
||||
},
|
||||
@ -651,11 +655,11 @@
|
||||
"category": "Error",
|
||||
"code": 1210
|
||||
},
|
||||
"A class declaration without the 'default' modifier must have a name": {
|
||||
"A class declaration without the 'default' modifier must have a name.": {
|
||||
"category": "Error",
|
||||
"code": 1211
|
||||
},
|
||||
"Identifier expected. '{0}' is a reserved word in strict mode": {
|
||||
"Identifier expected. '{0}' is a reserved word in strict mode.": {
|
||||
"category": "Error",
|
||||
"code": 1212
|
||||
},
|
||||
@ -1107,7 +1111,7 @@
|
||||
"category": "Error",
|
||||
"code": 2360
|
||||
},
|
||||
"The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter": {
|
||||
"The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.": {
|
||||
"category": "Error",
|
||||
"code": 2361
|
||||
},
|
||||
@ -1131,7 +1135,7 @@
|
||||
"category": "Error",
|
||||
"code": 2366
|
||||
},
|
||||
"Type parameter name cannot be '{0}'": {
|
||||
"Type parameter name cannot be '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2368
|
||||
},
|
||||
@ -1291,7 +1295,7 @@
|
||||
"category": "Error",
|
||||
"code": 2408
|
||||
},
|
||||
"Return type of constructor signature must be assignable to the instance type of the class": {
|
||||
"Return type of constructor signature must be assignable to the instance type of the class.": {
|
||||
"category": "Error",
|
||||
"code": 2409
|
||||
},
|
||||
@ -1311,7 +1315,7 @@
|
||||
"category": "Error",
|
||||
"code": 2413
|
||||
},
|
||||
"Class name cannot be '{0}'": {
|
||||
"Class name cannot be '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2414
|
||||
},
|
||||
@ -1347,7 +1351,7 @@
|
||||
"category": "Error",
|
||||
"code": 2426
|
||||
},
|
||||
"Interface name cannot be '{0}'": {
|
||||
"Interface name cannot be '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2427
|
||||
},
|
||||
@ -1359,7 +1363,7 @@
|
||||
"category": "Error",
|
||||
"code": 2430
|
||||
},
|
||||
"Enum name cannot be '{0}'": {
|
||||
"Enum name cannot be '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2431
|
||||
},
|
||||
@ -1367,11 +1371,11 @@
|
||||
"category": "Error",
|
||||
"code": 2432
|
||||
},
|
||||
"A namespace declaration cannot be in a different file from a class or function with which it is merged": {
|
||||
"A namespace declaration cannot be in a different file from a class or function with which it is merged.": {
|
||||
"category": "Error",
|
||||
"code": 2433
|
||||
},
|
||||
"A namespace declaration cannot be located prior to a class or function with which it is merged": {
|
||||
"A namespace declaration cannot be located prior to a class or function with which it is merged.": {
|
||||
"category": "Error",
|
||||
"code": 2434
|
||||
},
|
||||
@ -1383,11 +1387,11 @@
|
||||
"category": "Error",
|
||||
"code": 2436
|
||||
},
|
||||
"Module '{0}' is hidden by a local declaration with the same name": {
|
||||
"Module '{0}' is hidden by a local declaration with the same name.": {
|
||||
"category": "Error",
|
||||
"code": 2437
|
||||
},
|
||||
"Import name cannot be '{0}'": {
|
||||
"Import name cannot be '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2438
|
||||
},
|
||||
@ -1395,7 +1399,7 @@
|
||||
"category": "Error",
|
||||
"code": 2439
|
||||
},
|
||||
"Import declaration conflicts with local declaration of '{0}'": {
|
||||
"Import declaration conflicts with local declaration of '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2440
|
||||
},
|
||||
@ -1431,6 +1435,14 @@
|
||||
"category": "Error",
|
||||
"code": 2448
|
||||
},
|
||||
"Class '{0}' used before its declaration.": {
|
||||
"category": "Error",
|
||||
"code": 2449
|
||||
},
|
||||
"Enum '{0}' used before its declaration.": {
|
||||
"category": "Error",
|
||||
"code": 2450
|
||||
},
|
||||
"Cannot redeclare block-scoped variable '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2451
|
||||
@ -1455,7 +1467,7 @@
|
||||
"category": "Error",
|
||||
"code": 2456
|
||||
},
|
||||
"Type alias name cannot be '{0}'": {
|
||||
"Type alias name cannot be '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2457
|
||||
},
|
||||
@ -1475,7 +1487,7 @@
|
||||
"category": "Error",
|
||||
"code": 2461
|
||||
},
|
||||
"A rest element must be last in a destructuring pattern": {
|
||||
"A rest element must be last in a destructuring pattern.": {
|
||||
"category": "Error",
|
||||
"code": 2462
|
||||
},
|
||||
@ -1559,7 +1571,7 @@
|
||||
"category": "Error",
|
||||
"code": 2483
|
||||
},
|
||||
"Export declaration conflicts with exported declaration of '{0}'": {
|
||||
"Export declaration conflicts with exported declaration of '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2484
|
||||
},
|
||||
@ -1583,7 +1595,7 @@
|
||||
"category": "Error",
|
||||
"code": 2491
|
||||
},
|
||||
"Cannot redeclare identifier '{0}' in catch clause": {
|
||||
"Cannot redeclare identifier '{0}' in catch clause.": {
|
||||
"category": "Error",
|
||||
"code": 2492
|
||||
},
|
||||
@ -1631,6 +1643,10 @@
|
||||
"category": "Error",
|
||||
"code": 2503
|
||||
},
|
||||
"Type must have a '[Symbol.asyncIterator]()' method that returns an async iterator.": {
|
||||
"category": "Error",
|
||||
"code": 2504
|
||||
},
|
||||
"A generator cannot have a 'void' type annotation.": {
|
||||
"category": "Error",
|
||||
"code": 2505
|
||||
@ -1687,6 +1703,10 @@
|
||||
"category": "Error",
|
||||
"code": 2518
|
||||
},
|
||||
"An async iterator must have a 'next()' method.": {
|
||||
"category": "Error",
|
||||
"code": 2519
|
||||
},
|
||||
"Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions.": {
|
||||
"category": "Error",
|
||||
"code": 2520
|
||||
@ -1795,6 +1815,22 @@
|
||||
"category": "Error",
|
||||
"code": 2546
|
||||
},
|
||||
"The type returned by the 'next()' method of an async iterator must be a promise for a type with a 'value' property.": {
|
||||
"category": "Error",
|
||||
"code": 2547
|
||||
},
|
||||
"Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator.": {
|
||||
"category": "Error",
|
||||
"code": 2548
|
||||
},
|
||||
"Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator.": {
|
||||
"category": "Error",
|
||||
"code": 2549
|
||||
},
|
||||
"Generic type instantiation is excessively deep and possibly infinite.": {
|
||||
"category": "Error",
|
||||
"code": 2550
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
@ -1807,7 +1843,7 @@
|
||||
"category": "Error",
|
||||
"code": 2602
|
||||
},
|
||||
"Property '{0}' in type '{1}' is not assignable to type '{2}'": {
|
||||
"Property '{0}' in type '{1}' is not assignable to type '{2}'.": {
|
||||
"category": "Error",
|
||||
"code": 2603
|
||||
},
|
||||
@ -1823,11 +1859,11 @@
|
||||
"category": "Error",
|
||||
"code": 2606
|
||||
},
|
||||
"JSX element class does not support attributes because it does not have a '{0}' property": {
|
||||
"JSX element class does not support attributes because it does not have a '{0}' property.": {
|
||||
"category": "Error",
|
||||
"code": 2607
|
||||
},
|
||||
"The global type 'JSX.{0}' may not have more than one property": {
|
||||
"The global type 'JSX.{0}' may not have more than one property.": {
|
||||
"category": "Error",
|
||||
"code": 2608
|
||||
},
|
||||
@ -1839,7 +1875,7 @@
|
||||
"category": "Error",
|
||||
"code": 2649
|
||||
},
|
||||
"Cannot emit namespaced JSX elements in React": {
|
||||
"Cannot emit namespaced JSX elements in React.": {
|
||||
"category": "Error",
|
||||
"code": 2650
|
||||
},
|
||||
@ -1863,11 +1899,11 @@
|
||||
"category": "Error",
|
||||
"code": 2656
|
||||
},
|
||||
"JSX expressions must have one parent element": {
|
||||
"JSX expressions must have one parent element.": {
|
||||
"category": "Error",
|
||||
"code": 2657
|
||||
},
|
||||
"Type '{0}' provides no match for the signature '{1}'": {
|
||||
"Type '{0}' provides no match for the signature '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 2658
|
||||
},
|
||||
@ -1995,10 +2031,6 @@
|
||||
"category": "Error",
|
||||
"code": 2689
|
||||
},
|
||||
"A class must be declared after its base class.": {
|
||||
"category": "Error",
|
||||
"code": 2690
|
||||
},
|
||||
"An import path cannot end with a '{0}' extension. Consider importing '{1}' instead.": {
|
||||
"category": "Error",
|
||||
"code": 2691
|
||||
@ -2047,11 +2079,11 @@
|
||||
"category": "Error",
|
||||
"code": 2702
|
||||
},
|
||||
"The operand of a delete operator must be a property reference": {
|
||||
"The operand of a delete operator must be a property reference.": {
|
||||
"category": "Error",
|
||||
"code": 2703
|
||||
},
|
||||
"The operand of a delete operator cannot be a read-only property": {
|
||||
"The operand of a delete operator cannot be a read-only property.": {
|
||||
"category": "Error",
|
||||
"code": 2704
|
||||
},
|
||||
@ -2059,6 +2091,14 @@
|
||||
"category": "Error",
|
||||
"code": 2705
|
||||
},
|
||||
"Required type parameters may not follow optional type parameters.": {
|
||||
"category": "Error",
|
||||
"code": 2706
|
||||
},
|
||||
"Generic type '{0}' requires between {1} and {2} type arguments.": {
|
||||
"category": "Error",
|
||||
"code": 2707
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
@ -2100,11 +2140,11 @@
|
||||
"category": "Error",
|
||||
"code": 4019
|
||||
},
|
||||
"Extends clause of exported class '{0}' has or is using private name '{1}'.": {
|
||||
"'extends' clause of exported class '{0}' has or is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 4020
|
||||
},
|
||||
"Extends clause of exported interface '{0}' has or is using private name '{1}'.": {
|
||||
"'extends' clause of exported interface '{0}' has or is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 4022
|
||||
},
|
||||
@ -2356,6 +2396,10 @@
|
||||
"category": "Error",
|
||||
"code": 4092
|
||||
},
|
||||
"'extends' clause of exported class '{0}' refers to a type whose name cannot be referenced.": {
|
||||
"category": "Error",
|
||||
"code": 4093
|
||||
},
|
||||
|
||||
"The current host does not support the '{0}' option.": {
|
||||
"category": "Error",
|
||||
@ -2373,14 +2417,10 @@
|
||||
"category": "Error",
|
||||
"code": 5011
|
||||
},
|
||||
"Cannot read file '{0}': {1}": {
|
||||
"Cannot read file '{0}': {1}.": {
|
||||
"category": "Error",
|
||||
"code": 5012
|
||||
},
|
||||
"Unsupported file encoding.": {
|
||||
"category": "Error",
|
||||
"code": 5013
|
||||
},
|
||||
"Failed to parse file '{0}': {1}.": {
|
||||
"category": "Error",
|
||||
"code": 5014
|
||||
@ -2393,7 +2433,7 @@
|
||||
"category": "Error",
|
||||
"code": 5024
|
||||
},
|
||||
"Could not write file '{0}': {1}": {
|
||||
"Could not write file '{0}': {1}.": {
|
||||
"category": "Error",
|
||||
"code": 5033
|
||||
},
|
||||
@ -2429,11 +2469,11 @@
|
||||
"category": "Error",
|
||||
"code": 5056
|
||||
},
|
||||
"Cannot find a tsconfig.json file at the specified directory: '{0}'": {
|
||||
"Cannot find a tsconfig.json file at the specified directory: '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 5057
|
||||
},
|
||||
"The specified path does not exist: '{0}'": {
|
||||
"The specified path does not exist: '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 5058
|
||||
},
|
||||
@ -2445,11 +2485,11 @@
|
||||
"category": "Error",
|
||||
"code": 5060
|
||||
},
|
||||
"Pattern '{0}' can have at most one '*' character": {
|
||||
"Pattern '{0}' can have at most one '*' character.": {
|
||||
"category": "Error",
|
||||
"code": 5061
|
||||
},
|
||||
"Substitution '{0}' in pattern '{1}' in can have at most one '*' character": {
|
||||
"Substitution '{0}' in pattern '{1}' in can have at most one '*' character.": {
|
||||
"category": "Error",
|
||||
"code": 5062
|
||||
},
|
||||
@ -2521,11 +2561,11 @@
|
||||
"category": "Message",
|
||||
"code": 6012
|
||||
},
|
||||
"Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'": {
|
||||
"Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'.": {
|
||||
"category": "Message",
|
||||
"code": 6015
|
||||
},
|
||||
"Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'": {
|
||||
"Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'.": {
|
||||
"category": "Message",
|
||||
"code": 6016
|
||||
},
|
||||
@ -2537,7 +2577,7 @@
|
||||
"category": "Message",
|
||||
"code": 6019
|
||||
},
|
||||
"Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'": {
|
||||
"Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.": {
|
||||
"category": "Message",
|
||||
"code": 6020
|
||||
},
|
||||
@ -2617,7 +2657,7 @@
|
||||
"category": "Error",
|
||||
"code": 6045
|
||||
},
|
||||
"Argument for '{0}' option must be: {1}": {
|
||||
"Argument for '{0}' option must be: {1}.": {
|
||||
"category": "Error",
|
||||
"code": 6046
|
||||
},
|
||||
@ -2705,7 +2745,7 @@
|
||||
"category": "Message",
|
||||
"code": 6072
|
||||
},
|
||||
"Stylize errors and messages using color and context. (experimental)": {
|
||||
"Stylize errors and messages using color and context (experimental).": {
|
||||
"category": "Message",
|
||||
"code": 6073
|
||||
},
|
||||
@ -2733,7 +2773,7 @@
|
||||
"category": "Message",
|
||||
"code": 6079
|
||||
},
|
||||
"Specify JSX code generation: 'preserve', 'react-native', or 'react'": {
|
||||
"Specify JSX code generation: 'preserve', 'react-native', or 'react'.": {
|
||||
"category": "Message",
|
||||
"code": 6080
|
||||
},
|
||||
@ -2749,7 +2789,7 @@
|
||||
"category": "Message",
|
||||
"code": 6083
|
||||
},
|
||||
"Specify the object invoked for createElement and __spread when targeting 'react' JSX emit": {
|
||||
"[Deprecated] Use '--jsxFactory' instead. Specify the object invoked for createElement when targeting 'react' JSX emit": {
|
||||
"category": "Message",
|
||||
"code": 6084
|
||||
},
|
||||
@ -2837,27 +2877,27 @@
|
||||
"category": "Message",
|
||||
"code": 6105
|
||||
},
|
||||
"'baseUrl' option is set to '{0}', using this value to resolve non-relative module name '{1}'": {
|
||||
"'baseUrl' option is set to '{0}', using this value to resolve non-relative module name '{1}'.": {
|
||||
"category": "Message",
|
||||
"code": 6106
|
||||
},
|
||||
"'rootDirs' option is set, using it to resolve relative module name '{0}'": {
|
||||
"'rootDirs' option is set, using it to resolve relative module name '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 6107
|
||||
},
|
||||
"Longest matching prefix for '{0}' is '{1}'": {
|
||||
"Longest matching prefix for '{0}' is '{1}'.": {
|
||||
"category": "Message",
|
||||
"code": 6108
|
||||
},
|
||||
"Loading '{0}' from the root dir '{1}', candidate location '{2}'": {
|
||||
"Loading '{0}' from the root dir '{1}', candidate location '{2}'.": {
|
||||
"category": "Message",
|
||||
"code": 6109
|
||||
},
|
||||
"Trying other entries in 'rootDirs'": {
|
||||
"Trying other entries in 'rootDirs'.": {
|
||||
"category": "Message",
|
||||
"code": 6110
|
||||
},
|
||||
"Module resolution using 'rootDirs' has failed": {
|
||||
"Module resolution using 'rootDirs' has failed.": {
|
||||
"category": "Message",
|
||||
"code": 6111
|
||||
},
|
||||
@ -2897,7 +2937,7 @@
|
||||
"category": "Message",
|
||||
"code": 6120
|
||||
},
|
||||
"Resolving with primary search path '{0}'": {
|
||||
"Resolving with primary search path '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 6121
|
||||
},
|
||||
@ -2913,7 +2953,7 @@
|
||||
"category": "Message",
|
||||
"code": 6124
|
||||
},
|
||||
"Looking up in 'node_modules' folder, initial location '{0}'": {
|
||||
"Looking up in 'node_modules' folder, initial location '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 6125
|
||||
},
|
||||
@ -2933,7 +2973,7 @@
|
||||
"category": "Error",
|
||||
"code": 6129
|
||||
},
|
||||
"Resolving real path for '{0}', result '{1}'": {
|
||||
"Resolving real path for '{0}', result '{1}'.": {
|
||||
"category": "Message",
|
||||
"code": 6130
|
||||
},
|
||||
@ -2941,7 +2981,7 @@
|
||||
"category": "Error",
|
||||
"code": 6131
|
||||
},
|
||||
"File name '{0}' has a '{1}' extension - stripping it": {
|
||||
"File name '{0}' has a '{1}' extension - stripping it.": {
|
||||
"category": "Message",
|
||||
"code": 6132
|
||||
},
|
||||
@ -2957,7 +2997,7 @@
|
||||
"category": "Message",
|
||||
"code": 6135
|
||||
},
|
||||
"The maximum dependency depth to search under node_modules and load JavaScript files": {
|
||||
"The maximum dependency depth to search under node_modules and load JavaScript files.": {
|
||||
"category": "Message",
|
||||
"code": 6136
|
||||
},
|
||||
@ -2973,7 +3013,7 @@
|
||||
"category": "Error",
|
||||
"code": 6140
|
||||
},
|
||||
"Parse in strict mode and emit \"use strict\" for each source file": {
|
||||
"Parse in strict mode and emit \"use strict\" for each source file.": {
|
||||
"category": "Message",
|
||||
"code": 6141
|
||||
},
|
||||
@ -3005,6 +3045,139 @@
|
||||
"category": "Message",
|
||||
"code": 6148
|
||||
},
|
||||
"Show diagnostic information.": {
|
||||
"category": "Message",
|
||||
"code": 6149
|
||||
},
|
||||
"Show verbose diagnostic information.": {
|
||||
"category": "Message",
|
||||
"code": 6150
|
||||
},
|
||||
"Emit a single file with source maps instead of having a separate file.": {
|
||||
"category": "Message",
|
||||
"code": 6151
|
||||
},
|
||||
"Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set.": {
|
||||
"category": "Message",
|
||||
"code": 6152
|
||||
},
|
||||
"Transpile each file as a separate module (similar to 'ts.transpileModule').": {
|
||||
"category": "Message",
|
||||
"code": 6153
|
||||
},
|
||||
"Print names of generated files part of the compilation.": {
|
||||
"category": "Message",
|
||||
"code": 6154
|
||||
},
|
||||
"Print names of files part of the compilation.": {
|
||||
"category": "Message",
|
||||
"code": 6155
|
||||
},
|
||||
"The locale used when displaying messages to the user (e.g. 'en-us')": {
|
||||
"category": "Message",
|
||||
"code": 6156
|
||||
},
|
||||
"Do not generate custom helper functions like '__extends' in compiled output.": {
|
||||
"category": "Message",
|
||||
"code": 6157
|
||||
},
|
||||
"Do not include the default library file (lib.d.ts).": {
|
||||
"category": "Message",
|
||||
"code": 6158
|
||||
},
|
||||
"Do not add triple-slash references or imported modules to the list of compiled files.": {
|
||||
"category": "Message",
|
||||
"code": 6159
|
||||
},
|
||||
"[Deprecated] Use '--skipLibCheck' instead. Skip type checking of default library declaration files.": {
|
||||
"category": "Message",
|
||||
"code": 6160
|
||||
},
|
||||
"List of folders to include type definitions from.": {
|
||||
"category": "Message",
|
||||
"code": 6161
|
||||
},
|
||||
"Disable size limitations on JavaScript projects.": {
|
||||
"category": "Message",
|
||||
"code": 6162
|
||||
},
|
||||
"The character set of the input files.": {
|
||||
"category": "Message",
|
||||
"code": 6163
|
||||
},
|
||||
"Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.": {
|
||||
"category": "Message",
|
||||
"code": 6164
|
||||
},
|
||||
"Do not truncate error messages.": {
|
||||
"category": "Message",
|
||||
"code": 6165
|
||||
},
|
||||
"Output directory for generated declaration files.": {
|
||||
"category": "Message",
|
||||
"code": 6166
|
||||
},
|
||||
"A series of entries which re-map imports to lookup locations relative to the 'baseUrl'.": {
|
||||
"category": "Message",
|
||||
"code": 6167
|
||||
},
|
||||
"List of root folders whose combined content represents the structure of the project at runtime.": {
|
||||
"category": "Message",
|
||||
"code": 6168
|
||||
},
|
||||
"Show all compiler options.": {
|
||||
"category": "Message",
|
||||
"code": 6169
|
||||
},
|
||||
"[Deprecated] Use '--outFile' instead. Concatenate and emit output to single file": {
|
||||
"category": "Message",
|
||||
"code": 6170
|
||||
},
|
||||
"Command-line Options": {
|
||||
"category": "Message",
|
||||
"code": 6171
|
||||
},
|
||||
"Basic Options": {
|
||||
"category": "Message",
|
||||
"code": 6172
|
||||
},
|
||||
"Strict Type-Checking Options": {
|
||||
"category": "Message",
|
||||
"code": 6173
|
||||
},
|
||||
"Module Resolution Options": {
|
||||
"category": "Message",
|
||||
"code": 6174
|
||||
},
|
||||
"Source Map Options": {
|
||||
"category": "Message",
|
||||
"code": 6175
|
||||
},
|
||||
"Additional Checks": {
|
||||
"category": "Message",
|
||||
"code": 6176
|
||||
},
|
||||
"Experimental Options": {
|
||||
"category": "Message",
|
||||
"code": 6177
|
||||
},
|
||||
"Advanced Options": {
|
||||
"category": "Message",
|
||||
"code": 6178
|
||||
},
|
||||
"Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'.": {
|
||||
"category": "Message",
|
||||
"code": 6179
|
||||
},
|
||||
"Enable all strict type-checking options.": {
|
||||
"category": "Message",
|
||||
"code": 6180
|
||||
},
|
||||
"List of language service plugins.": {
|
||||
"category": "Message",
|
||||
"code": 6181
|
||||
},
|
||||
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
"code": 7005
|
||||
@ -3073,7 +3246,7 @@
|
||||
"category": "Error",
|
||||
"code": 7025
|
||||
},
|
||||
"JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists": {
|
||||
"JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists.": {
|
||||
"category": "Error",
|
||||
"code": 7026
|
||||
},
|
||||
@ -3169,7 +3342,7 @@
|
||||
"category": "Error",
|
||||
"code": 8016
|
||||
},
|
||||
"Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses.": {
|
||||
"Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause.": {
|
||||
"category": "Error",
|
||||
"code": 9002
|
||||
},
|
||||
@ -3201,7 +3374,7 @@
|
||||
"category": "Error",
|
||||
"code": 17004
|
||||
},
|
||||
"A constructor cannot contain a 'super' call when its class extends 'null'": {
|
||||
"A constructor cannot contain a 'super' call when its class extends 'null'.": {
|
||||
"category": "Error",
|
||||
"code": 17005
|
||||
},
|
||||
@ -3229,7 +3402,7 @@
|
||||
"category": "Error",
|
||||
"code": 17011
|
||||
},
|
||||
"'{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{0}'?": {
|
||||
"'{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?": {
|
||||
"category": "Error",
|
||||
"code": 17012
|
||||
},
|
||||
@ -3267,7 +3440,7 @@
|
||||
"category": "Message",
|
||||
"code": 90003
|
||||
},
|
||||
"Remove declaration for: {0}": {
|
||||
"Remove declaration for: '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 90004
|
||||
},
|
||||
@ -3283,7 +3456,7 @@
|
||||
"category": "Message",
|
||||
"code": 90008
|
||||
},
|
||||
"Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig": {
|
||||
"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
|
||||
},
|
||||
@ -3291,18 +3464,44 @@
|
||||
"category": "Error",
|
||||
"code": 90010
|
||||
},
|
||||
"Import {0} from {1}": {
|
||||
"Import {0} from {1}.": {
|
||||
"category": "Message",
|
||||
"code": 90013
|
||||
},
|
||||
"Change {0} to {1}": {
|
||||
"Change {0} to {1}.": {
|
||||
"category": "Message",
|
||||
"code": 90014
|
||||
},
|
||||
"Add {0} to existing import declaration from {1}": {
|
||||
"Add {0} to existing import declaration from {1}.": {
|
||||
"category": "Message",
|
||||
"code": 90015
|
||||
},
|
||||
"Add declaration for missing property '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 90016
|
||||
},
|
||||
"Add index signature for missing property '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 90017
|
||||
},
|
||||
"Disable checking for this file.": {
|
||||
"category": "Message",
|
||||
"code": 90018
|
||||
},
|
||||
"Ignore this error message.": {
|
||||
"category": "Message",
|
||||
"code": 90019
|
||||
},
|
||||
"Initialize property '{0}' in the constructor.": {
|
||||
"category": "Message",
|
||||
"code": 90020
|
||||
},
|
||||
"Initialize static property '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 90021
|
||||
},
|
||||
|
||||
|
||||
"Octal literal types must use ES2015 syntax. Use the syntax '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 8017
|
||||
@ -3310,5 +3509,9 @@
|
||||
"Octal literals are not allowed in enums members initializer. Use the syntax '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 8018
|
||||
},
|
||||
"Report errors in .js files.": {
|
||||
"category": "Message",
|
||||
"code": 8019
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/// <reference path="checker.ts" />
|
||||
/// <reference path="checker.ts" />
|
||||
/// <reference path="transformer.ts" />
|
||||
/// <reference path="declarationEmitter.ts" />
|
||||
/// <reference path="sourcemap.ts" />
|
||||
@ -10,14 +10,13 @@ namespace ts {
|
||||
|
||||
/*@internal*/
|
||||
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
|
||||
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean): EmitResult {
|
||||
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean, transformers?: TransformerFactory<SourceFile>[]): EmitResult {
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
const sourceMapDataList: SourceMapData[] = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? [] : undefined;
|
||||
const emittedFilesList: string[] = compilerOptions.listEmittedFiles ? [] : undefined;
|
||||
const emitterDiagnostics = createDiagnosticCollection();
|
||||
const newLine = host.getNewLine();
|
||||
const transformers = emitOnlyDtsFiles ? [] : getTransformers(compilerOptions);
|
||||
const writer = createTextWriter(newLine);
|
||||
const sourceMap = createSourceMapWriter(host, writer);
|
||||
|
||||
@ -29,7 +28,7 @@ namespace ts {
|
||||
const sourceFiles = getSourceFilesToEmit(host, targetSourceFile);
|
||||
|
||||
// Transform the source files
|
||||
const transform = transformFiles(resolver, host, sourceFiles, transformers);
|
||||
const transform = transformNodes(resolver, host, compilerOptions, sourceFiles, transformers, /*allowDtsFiles*/ false);
|
||||
|
||||
// Create a printer to print the nodes
|
||||
const printer = createPrinter(compilerOptions, {
|
||||
@ -38,7 +37,7 @@ namespace ts {
|
||||
|
||||
// transform hooks
|
||||
onEmitNode: transform.emitNodeWithNotification,
|
||||
onSubstituteNode: transform.emitNodeWithSubstitution,
|
||||
substituteNode: transform.substituteNode,
|
||||
|
||||
// sourcemap hooks
|
||||
onEmitSourceMapOfNode: sourceMap.emitNodeWithSourceMap,
|
||||
@ -56,9 +55,7 @@ namespace ts {
|
||||
performance.measure("printTime", "beforePrint");
|
||||
|
||||
// Clean up emit nodes on parse tree
|
||||
for (const sourceFile of sourceFiles) {
|
||||
disposeEmitNodes(sourceFile);
|
||||
}
|
||||
transform.dispose();
|
||||
|
||||
return {
|
||||
emitSkipped,
|
||||
@ -201,11 +198,12 @@ namespace ts {
|
||||
onEmitNode,
|
||||
onEmitHelpers,
|
||||
onSetSourceFile,
|
||||
onSubstituteNode,
|
||||
substituteNode,
|
||||
onBeforeEmitNodeArray,
|
||||
onAfterEmitNodeArray
|
||||
} = handlers;
|
||||
|
||||
const newLine = getNewLineCharacter(printerOptions);
|
||||
const languageVersion = getEmitScriptTarget(printerOptions);
|
||||
const comments = createCommentWriter(printerOptions, onEmitSourceMapOfPosition);
|
||||
const {
|
||||
emitNodeWithComments,
|
||||
@ -277,6 +275,8 @@ namespace ts {
|
||||
function writeBundle(bundle: Bundle, output: EmitTextWriter) {
|
||||
const previousWriter = writer;
|
||||
setWriter(output);
|
||||
emitShebangIfNeeded(bundle);
|
||||
emitPrologueDirectivesIfNeeded(bundle);
|
||||
emitHelpersIndirect(bundle);
|
||||
for (const sourceFile of bundle.sourceFiles) {
|
||||
print(EmitHint.SourceFile, sourceFile, sourceFile);
|
||||
@ -288,6 +288,8 @@ namespace ts {
|
||||
function writeFile(sourceFile: SourceFile, output: EmitTextWriter) {
|
||||
const previousWriter = writer;
|
||||
setWriter(output);
|
||||
emitShebangIfNeeded(sourceFile);
|
||||
emitPrologueDirectivesIfNeeded(sourceFile);
|
||||
print(EmitHint.SourceFile, sourceFile, sourceFile);
|
||||
reset();
|
||||
writer = previousWriter;
|
||||
@ -331,8 +333,8 @@ namespace ts {
|
||||
setWriter(/*output*/ undefined);
|
||||
}
|
||||
|
||||
function emit(node: Node, hint = EmitHint.Unspecified) {
|
||||
pipelineEmitWithNotification(hint, node);
|
||||
function emit(node: Node) {
|
||||
pipelineEmitWithNotification(EmitHint.Unspecified, node);
|
||||
}
|
||||
|
||||
function emitIdentifierName(node: Identifier) {
|
||||
@ -353,6 +355,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function pipelineEmitWithComments(hint: EmitHint, node: Node) {
|
||||
node = trySubstituteNode(hint, node);
|
||||
if (emitNodeWithComments && hint !== EmitHint.SourceFile) {
|
||||
emitNodeWithComments(hint, node, pipelineEmitWithSourceMap);
|
||||
}
|
||||
@ -363,16 +366,7 @@ namespace ts {
|
||||
|
||||
function pipelineEmitWithSourceMap(hint: EmitHint, node: Node) {
|
||||
if (onEmitSourceMapOfNode && hint !== EmitHint.SourceFile && hint !== EmitHint.IdentifierName) {
|
||||
onEmitSourceMapOfNode(hint, node, pipelineEmitWithSubstitution);
|
||||
}
|
||||
else {
|
||||
pipelineEmitWithSubstitution(hint, node);
|
||||
}
|
||||
}
|
||||
|
||||
function pipelineEmitWithSubstitution(hint: EmitHint, node: Node) {
|
||||
if (onSubstituteNode) {
|
||||
onSubstituteNode(hint, node, pipelineEmitWithHint);
|
||||
onEmitSourceMapOfNode(hint, node, pipelineEmitWithHint);
|
||||
}
|
||||
else {
|
||||
pipelineEmitWithHint(hint, node);
|
||||
@ -604,6 +598,8 @@ namespace ts {
|
||||
return emitJsxClosingElement(<JsxClosingElement>node);
|
||||
case SyntaxKind.JsxAttribute:
|
||||
return emitJsxAttribute(<JsxAttribute>node);
|
||||
case SyntaxKind.JsxAttributes:
|
||||
return emitJsxAttributes(<JsxAttributes>node);
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
return emitJsxSpreadAttribute(<JsxSpreadAttribute>node);
|
||||
case SyntaxKind.JsxExpression:
|
||||
@ -638,7 +634,12 @@ namespace ts {
|
||||
// If the node is an expression, try to emit it as an expression with
|
||||
// substitution.
|
||||
if (isExpression(node)) {
|
||||
return pipelineEmitWithSubstitution(EmitHint.Expression, node);
|
||||
return pipelineEmitExpression(trySubstituteNode(EmitHint.Expression, node));
|
||||
}
|
||||
|
||||
if (isToken(node)) {
|
||||
writeTokenText(kind);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -735,13 +736,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitBodyIndirect(node: Node, elements: NodeArray<Node>, emitCallback: (node: Node) => void): void {
|
||||
if (emitBodyWithDetachedComments) {
|
||||
emitBodyWithDetachedComments(node, elements, emitCallback);
|
||||
}
|
||||
else {
|
||||
emitCallback(node);
|
||||
}
|
||||
function trySubstituteNode(hint: EmitHint, node: Node) {
|
||||
return node && substituteNode && substituteNode(hint, node) || node;
|
||||
}
|
||||
|
||||
function emitHelpersIndirect(node: Node) {
|
||||
@ -757,9 +753,6 @@ namespace ts {
|
||||
// SyntaxKind.NumericLiteral
|
||||
function emitNumericLiteral(node: NumericLiteral) {
|
||||
emitLiteral(node);
|
||||
if (node.trailingComment) {
|
||||
write(` /*${node.trailingComment}*/`);
|
||||
}
|
||||
}
|
||||
|
||||
// SyntaxKind.StringLiteral
|
||||
@ -827,8 +820,8 @@ namespace ts {
|
||||
writeIfPresent(node.dotDotDotToken, "...");
|
||||
emit(node.name);
|
||||
writeIfPresent(node.questionToken, "?");
|
||||
emitExpressionWithPrefix(" = ", node.initializer);
|
||||
emitWithPrefix(": ", node.type);
|
||||
emitExpressionWithPrefix(" = ", node.initializer);
|
||||
}
|
||||
|
||||
function emitDecorator(decorator: Decorator) {
|
||||
@ -1090,7 +1083,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None;
|
||||
const allowTrailingComma = languageVersion >= ScriptTarget.ES5 ? ListFormat.AllowTrailingComma : ListFormat.None;
|
||||
const allowTrailingComma = currentSourceFile.languageVersion >= ScriptTarget.ES5 ? ListFormat.AllowTrailingComma : ListFormat.None;
|
||||
emitList(node, properties, ListFormat.ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine);
|
||||
|
||||
if (indentedFlag) {
|
||||
@ -1124,11 +1117,11 @@ namespace ts {
|
||||
// 1..toString is a valid property access, emit a dot after the literal
|
||||
// Also emit a dot if expression is a integer const enum value - it will appear in generated code as numeric literal
|
||||
function needsDotDotForPropertyAccess(expression: Expression) {
|
||||
if (expression.kind === SyntaxKind.NumericLiteral) {
|
||||
expression = skipPartiallyEmittedExpressions(expression);
|
||||
if (isNumericLiteral(expression)) {
|
||||
// check if numeric literal is a decimal literal that was originally written with a dot
|
||||
const text = getLiteralTextOfNode(<LiteralExpression>expression);
|
||||
return getNumericLiteralFlags(text, /*hint*/ NumericLiteralFlags.All) === NumericLiteralFlags.None
|
||||
&& !(<LiteralExpression>expression).isOctalLiteral
|
||||
return !expression.numericLiteralFlags
|
||||
&& text.indexOf(tokenToString(SyntaxKind.DotToken)) < 0;
|
||||
}
|
||||
else if (isPropertyAccessExpression(expression) || isElementAccessExpression(expression)) {
|
||||
@ -1448,6 +1441,7 @@ namespace ts {
|
||||
function emitForOfStatement(node: ForOfStatement) {
|
||||
const openParenPos = writeToken(SyntaxKind.ForKeyword, node.pos);
|
||||
write(" ");
|
||||
emitWithSuffix(node.awaitModifier, " ");
|
||||
writeToken(SyntaxKind.OpenParenToken, openParenPos);
|
||||
emitForBinding(node.initializer);
|
||||
write(" of ");
|
||||
@ -1560,6 +1554,10 @@ namespace ts {
|
||||
emitSignatureAndBody(node, emitSignatureHead);
|
||||
}
|
||||
|
||||
function emitBlockCallback(_hint: EmitHint, body: Node): void {
|
||||
emitBlockFunctionBody(<Block>body);
|
||||
}
|
||||
|
||||
function emitSignatureAndBody(node: FunctionLikeDeclaration, emitSignatureHead: (node: SignatureDeclaration) => void) {
|
||||
const body = node.body;
|
||||
if (body) {
|
||||
@ -1571,12 +1569,22 @@ namespace ts {
|
||||
|
||||
if (getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) {
|
||||
emitSignatureHead(node);
|
||||
emitBlockFunctionBody(body);
|
||||
if (onEmitNode) {
|
||||
onEmitNode(EmitHint.Unspecified, body, emitBlockCallback);
|
||||
}
|
||||
else {
|
||||
emitBlockFunctionBody(body);
|
||||
}
|
||||
}
|
||||
else {
|
||||
pushNameGenerationScope();
|
||||
emitSignatureHead(node);
|
||||
emitBlockFunctionBody(body);
|
||||
if (onEmitNode) {
|
||||
onEmitNode(EmitHint.Unspecified, body, emitBlockCallback);
|
||||
}
|
||||
else {
|
||||
emitBlockFunctionBody(body);
|
||||
}
|
||||
popNameGenerationScope();
|
||||
}
|
||||
|
||||
@ -1649,7 +1657,12 @@ namespace ts {
|
||||
? emitBlockFunctionBodyOnSingleLine
|
||||
: emitBlockFunctionBodyWorker;
|
||||
|
||||
emitBodyIndirect(body, body.statements, emitBlockFunctionBody);
|
||||
if (emitBodyWithDetachedComments) {
|
||||
emitBodyWithDetachedComments(body, body.statements, emitBlockFunctionBody);
|
||||
}
|
||||
else {
|
||||
emitBlockFunctionBody(body);
|
||||
}
|
||||
|
||||
decreaseIndent();
|
||||
writeToken(SyntaxKind.CloseBraceToken, body.statements.end, body);
|
||||
@ -1760,7 +1773,6 @@ namespace ts {
|
||||
else {
|
||||
pushNameGenerationScope();
|
||||
write("{");
|
||||
increaseIndent();
|
||||
emitBlockStatements(node);
|
||||
write("}");
|
||||
popNameGenerationScope();
|
||||
@ -1891,15 +1903,21 @@ namespace ts {
|
||||
write("<");
|
||||
emitJsxTagName(node.tagName);
|
||||
write(" ");
|
||||
emitList(node, node.attributes, ListFormat.JsxElementAttributes);
|
||||
// We are checking here so we won't re-enter the emiting pipeline and emit extra sourcemap
|
||||
if (node.attributes.properties && node.attributes.properties.length > 0) {
|
||||
emit(node.attributes);
|
||||
}
|
||||
write("/>");
|
||||
}
|
||||
|
||||
function emitJsxOpeningElement(node: JsxOpeningElement) {
|
||||
write("<");
|
||||
emitJsxTagName(node.tagName);
|
||||
writeIfAny(node.attributes, " ");
|
||||
emitList(node, node.attributes, ListFormat.JsxElementAttributes);
|
||||
writeIfAny(node.attributes.properties, " ");
|
||||
// We are checking here so we won't re-enter the emitting pipeline and emit extra sourcemap
|
||||
if (node.attributes.properties && node.attributes.properties.length > 0) {
|
||||
emit(node.attributes);
|
||||
}
|
||||
write(">");
|
||||
}
|
||||
|
||||
@ -1913,6 +1931,10 @@ namespace ts {
|
||||
write(">");
|
||||
}
|
||||
|
||||
function emitJsxAttributes(node: JsxAttributes) {
|
||||
emitList(node, node.properties, ListFormat.JsxElementAttributes);
|
||||
}
|
||||
|
||||
function emitJsxAttribute(node: JsxAttribute) {
|
||||
emit(node.name);
|
||||
emitWithPrefix("=", node.initializer);
|
||||
@ -2049,16 +2071,27 @@ namespace ts {
|
||||
|
||||
function emitSourceFile(node: SourceFile) {
|
||||
writeLine();
|
||||
emitShebang();
|
||||
emitBodyIndirect(node, node.statements, emitSourceFileWorker);
|
||||
const statements = node.statements;
|
||||
if (emitBodyWithDetachedComments) {
|
||||
// Emit detached comment if there are no prologue directives or if the first node is synthesized.
|
||||
// The synthesized node will have no leading comment so some comments may be missed.
|
||||
const shouldEmitDetachedComment = statements.length === 0 ||
|
||||
!isPrologueDirective(statements[0]) ||
|
||||
nodeIsSynthesized(statements[0]);
|
||||
if (shouldEmitDetachedComment) {
|
||||
emitBodyWithDetachedComments(node, statements, emitSourceFileWorker);
|
||||
return;
|
||||
}
|
||||
}
|
||||
emitSourceFileWorker(node);
|
||||
}
|
||||
|
||||
function emitSourceFileWorker(node: SourceFile) {
|
||||
const statements = node.statements;
|
||||
const statementOffset = emitPrologueDirectives(statements);
|
||||
pushNameGenerationScope();
|
||||
emitHelpersIndirect(node);
|
||||
emitList(node, statements, ListFormat.MultiLine, statementOffset);
|
||||
const index = findIndex(statements, statement => !isPrologueDirective(statement));
|
||||
emitList(node, statements, ListFormat.MultiLine, index === -1 ? statements.length : index);
|
||||
popNameGenerationScope();
|
||||
}
|
||||
|
||||
@ -2072,13 +2105,20 @@ namespace ts {
|
||||
* Emits any prologue directives at the start of a Statement list, returning the
|
||||
* number of prologue directives written to the output.
|
||||
*/
|
||||
function emitPrologueDirectives(statements: Node[], startWithNewLine?: boolean): number {
|
||||
function emitPrologueDirectives(statements: Node[], startWithNewLine?: boolean, seenPrologueDirectives?: Map<String>): number {
|
||||
for (let i = 0; i < statements.length; i++) {
|
||||
if (isPrologueDirective(statements[i])) {
|
||||
if (startWithNewLine || i > 0) {
|
||||
writeLine();
|
||||
const statement = statements[i];
|
||||
if (isPrologueDirective(statement)) {
|
||||
const shouldEmitPrologueDirective = seenPrologueDirectives ? !seenPrologueDirectives.has(statement.expression.text) : true;
|
||||
if (shouldEmitPrologueDirective) {
|
||||
if (startWithNewLine || i > 0) {
|
||||
writeLine();
|
||||
}
|
||||
emit(statement);
|
||||
if (seenPrologueDirectives) {
|
||||
seenPrologueDirectives.set(statement.expression.text, statement.expression.text);
|
||||
}
|
||||
}
|
||||
emit(statements[i]);
|
||||
}
|
||||
else {
|
||||
// return index of the first non prologue directive
|
||||
@ -2089,18 +2129,43 @@ namespace ts {
|
||||
return statements.length;
|
||||
}
|
||||
|
||||
function emitPrologueDirectivesIfNeeded(sourceFileOrBundle: Bundle | SourceFile) {
|
||||
if (isSourceFile(sourceFileOrBundle)) {
|
||||
setSourceFile(sourceFileOrBundle as SourceFile);
|
||||
emitPrologueDirectives((sourceFileOrBundle as SourceFile).statements);
|
||||
}
|
||||
else {
|
||||
const seenPrologueDirectives = createMap<String>();
|
||||
for (const sourceFile of (sourceFileOrBundle as Bundle).sourceFiles) {
|
||||
setSourceFile(sourceFile);
|
||||
emitPrologueDirectives(sourceFile.statements, /*startWithNewLine*/ true, seenPrologueDirectives);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitShebangIfNeeded(sourceFileOrBundle: Bundle | SourceFile) {
|
||||
if (isSourceFile(sourceFileOrBundle)) {
|
||||
const shebang = getShebang(sourceFileOrBundle.text);
|
||||
if (shebang) {
|
||||
write(shebang);
|
||||
writeLine();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const sourceFile of sourceFileOrBundle.sourceFiles) {
|
||||
// Emit only the first encountered shebang
|
||||
if (emitShebangIfNeeded(sourceFile)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Helpers
|
||||
//
|
||||
|
||||
function emitShebang() {
|
||||
const shebang = getShebang(currentSourceFile.text);
|
||||
if (shebang) {
|
||||
write(shebang);
|
||||
writeLine();
|
||||
}
|
||||
}
|
||||
|
||||
function emitModifiers(node: Node, modifiers: NodeArray<Modifier>) {
|
||||
if (modifiers && modifiers.length) {
|
||||
emitList(node, modifiers, ListFormat.Modifiers);
|
||||
@ -2198,6 +2263,10 @@ namespace ts {
|
||||
write(getOpeningBracket(format));
|
||||
}
|
||||
|
||||
if (onBeforeEmitNodeArray) {
|
||||
onBeforeEmitNodeArray(children);
|
||||
}
|
||||
|
||||
if (isEmpty) {
|
||||
// Write a line terminator if the parent node was multi-line
|
||||
if (format & ListFormat.MultiLine) {
|
||||
@ -2313,6 +2382,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (onAfterEmitNodeArray) {
|
||||
onAfterEmitNodeArray(children);
|
||||
}
|
||||
|
||||
if (format & ListFormat.BracketsMask) {
|
||||
write(getClosingBracket(format));
|
||||
}
|
||||
@ -2564,7 +2637,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
return getLiteralText(node, currentSourceFile, languageVersion);
|
||||
return getLiteralText(node, currentSourceFile);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2903,4 +2976,4 @@ namespace ts {
|
||||
Parameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | Parenthesis,
|
||||
IndexSignatureParameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | SquareBrackets,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/// <reference path="core.ts" />
|
||||
/// <reference path="core.ts" />
|
||||
/// <reference path="diagnosticInformationMap.generated.ts" />
|
||||
|
||||
namespace ts {
|
||||
@ -135,7 +135,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
let typeRoots: string[];
|
||||
forEachAncestorDirectory(currentDirectory, directory => {
|
||||
forEachAncestorDirectory(ts.normalizePath(currentDirectory), directory => {
|
||||
const atTypes = combinePaths(directory, nodeModulesAtTypes);
|
||||
if (host.directoryExists(atTypes)) {
|
||||
(typeRoots || (typeRoots = [])).push(atTypes);
|
||||
@ -249,13 +249,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a set of options, returns the set of type directive names
|
||||
* that should be included for this program automatically.
|
||||
* This list could either come from the config file,
|
||||
* or from enumerating the types root + initial secondary types lookup location.
|
||||
* More type directives might appear in the program later as a result of loading actual source files;
|
||||
* this list is only the set of defaults that are implicitly included.
|
||||
*/
|
||||
* Given a set of options, returns the set of type directive names
|
||||
* that should be included for this program automatically.
|
||||
* This list could either come from the config file,
|
||||
* or from enumerating the types root + initial secondary types lookup location.
|
||||
* More type directives might appear in the program later as a result of loading actual source files;
|
||||
* this list is only the set of defaults that are implicitly included.
|
||||
*/
|
||||
export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): string[] {
|
||||
// Use explicit type list from tsconfig.json
|
||||
if (options.types) {
|
||||
@ -656,7 +656,7 @@ namespace ts {
|
||||
// A path mapping may have a ".ts" extension; in contrast to an import, which should omit it.
|
||||
const tsExtension = tryGetExtensionFromPath(candidate);
|
||||
if (tsExtension !== undefined) {
|
||||
const path = tryFile(candidate, failedLookupLocations, /*onlyRecordFailures*/false, state);
|
||||
const path = tryFile(candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state);
|
||||
return path && { path, extension: tsExtension };
|
||||
}
|
||||
|
||||
@ -675,7 +675,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations {
|
||||
return nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, /* jsOnly*/ false);
|
||||
return nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, /*jsOnly*/ false);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@ -694,7 +694,7 @@ namespace ts {
|
||||
return { resolvedModule: undefined, failedLookupLocations };
|
||||
|
||||
function tryResolve(extensions: Extensions): SearchResult<{ resolved: Resolved, isExternalLibraryImport: boolean }> {
|
||||
const loader: ResolutionKindSpecificLoader = (extensions, candidate, failedLookupLocations, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/true);
|
||||
const loader: ResolutionKindSpecificLoader = (extensions, candidate, failedLookupLocations, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ true);
|
||||
const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state);
|
||||
if (resolved) {
|
||||
return toSearchResult({ resolved, isExternalLibraryImport: false });
|
||||
@ -710,7 +710,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
|
||||
const resolved = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/true);
|
||||
const resolved = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true);
|
||||
return resolved && toSearchResult({ resolved, isExternalLibraryImport: false });
|
||||
}
|
||||
}
|
||||
@ -962,7 +962,7 @@ namespace ts {
|
||||
const result = cache && cache.get(containingDirectory);
|
||||
if (result) {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName)
|
||||
trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName);
|
||||
}
|
||||
return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension } };
|
||||
}
|
||||
@ -1060,4 +1060,4 @@ namespace ts {
|
||||
directory = parentPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,6 +66,7 @@ namespace ts {
|
||||
case SyntaxKind.TypeParameter:
|
||||
return visitNode(cbNode, (<TypeParameterDeclaration>node).name) ||
|
||||
visitNode(cbNode, (<TypeParameterDeclaration>node).constraint) ||
|
||||
visitNode(cbNode, (<TypeParameterDeclaration>node).default) ||
|
||||
visitNode(cbNode, (<TypeParameterDeclaration>node).expression);
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
return visitNodes(cbNodes, node.decorators) ||
|
||||
@ -242,7 +243,8 @@ namespace ts {
|
||||
visitNode(cbNode, (<ForInStatement>node).expression) ||
|
||||
visitNode(cbNode, (<ForInStatement>node).statement);
|
||||
case SyntaxKind.ForOfStatement:
|
||||
return visitNode(cbNode, (<ForOfStatement>node).initializer) ||
|
||||
return visitNode(cbNode, (<ForOfStatement>node).awaitModifier) ||
|
||||
visitNode(cbNode, (<ForOfStatement>node).initializer) ||
|
||||
visitNode(cbNode, (<ForOfStatement>node).expression) ||
|
||||
visitNode(cbNode, (<ForOfStatement>node).statement);
|
||||
case SyntaxKind.ContinueStatement:
|
||||
@ -368,7 +370,9 @@ namespace ts {
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
return visitNode(cbNode, (<JsxOpeningLikeElement>node).tagName) ||
|
||||
visitNodes(cbNodes, (<JsxOpeningLikeElement>node).attributes);
|
||||
visitNode(cbNode, (<JsxOpeningLikeElement>node).attributes);
|
||||
case SyntaxKind.JsxAttributes:
|
||||
return visitNodes(cbNodes, (<JsxAttributes>node).properties);
|
||||
case SyntaxKind.JsxAttribute:
|
||||
return visitNode(cbNode, (<JsxAttribute>node).name) ||
|
||||
visitNode(cbNode, (<JsxAttribute>node).initializer);
|
||||
@ -1263,6 +1267,7 @@ namespace ts {
|
||||
function nextTokenIsClassOrFunctionOrAsync(): boolean {
|
||||
nextToken();
|
||||
return token() === SyntaxKind.ClassKeyword || token() === SyntaxKind.FunctionKeyword ||
|
||||
(token() === SyntaxKind.AbstractKeyword && lookAhead(nextTokenIsClassKeywordOnSameLine)) ||
|
||||
(token() === SyntaxKind.AsyncKeyword && lookAhead(nextTokenIsFunctionKeywordOnSameLine));
|
||||
}
|
||||
|
||||
@ -1305,7 +1310,7 @@ namespace ts {
|
||||
case ParsingContext.ObjectBindingElements:
|
||||
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 {
|
||||
// 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.
|
||||
if (token() === SyntaxKind.OpenBraceToken) {
|
||||
return lookAhead(isValidHeritageClauseObjectLiteral);
|
||||
@ -1840,7 +1845,7 @@ namespace ts {
|
||||
case ParsingContext.JSDocTupleTypes: return Diagnostics.Type_expected;
|
||||
case ParsingContext.JSDocRecordMembers: return Diagnostics.Property_assignment_expected;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Parses a comma-delimited list of elements
|
||||
function parseDelimitedList<T extends Node>(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray<T> {
|
||||
@ -2026,32 +2031,27 @@ namespace ts {
|
||||
node.isUnterminated = true;
|
||||
}
|
||||
|
||||
const tokenPos = scanner.getTokenPos();
|
||||
nextToken();
|
||||
finishNode(node);
|
||||
|
||||
// Octal literals are not allowed in strict mode or ES5
|
||||
// Note that theoretically the following condition would hold true literals like 009,
|
||||
// which is not octal.But because of how the scanner separates the tokens, we would
|
||||
// never get a token like this. Instead, we would get 00 and 9 as two separate tokens.
|
||||
// We also do not need to check for negatives because any prefix operator would be part of a
|
||||
// parent unary expression.
|
||||
if (node.kind === SyntaxKind.NumericLiteral
|
||||
&& sourceText.charCodeAt(tokenPos) === CharacterCodes._0
|
||||
&& isOctalDigit(sourceText.charCodeAt(tokenPos + 1))) {
|
||||
|
||||
node.isOctalLiteral = true;
|
||||
if (node.kind === SyntaxKind.NumericLiteral) {
|
||||
(<NumericLiteral>node).numericLiteralFlags = scanner.getNumericLiteralFlags();
|
||||
}
|
||||
|
||||
nextToken();
|
||||
finishNode(node);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
// TYPES
|
||||
|
||||
function parseTypeReference(): TypeReferenceNode {
|
||||
const typeName = parseEntityName(/*allowReservedWords*/ false, Diagnostics.Type_expected);
|
||||
const node = <TypeReferenceNode>createNode(SyntaxKind.TypeReference, typeName.pos);
|
||||
node.typeName = typeName;
|
||||
const node = <TypeReferenceNode>createNode(SyntaxKind.TypeReference);
|
||||
node.typeName = parseEntityName(/*allowReservedWords*/ false, Diagnostics.Type_expected);
|
||||
if (!scanner.hasPrecedingLineBreak() && token() === SyntaxKind.LessThanToken) {
|
||||
node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken);
|
||||
}
|
||||
@ -2102,10 +2102,14 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (parseOptional(SyntaxKind.EqualsToken)) {
|
||||
node.default = parseType();
|
||||
}
|
||||
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseTypeParameters(): NodeArray<TypeParameterDeclaration> {
|
||||
function parseTypeParameters(): NodeArray<TypeParameterDeclaration> | undefined {
|
||||
if (token() === SyntaxKind.LessThanToken) {
|
||||
return parseBracketedList(ParsingContext.TypeParameters, parseTypeParameter, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken);
|
||||
}
|
||||
@ -2126,7 +2130,7 @@ namespace ts {
|
||||
function parseParameter(): ParameterDeclaration {
|
||||
const node = <ParameterDeclaration>createNode(SyntaxKind.Parameter);
|
||||
if (token() === SyntaxKind.ThisKeyword) {
|
||||
node.name = createIdentifier(/*isIdentifier*/true, undefined);
|
||||
node.name = createIdentifier(/*isIdentifier*/ true);
|
||||
node.type = parseParameterType();
|
||||
return finishNode(node);
|
||||
}
|
||||
@ -2175,7 +2179,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function fillSignature(
|
||||
returnToken: SyntaxKind,
|
||||
returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken,
|
||||
yieldContext: boolean,
|
||||
awaitContext: boolean,
|
||||
requireCompleteParameterList: boolean,
|
||||
@ -2365,14 +2369,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isTypeMemberStart(): boolean {
|
||||
let idToken: SyntaxKind;
|
||||
// Return true if we have the start of a signature member
|
||||
if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) {
|
||||
return true;
|
||||
}
|
||||
let idToken: boolean;
|
||||
// Eat up all modifiers, but hold on to the last one in case it is actually an identifier
|
||||
while (isModifierKind(token())) {
|
||||
idToken = token();
|
||||
idToken = true;
|
||||
nextToken();
|
||||
}
|
||||
// Index signatures and computed property names are type members
|
||||
@ -2381,7 +2385,7 @@ namespace ts {
|
||||
}
|
||||
// Try to get the first property-like token following all modifiers
|
||||
if (isLiteralPropertyName()) {
|
||||
idToken = token();
|
||||
idToken = true;
|
||||
nextToken();
|
||||
}
|
||||
// If we were able to get any potential identifier, check that it is
|
||||
@ -2489,7 +2493,7 @@ namespace ts {
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseKeywordAndNoDot(): TypeNode {
|
||||
function parseKeywordAndNoDot(): TypeNode | undefined {
|
||||
const node = parseTokenNode<TypeNode>();
|
||||
return token() === SyntaxKind.DotToken ? undefined : node;
|
||||
}
|
||||
@ -2627,7 +2631,7 @@ namespace ts {
|
||||
return parseArrayTypeOrHigher();
|
||||
}
|
||||
|
||||
function parseUnionOrIntersectionType(kind: SyntaxKind, parseConstituentType: () => TypeNode, operator: SyntaxKind): TypeNode {
|
||||
function parseUnionOrIntersectionType(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, parseConstituentType: () => TypeNode, operator: SyntaxKind.BarToken | SyntaxKind.AmpersandToken): TypeNode {
|
||||
parseOptional(operator);
|
||||
let type = parseConstituentType();
|
||||
if (token() === operator) {
|
||||
@ -3035,7 +3039,7 @@ namespace ts {
|
||||
// If we have an arrow, then try to parse the body. Even if not, try to parse if we
|
||||
// have an opening brace, just in case we're in an error state.
|
||||
const lastToken = token();
|
||||
arrowFunction.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, /*reportAtCurrentPosition*/false, Diagnostics._0_expected, "=>");
|
||||
arrowFunction.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, "=>");
|
||||
arrowFunction.body = (lastToken === SyntaxKind.EqualsGreaterThanToken || lastToken === SyntaxKind.OpenBraceToken)
|
||||
? parseArrowFunctionExpressionBody(isAsync)
|
||||
: parseIdentifier();
|
||||
@ -3804,7 +3808,7 @@ namespace ts {
|
||||
// Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios
|
||||
// of one sort or another.
|
||||
if (inExpressionContext && token() === SyntaxKind.LessThanToken) {
|
||||
const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElement(/*inExpressionContext*/true));
|
||||
const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true));
|
||||
if (invalidElement) {
|
||||
parseErrorAtCurrentToken(Diagnostics.JSX_expressions_must_have_one_parent_element);
|
||||
const badNode = <BinaryExpression>createNode(SyntaxKind.BinaryExpression, result.pos);
|
||||
@ -3855,6 +3859,9 @@ namespace ts {
|
||||
parseErrorAtPosition(openingTagName.pos, openingTagName.end - openingTagName.pos, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, openingTagName));
|
||||
break;
|
||||
}
|
||||
else if (token() === SyntaxKind.ConflictMarkerTrivia) {
|
||||
break;
|
||||
}
|
||||
result.push(parseJsxChild());
|
||||
}
|
||||
|
||||
@ -3865,14 +3872,20 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseJsxAttributes(): JsxAttributes {
|
||||
const jsxAttributes = <JsxAttributes>createNode(SyntaxKind.JsxAttributes);
|
||||
jsxAttributes.properties = parseList(ParsingContext.JsxAttributes, parseJsxAttribute);
|
||||
return finishNode(jsxAttributes);
|
||||
}
|
||||
|
||||
function parseJsxOpeningOrSelfClosingElement(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement {
|
||||
const fullStart = scanner.getStartPos();
|
||||
|
||||
parseExpected(SyntaxKind.LessThanToken);
|
||||
|
||||
const tagName = parseJsxElementName();
|
||||
const attributes = parseJsxAttributes();
|
||||
|
||||
const attributes = parseList(ParsingContext.JsxAttributes, parseJsxAttribute);
|
||||
let node: JsxOpeningLikeElement;
|
||||
|
||||
if (token() === SyntaxKind.GreaterThanToken) {
|
||||
@ -4448,6 +4461,7 @@ namespace ts {
|
||||
function parseForOrForInOrForOfStatement(): Statement {
|
||||
const pos = getNodePos();
|
||||
parseExpected(SyntaxKind.ForKeyword);
|
||||
const awaitToken = parseOptionalToken(SyntaxKind.AwaitKeyword);
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
|
||||
let initializer: VariableDeclarationList | Expression = undefined;
|
||||
@ -4460,20 +4474,21 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
let forOrForInOrForOfStatement: IterationStatement;
|
||||
if (parseOptional(SyntaxKind.InKeyword)) {
|
||||
if (awaitToken ? parseExpected(SyntaxKind.OfKeyword) : parseOptional(SyntaxKind.OfKeyword)) {
|
||||
const forOfStatement = <ForOfStatement>createNode(SyntaxKind.ForOfStatement, pos);
|
||||
forOfStatement.awaitModifier = awaitToken;
|
||||
forOfStatement.initializer = initializer;
|
||||
forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
forOrForInOrForOfStatement = forOfStatement;
|
||||
}
|
||||
else if (parseOptional(SyntaxKind.InKeyword)) {
|
||||
const forInStatement = <ForInStatement>createNode(SyntaxKind.ForInStatement, pos);
|
||||
forInStatement.initializer = initializer;
|
||||
forInStatement.expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
forOrForInOrForOfStatement = forInStatement;
|
||||
}
|
||||
else if (parseOptional(SyntaxKind.OfKeyword)) {
|
||||
const forOfStatement = <ForOfStatement>createNode(SyntaxKind.ForOfStatement, pos);
|
||||
forOfStatement.initializer = initializer;
|
||||
forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
forOrForInOrForOfStatement = forOfStatement;
|
||||
}
|
||||
else {
|
||||
const forStatement = <ForStatement>createNode(SyntaxKind.ForStatement, pos);
|
||||
forStatement.initializer = initializer;
|
||||
@ -4642,6 +4657,11 @@ namespace ts {
|
||||
return tokenIsIdentifierOrKeyword(token()) && !scanner.hasPrecedingLineBreak();
|
||||
}
|
||||
|
||||
function nextTokenIsClassKeywordOnSameLine() {
|
||||
nextToken();
|
||||
return token() === SyntaxKind.ClassKeyword && !scanner.hasPrecedingLineBreak();
|
||||
}
|
||||
|
||||
function nextTokenIsFunctionKeywordOnSameLine() {
|
||||
nextToken();
|
||||
return token() === SyntaxKind.FunctionKeyword && !scanner.hasPrecedingLineBreak();
|
||||
@ -5265,8 +5285,8 @@ namespace ts {
|
||||
*
|
||||
* In such situations, 'permitInvalidConstAsModifier' should be set to true.
|
||||
*/
|
||||
function parseModifiers(permitInvalidConstAsModifier?: boolean): NodeArray<Modifier> {
|
||||
let modifiers: NodeArray<Modifier>;
|
||||
function parseModifiers(permitInvalidConstAsModifier?: boolean): NodeArray<Modifier> | undefined {
|
||||
let modifiers: NodeArray<Modifier> | undefined;
|
||||
while (true) {
|
||||
const modifierStart = scanner.getStartPos();
|
||||
const modifierKind = token();
|
||||
@ -5406,7 +5426,7 @@ namespace ts {
|
||||
return token() === SyntaxKind.ImplementsKeyword && lookAhead(nextTokenIsIdentifierOrKeyword);
|
||||
}
|
||||
|
||||
function parseHeritageClauses(): NodeArray<HeritageClause> {
|
||||
function parseHeritageClauses(): NodeArray<HeritageClause> | undefined {
|
||||
// ClassTail[Yield,Await] : (Modified) See 14.5
|
||||
// ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
|
||||
|
||||
@ -5417,10 +5437,11 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function parseHeritageClause() {
|
||||
if (token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword) {
|
||||
function parseHeritageClause(): HeritageClause | undefined {
|
||||
const tok = token();
|
||||
if (tok === SyntaxKind.ExtendsKeyword || tok === SyntaxKind.ImplementsKeyword) {
|
||||
const node = <HeritageClause>createNode(SyntaxKind.HeritageClause);
|
||||
node.token = token();
|
||||
node.token = tok;
|
||||
nextToken();
|
||||
node.types = parseDelimitedList(ParsingContext.HeritageClauseElement, parseExpressionWithTypeArguments);
|
||||
return finishNode(node);
|
||||
@ -5443,7 +5464,7 @@ namespace ts {
|
||||
return token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword;
|
||||
}
|
||||
|
||||
function parseClassMembers() {
|
||||
function parseClassMembers(): NodeArray<ClassElement> {
|
||||
return parseList(ParsingContext.ClassMembers, parseClassElement);
|
||||
}
|
||||
|
||||
@ -5602,17 +5623,7 @@ namespace ts {
|
||||
if (isIdentifier()) {
|
||||
identifier = parseIdentifier();
|
||||
if (token() !== SyntaxKind.CommaToken && token() !== SyntaxKind.FromKeyword) {
|
||||
// ImportEquals declaration of type:
|
||||
// import x = require("mod"); or
|
||||
// import x = M.x;
|
||||
const importEqualsDeclaration = <ImportEqualsDeclaration>createNode(SyntaxKind.ImportEqualsDeclaration, fullStart);
|
||||
importEqualsDeclaration.decorators = decorators;
|
||||
importEqualsDeclaration.modifiers = modifiers;
|
||||
importEqualsDeclaration.name = identifier;
|
||||
parseExpected(SyntaxKind.EqualsToken);
|
||||
importEqualsDeclaration.moduleReference = parseModuleReference();
|
||||
parseSemicolon();
|
||||
return addJSDocComment(finishNode(importEqualsDeclaration));
|
||||
return parseImportEqualsDeclaration(fullStart, decorators, modifiers, identifier);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5636,6 +5647,17 @@ namespace ts {
|
||||
return finishNode(importDeclaration);
|
||||
}
|
||||
|
||||
function parseImportEqualsDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: NodeArray<Modifier>, identifier: ts.Identifier): ImportEqualsDeclaration {
|
||||
const importEqualsDeclaration = <ImportEqualsDeclaration>createNode(SyntaxKind.ImportEqualsDeclaration, fullStart);
|
||||
importEqualsDeclaration.decorators = decorators;
|
||||
importEqualsDeclaration.modifiers = modifiers;
|
||||
importEqualsDeclaration.name = identifier;
|
||||
parseExpected(SyntaxKind.EqualsToken);
|
||||
importEqualsDeclaration.moduleReference = parseModuleReference();
|
||||
parseSemicolon();
|
||||
return addJSDocComment(finishNode(importEqualsDeclaration));
|
||||
}
|
||||
|
||||
function parseImportClause(identifier: Identifier, fullStart: number) {
|
||||
// ImportClause:
|
||||
// ImportedDefaultBinding
|
||||
@ -5796,11 +5818,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
function processReferenceComments(sourceFile: SourceFile): void {
|
||||
const triviaScanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/false, LanguageVariant.Standard, sourceText);
|
||||
const triviaScanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/ false, LanguageVariant.Standard, sourceText);
|
||||
const referencedFiles: FileReference[] = [];
|
||||
const typeReferenceDirectives: FileReference[] = [];
|
||||
const amdDependencies: { path: string; name: string }[] = [];
|
||||
let amdModuleName: string;
|
||||
let checkJsDirective: CheckJsDirective = undefined;
|
||||
|
||||
// Keep scanning all the leading trivia in the file until we get to something that
|
||||
// isn't trivia. Any single line comment will be analyzed to see if it is a
|
||||
@ -5816,7 +5839,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const range = { pos: triviaScanner.getTokenPos(), end: triviaScanner.getTextPos(), kind: triviaScanner.getToken() };
|
||||
const range = {
|
||||
kind: <SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia>triviaScanner.getToken(),
|
||||
pos: triviaScanner.getTokenPos(),
|
||||
end: triviaScanner.getTextPos(),
|
||||
};
|
||||
|
||||
const comment = sourceText.substring(range.pos, range.end);
|
||||
const referencePathMatchResult = getFileReferenceFromReferencePath(comment, range);
|
||||
@ -5858,6 +5885,16 @@ namespace ts {
|
||||
amdDependencies.push(amdDependency);
|
||||
}
|
||||
}
|
||||
|
||||
const checkJsDirectiveRegEx = /^\/\/\/?\s*(@ts-check|@ts-nocheck)\s*$/gim;
|
||||
const checkJsDirectiveMatchResult = checkJsDirectiveRegEx.exec(comment);
|
||||
if (checkJsDirectiveMatchResult) {
|
||||
checkJsDirective = {
|
||||
enabled: compareStrings(checkJsDirectiveMatchResult[1], "@ts-check", /*ignoreCase*/ true) === Comparison.EqualTo,
|
||||
end: range.end,
|
||||
pos: range.pos
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5865,6 +5902,7 @@ namespace ts {
|
||||
sourceFile.typeReferenceDirectives = typeReferenceDirectives;
|
||||
sourceFile.amdDependencies = amdDependencies;
|
||||
sourceFile.moduleName = amdModuleName;
|
||||
sourceFile.checkJsDirective = checkJsDirective;
|
||||
}
|
||||
|
||||
function setExternalModuleIndicator(sourceFile: SourceFile) {
|
||||
@ -6491,7 +6529,7 @@ namespace ts {
|
||||
|
||||
function parseTagComments(indent: number) {
|
||||
const comments: string[] = [];
|
||||
let state = JSDocState.SawAsterisk;
|
||||
let state = JSDocState.BeginningOfLine;
|
||||
let margin: number | undefined;
|
||||
function pushComment(text: string) {
|
||||
if (!margin) {
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
namespace ts {
|
||||
const emptyArray: any[] = [];
|
||||
const ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/;
|
||||
|
||||
export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string {
|
||||
while (true) {
|
||||
@ -87,9 +88,6 @@ namespace ts {
|
||||
return sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||
}
|
||||
|
||||
// returned by CScript sys environment
|
||||
const unsupportedFileEncodingErrorCode = -2147024809;
|
||||
|
||||
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile {
|
||||
let text: string;
|
||||
try {
|
||||
@ -100,9 +98,7 @@ namespace ts {
|
||||
}
|
||||
catch (e) {
|
||||
if (onError) {
|
||||
onError(e.number === unsupportedFileEncodingErrorCode
|
||||
? createCompilerDiagnostic(Diagnostics.Unsupported_file_encoding).messageText
|
||||
: e.message);
|
||||
onError(e.message);
|
||||
}
|
||||
text = "";
|
||||
}
|
||||
@ -290,6 +286,11 @@ namespace ts {
|
||||
return resolutions;
|
||||
}
|
||||
|
||||
interface DiagnosticCache {
|
||||
perFile?: FileMap<Diagnostic[]>;
|
||||
allDiagnostics?: Diagnostic[];
|
||||
}
|
||||
|
||||
export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program {
|
||||
let program: Program;
|
||||
let files: SourceFile[] = [];
|
||||
@ -298,6 +299,9 @@ namespace ts {
|
||||
let noDiagnosticsTypeChecker: TypeChecker;
|
||||
let classifiableNames: Map<string>;
|
||||
|
||||
const cachedSemanticDiagnosticsForFile: DiagnosticCache = {};
|
||||
const cachedDeclarationDiagnosticsForFile: DiagnosticCache = {};
|
||||
|
||||
let resolvedTypeReferenceDirectives = createMap<ResolvedTypeReferenceDirective>();
|
||||
let fileProcessingDiagnostics = createDiagnosticCollection();
|
||||
|
||||
@ -754,15 +758,15 @@ namespace ts {
|
||||
return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = createTypeChecker(program, /*produceDiagnostics:*/ false));
|
||||
}
|
||||
|
||||
function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean): EmitResult {
|
||||
return runWithCancellationToken(() => emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles));
|
||||
function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, transformers?: CustomTransformers): EmitResult {
|
||||
return runWithCancellationToken(() => emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers));
|
||||
}
|
||||
|
||||
function isEmitBlocked(emitFileName: string): boolean {
|
||||
return hasEmitBlockingDiagnostics.contains(toPath(emitFileName, currentDirectory, getCanonicalFileName));
|
||||
}
|
||||
|
||||
function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken, emitOnlyDtsFiles?: boolean): EmitResult {
|
||||
function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult {
|
||||
let declarationDiagnostics: Diagnostic[] = [];
|
||||
|
||||
if (options.noEmit) {
|
||||
@ -804,11 +808,13 @@ namespace ts {
|
||||
|
||||
performance.mark("beforeEmit");
|
||||
|
||||
const transformers = emitOnlyDtsFiles ? [] : getTransformers(options, customTransformers);
|
||||
const emitResult = emitFiles(
|
||||
emitResolver,
|
||||
getEmitHost(writeFileCallback),
|
||||
sourceFile,
|
||||
emitOnlyDtsFiles);
|
||||
emitOnlyDtsFiles,
|
||||
transformers);
|
||||
|
||||
performance.mark("afterEmit");
|
||||
performance.measure("Emit", "beforeEmit", "afterEmit");
|
||||
@ -897,22 +903,51 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedSemanticDiagnosticsForFile, getSemanticDiagnosticsForFileNoCache);
|
||||
}
|
||||
|
||||
function getSemanticDiagnosticsForFileNoCache(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return runWithCancellationToken(() => {
|
||||
const typeChecker = getDiagnosticsProducingTypeChecker();
|
||||
|
||||
Debug.assert(!!sourceFile.bindDiagnostics);
|
||||
const bindDiagnostics = sourceFile.bindDiagnostics;
|
||||
// For JavaScript files, we don't want to report semantic errors.
|
||||
// Instead, we'll report errors for using TypeScript-only constructs from within a
|
||||
// JavaScript file when we get syntactic diagnostics for the file.
|
||||
const checkDiagnostics = isSourceFileJavaScript(sourceFile) ? [] : typeChecker.getDiagnostics(sourceFile, cancellationToken);
|
||||
// For JavaScript files, we don't want to report semantic errors unless explicitly requested.
|
||||
const includeCheckDiagnostics = !isSourceFileJavaScript(sourceFile) || isCheckJsEnabledForFile(sourceFile, options);
|
||||
const checkDiagnostics = includeCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : [];
|
||||
const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
|
||||
const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
|
||||
|
||||
return bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile);
|
||||
const diagnostics = bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile);
|
||||
return isSourceFileJavaScript(sourceFile)
|
||||
? filter(diagnostics, shouldReportDiagnostic)
|
||||
: diagnostics;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip errors if previous line start with '// @ts-ignore' comment, not counting non-empty non-comment lines
|
||||
*/
|
||||
function shouldReportDiagnostic(diagnostic: Diagnostic) {
|
||||
const { file, start } = diagnostic;
|
||||
const lineStarts = getLineStarts(file);
|
||||
let { line } = computeLineAndCharacterOfPosition(lineStarts, start);
|
||||
while (line > 0) {
|
||||
const previousLineText = file.text.slice(lineStarts[line - 1], lineStarts[line]);
|
||||
const result = ignoreDiagnosticCommentRegEx.exec(previousLineText);
|
||||
if (!result) {
|
||||
// non-empty line
|
||||
return true;
|
||||
}
|
||||
if (result[3]) {
|
||||
// @ts-ignore
|
||||
return false;
|
||||
}
|
||||
line--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function getJavaScriptSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
|
||||
return runWithCancellationToken(() => {
|
||||
const diagnostics: Diagnostic[] = [];
|
||||
@ -1092,7 +1127,11 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
function getDeclarationDiagnosticsWorker(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
function getDeclarationDiagnosticsWorker(sourceFile: SourceFile | undefined, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedDeclarationDiagnosticsForFile, getDeclarationDiagnosticsForFileNoCache);
|
||||
}
|
||||
|
||||
function getDeclarationDiagnosticsForFileNoCache(sourceFile: SourceFile | undefined, cancellationToken: CancellationToken) {
|
||||
return runWithCancellationToken(() => {
|
||||
const resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
|
||||
// Don't actually write any files since we're just getting diagnostics.
|
||||
@ -1100,6 +1139,32 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
function getAndCacheDiagnostics(
|
||||
sourceFile: SourceFile | undefined,
|
||||
cancellationToken: CancellationToken,
|
||||
cache: DiagnosticCache,
|
||||
getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => Diagnostic[]) {
|
||||
|
||||
const cachedResult = sourceFile
|
||||
? cache.perFile && cache.perFile.get(sourceFile.path)
|
||||
: cache.allDiagnostics;
|
||||
|
||||
if (cachedResult) {
|
||||
return cachedResult;
|
||||
}
|
||||
const result = getDiagnostics(sourceFile, cancellationToken) || emptyArray;
|
||||
if (sourceFile) {
|
||||
if (!cache.perFile) {
|
||||
cache.perFile = createFileMap<Diagnostic[]>();
|
||||
}
|
||||
cache.perFile.set(sourceFile.path, result);
|
||||
}
|
||||
else {
|
||||
cache.allDiagnostics = result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
return isDeclarationFile(sourceFile) ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
|
||||
}
|
||||
@ -1153,7 +1218,7 @@ namespace ts {
|
||||
&& !file.isDeclarationFile) {
|
||||
// synthesize 'import "tslib"' declaration
|
||||
const externalHelpersModuleReference = createLiteral(externalHelpersModuleNameText);
|
||||
const importDecl = createImportDeclaration(undefined, undefined, undefined);
|
||||
const importDecl = createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined);
|
||||
externalHelpersModuleReference.parent = importDecl;
|
||||
importDecl.parent = file;
|
||||
imports = [externalHelpersModuleReference];
|
||||
@ -1226,7 +1291,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function collectRequireCalls(node: Node): void {
|
||||
if (isRequireCall(node, /*checkArgumentIsStringLiteral*/true)) {
|
||||
if (isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
|
||||
(imports || (imports = [])).push(<StringLiteral>(<CallExpression>node).arguments[0]);
|
||||
}
|
||||
else {
|
||||
@ -1628,7 +1693,7 @@ namespace ts {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib"));
|
||||
}
|
||||
|
||||
if (options.noImplicitUseStrict && options.alwaysStrict) {
|
||||
if (options.noImplicitUseStrict && (options.alwaysStrict === undefined ? options.strict : options.alwaysStrict)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict"));
|
||||
}
|
||||
|
||||
@ -1683,6 +1748,10 @@ namespace ts {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration"));
|
||||
}
|
||||
|
||||
if (options.checkJs && !options.allowJs) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs"));
|
||||
}
|
||||
|
||||
if (options.emitDecoratorMetadata &&
|
||||
!options.experimentalDecorators) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators"));
|
||||
|
||||
@ -23,6 +23,8 @@ namespace ts {
|
||||
isIdentifier(): boolean;
|
||||
isReservedWord(): boolean;
|
||||
isUnterminated(): boolean;
|
||||
/* @internal */
|
||||
getNumericLiteralFlags(): NumericLiteralFlags;
|
||||
reScanGreaterToken(): SyntaxKind;
|
||||
reScanSlashToken(): SyntaxKind;
|
||||
reScanTemplateToken(): SyntaxKind;
|
||||
@ -333,7 +335,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function getLineStarts(sourceFile: SourceFile): number[] {
|
||||
export function getLineStarts(sourceFile: SourceFileLike): number[] {
|
||||
return sourceFile.lineMap || (sourceFile.lineMap = computeLineStarts(sourceFile.text));
|
||||
}
|
||||
|
||||
@ -608,10 +610,10 @@ namespace ts {
|
||||
* @returns If "reduce" is true, the accumulated value. If "reduce" is false, the first truthy
|
||||
* return value of the callback.
|
||||
*/
|
||||
function iterateCommentRanges<T, U>(reduce: boolean, text: string, pos: number, trailing: boolean, cb: (pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial?: U): U {
|
||||
function iterateCommentRanges<T, U>(reduce: boolean, text: string, pos: number, trailing: boolean, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial?: U): U {
|
||||
let pendingPos: number;
|
||||
let pendingEnd: number;
|
||||
let pendingKind: SyntaxKind;
|
||||
let pendingKind: CommentKind;
|
||||
let pendingHasTrailingNewLine: boolean;
|
||||
let hasPendingCommentRange = false;
|
||||
let collecting = trailing || pos === 0;
|
||||
@ -707,37 +709,37 @@ namespace ts {
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
export function forEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: T) => U, state?: T) {
|
||||
export function forEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T) {
|
||||
return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state);
|
||||
}
|
||||
|
||||
export function forEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: T) => U, state?: T) {
|
||||
export function forEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T) {
|
||||
return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state);
|
||||
}
|
||||
|
||||
export function reduceEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) {
|
||||
export function reduceEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) {
|
||||
return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ false, cb, state, initial);
|
||||
}
|
||||
|
||||
export function reduceEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) {
|
||||
export function reduceEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) {
|
||||
return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial);
|
||||
}
|
||||
|
||||
function appendCommentRange(pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, _state: any, comments: CommentRange[]) {
|
||||
function appendCommentRange(pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, _state: any, comments: CommentRange[]) {
|
||||
if (!comments) {
|
||||
comments = [];
|
||||
}
|
||||
|
||||
comments.push({ pos, end, hasTrailingNewLine, kind });
|
||||
comments.push({ kind, pos, end, hasTrailingNewLine });
|
||||
return comments;
|
||||
}
|
||||
|
||||
export function getLeadingCommentRanges(text: string, pos: number): CommentRange[] | undefined {
|
||||
return reduceEachLeadingCommentRange(text, pos, appendCommentRange, undefined, undefined);
|
||||
return reduceEachLeadingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined);
|
||||
}
|
||||
|
||||
export function getTrailingCommentRanges(text: string, pos: number): CommentRange[] | undefined {
|
||||
return reduceEachTrailingCommentRange(text, pos, appendCommentRange, undefined, undefined);
|
||||
return reduceEachTrailingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined);
|
||||
}
|
||||
|
||||
/** Optionally, get the shebang */
|
||||
@ -799,6 +801,7 @@ namespace ts {
|
||||
let precedingLineBreak: boolean;
|
||||
let hasExtendedUnicodeEscape: boolean;
|
||||
let tokenIsUnterminated: boolean;
|
||||
let numericLiteralFlags: NumericLiteralFlags;
|
||||
|
||||
setText(text, start, length);
|
||||
|
||||
@ -814,6 +817,7 @@ namespace ts {
|
||||
isIdentifier: () => token === SyntaxKind.Identifier || token > SyntaxKind.LastReservedWord,
|
||||
isReservedWord: () => token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord,
|
||||
isUnterminated: () => tokenIsUnterminated,
|
||||
getNumericLiteralFlags: () => numericLiteralFlags,
|
||||
reScanGreaterToken,
|
||||
reScanSlashToken,
|
||||
reScanTemplateToken,
|
||||
@ -850,6 +854,7 @@ namespace ts {
|
||||
let end = pos;
|
||||
if (text.charCodeAt(pos) === CharacterCodes.E || text.charCodeAt(pos) === CharacterCodes.e) {
|
||||
pos++;
|
||||
numericLiteralFlags = NumericLiteralFlags.Scientific;
|
||||
if (text.charCodeAt(pos) === CharacterCodes.plus || text.charCodeAt(pos) === CharacterCodes.minus) pos++;
|
||||
if (isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
@ -1221,6 +1226,7 @@ namespace ts {
|
||||
hasExtendedUnicodeEscape = false;
|
||||
precedingLineBreak = false;
|
||||
tokenIsUnterminated = false;
|
||||
numericLiteralFlags = 0;
|
||||
while (true) {
|
||||
tokenPos = pos;
|
||||
if (pos >= end) {
|
||||
@ -1419,6 +1425,7 @@ namespace ts {
|
||||
value = 0;
|
||||
}
|
||||
tokenValue = "" + value;
|
||||
numericLiteralFlags = NumericLiteralFlags.HexSpecifier;
|
||||
return token = SyntaxKind.NumericLiteral;
|
||||
}
|
||||
else if (pos + 2 < end && (text.charCodeAt(pos + 1) === CharacterCodes.B || text.charCodeAt(pos + 1) === CharacterCodes.b)) {
|
||||
@ -1429,6 +1436,7 @@ namespace ts {
|
||||
value = 0;
|
||||
}
|
||||
tokenValue = "" + value;
|
||||
numericLiteralFlags = NumericLiteralFlags.BinarySpecifier;
|
||||
return token = SyntaxKind.NumericLiteral;
|
||||
}
|
||||
else if (pos + 2 < end && (text.charCodeAt(pos + 1) === CharacterCodes.O || text.charCodeAt(pos + 1) === CharacterCodes.o)) {
|
||||
@ -1439,11 +1447,13 @@ namespace ts {
|
||||
value = 0;
|
||||
}
|
||||
tokenValue = "" + value;
|
||||
numericLiteralFlags = NumericLiteralFlags.OctalSpecifier;
|
||||
return token = SyntaxKind.NumericLiteral;
|
||||
}
|
||||
// Try to parse as an octal
|
||||
if (pos + 1 < end && isOctalDigit(text.charCodeAt(pos + 1))) {
|
||||
tokenValue = "" + scanOctalDigits();
|
||||
numericLiteralFlags = NumericLiteralFlags.Octal;
|
||||
return token = SyntaxKind.NumericLiteral;
|
||||
}
|
||||
// This fall-through is a deviation from the EcmaScript grammar. The grammar says that a leading zero
|
||||
@ -1716,7 +1726,14 @@ namespace ts {
|
||||
while (pos < end) {
|
||||
pos++;
|
||||
char = text.charCodeAt(pos);
|
||||
if ((char === CharacterCodes.openBrace) || (char === CharacterCodes.lessThan)) {
|
||||
if (char === CharacterCodes.openBrace) {
|
||||
break;
|
||||
}
|
||||
if (char === CharacterCodes.lessThan) {
|
||||
if (isConflictMarkerTrivia(text, pos)) {
|
||||
pos = scanConflictMarkerTrivia(text, pos, error);
|
||||
return token = SyntaxKind.ConflictMarkerTrivia;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/// <reference path="core.ts"/>
|
||||
/// <reference path="core.ts"/>
|
||||
|
||||
declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any;
|
||||
declare function clearTimeout(handle: any): void;
|
||||
@ -54,19 +54,27 @@ namespace ts {
|
||||
referenceCount: number;
|
||||
}
|
||||
|
||||
declare var require: any;
|
||||
declare var process: any;
|
||||
declare var global: any;
|
||||
declare var __filename: string;
|
||||
declare const require: any;
|
||||
declare const process: any;
|
||||
declare const global: any;
|
||||
declare const __filename: string;
|
||||
|
||||
declare class Enumerator {
|
||||
public atEnd(): boolean;
|
||||
public moveNext(): boolean;
|
||||
public item(): any;
|
||||
constructor(o: any);
|
||||
export function getNodeMajorVersion() {
|
||||
if (typeof process === "undefined") {
|
||||
return undefined;
|
||||
}
|
||||
const version: string = process.version;
|
||||
if (!version) {
|
||||
return undefined;
|
||||
}
|
||||
const dot = version.indexOf(".");
|
||||
if (dot === -1) {
|
||||
return undefined;
|
||||
}
|
||||
return parseInt(version.substring(1, dot));
|
||||
}
|
||||
|
||||
declare var ChakraHost: {
|
||||
declare const ChakraHost: {
|
||||
args: string[];
|
||||
currentDirectory: string;
|
||||
executingFile: string;
|
||||
@ -89,152 +97,6 @@ namespace ts {
|
||||
};
|
||||
|
||||
export let sys: System = (function() {
|
||||
|
||||
function getWScriptSystem(): System {
|
||||
|
||||
const fso = new ActiveXObject("Scripting.FileSystemObject");
|
||||
const shell = new ActiveXObject("WScript.Shell");
|
||||
|
||||
const fileStream = new ActiveXObject("ADODB.Stream");
|
||||
fileStream.Type = 2 /*text*/;
|
||||
|
||||
const binaryStream = new ActiveXObject("ADODB.Stream");
|
||||
binaryStream.Type = 1 /*binary*/;
|
||||
|
||||
const args: string[] = [];
|
||||
for (let i = 0; i < WScript.Arguments.length; i++) {
|
||||
args[i] = WScript.Arguments.Item(i);
|
||||
}
|
||||
|
||||
function readFile(fileName: string, encoding?: string): string {
|
||||
if (!fso.FileExists(fileName)) {
|
||||
return undefined;
|
||||
}
|
||||
fileStream.Open();
|
||||
try {
|
||||
if (encoding) {
|
||||
fileStream.Charset = encoding;
|
||||
fileStream.LoadFromFile(fileName);
|
||||
}
|
||||
else {
|
||||
// Load file and read the first two bytes into a string with no interpretation
|
||||
fileStream.Charset = "x-ansi";
|
||||
fileStream.LoadFromFile(fileName);
|
||||
const bom = fileStream.ReadText(2) || "";
|
||||
// Position must be at 0 before encoding can be changed
|
||||
fileStream.Position = 0;
|
||||
// [0xFF,0xFE] and [0xFE,0xFF] mean utf-16 (little or big endian), otherwise default to utf-8
|
||||
fileStream.Charset = bom.length >= 2 && (bom.charCodeAt(0) === 0xFF && bom.charCodeAt(1) === 0xFE || bom.charCodeAt(0) === 0xFE && bom.charCodeAt(1) === 0xFF) ? "unicode" : "utf-8";
|
||||
}
|
||||
// ReadText method always strips byte order mark from resulting string
|
||||
return fileStream.ReadText();
|
||||
}
|
||||
catch (e) {
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
fileStream.Close();
|
||||
}
|
||||
}
|
||||
|
||||
function writeFile(fileName: string, data: string, writeByteOrderMark?: boolean): void {
|
||||
fileStream.Open();
|
||||
binaryStream.Open();
|
||||
try {
|
||||
// Write characters in UTF-8 encoding
|
||||
fileStream.Charset = "utf-8";
|
||||
fileStream.WriteText(data);
|
||||
// If we don't want the BOM, then skip it by setting the starting location to 3 (size of BOM).
|
||||
// If not, start from position 0, as the BOM will be added automatically when charset==utf8.
|
||||
if (writeByteOrderMark) {
|
||||
fileStream.Position = 0;
|
||||
}
|
||||
else {
|
||||
fileStream.Position = 3;
|
||||
}
|
||||
fileStream.CopyTo(binaryStream);
|
||||
binaryStream.SaveToFile(fileName, 2 /*overwrite*/);
|
||||
}
|
||||
finally {
|
||||
binaryStream.Close();
|
||||
fileStream.Close();
|
||||
}
|
||||
}
|
||||
|
||||
function getNames(collection: any): string[] {
|
||||
const result: string[] = [];
|
||||
for (const e = new Enumerator(collection); !e.atEnd(); e.moveNext()) {
|
||||
result.push(e.item().Name);
|
||||
}
|
||||
return result.sort();
|
||||
}
|
||||
|
||||
function getDirectories(path: string): string[] {
|
||||
const folder = fso.GetFolder(path);
|
||||
return getNames(folder.subfolders);
|
||||
}
|
||||
|
||||
function getAccessibleFileSystemEntries(path: string): FileSystemEntries {
|
||||
try {
|
||||
const folder = fso.GetFolder(path || ".");
|
||||
const files = getNames(folder.files);
|
||||
const directories = getNames(folder.subfolders);
|
||||
return { files, directories };
|
||||
}
|
||||
catch (e) {
|
||||
return { files: [], directories: [] };
|
||||
}
|
||||
}
|
||||
|
||||
function readDirectory(path: string, extensions?: string[], excludes?: string[], includes?: string[]): string[] {
|
||||
return matchFiles(path, extensions, excludes, includes, /*useCaseSensitiveFileNames*/ false, shell.CurrentDirectory, getAccessibleFileSystemEntries);
|
||||
}
|
||||
|
||||
const wscriptSystem: System = {
|
||||
args,
|
||||
newLine: "\r\n",
|
||||
useCaseSensitiveFileNames: false,
|
||||
write(s: string): void {
|
||||
WScript.StdOut.Write(s);
|
||||
},
|
||||
readFile,
|
||||
writeFile,
|
||||
resolvePath(path: string): string {
|
||||
return fso.GetAbsolutePathName(path);
|
||||
},
|
||||
fileExists(path: string): boolean {
|
||||
return fso.FileExists(path);
|
||||
},
|
||||
directoryExists(path: string) {
|
||||
return fso.FolderExists(path);
|
||||
},
|
||||
createDirectory(directoryName: string) {
|
||||
if (!wscriptSystem.directoryExists(directoryName)) {
|
||||
fso.CreateFolder(directoryName);
|
||||
}
|
||||
},
|
||||
getExecutingFilePath() {
|
||||
return WScript.ScriptFullName;
|
||||
},
|
||||
getCurrentDirectory() {
|
||||
return shell.CurrentDirectory;
|
||||
},
|
||||
getDirectories,
|
||||
getEnvironmentVariable(name: string) {
|
||||
return new ActiveXObject("WScript.Shell").ExpandEnvironmentStrings(`%${name}%`);
|
||||
},
|
||||
readDirectory,
|
||||
exit(exitCode?: number): void {
|
||||
try {
|
||||
WScript.Quit(exitCode);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
}
|
||||
};
|
||||
return wscriptSystem;
|
||||
}
|
||||
|
||||
function getNodeSystem(): System {
|
||||
const _fs = require("fs");
|
||||
const _path = require("path");
|
||||
@ -315,9 +177,8 @@ namespace ts {
|
||||
}
|
||||
const watchedFileSet = createWatchedFileSet();
|
||||
|
||||
function isNode4OrLater(): boolean {
|
||||
return parseInt(process.version.charAt(1)) >= 4;
|
||||
}
|
||||
const nodeVersion = getNodeMajorVersion();
|
||||
const isNode4OrLater = nodeVersion >= 4;
|
||||
|
||||
function isFileSystemCaseSensitive(): boolean {
|
||||
// win32\win64 are case insensitive platforms
|
||||
@ -341,7 +202,7 @@ namespace ts {
|
||||
if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) {
|
||||
// Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js,
|
||||
// flip all byte pairs and treat as little endian.
|
||||
len &= ~1;
|
||||
len &= ~1; // Round down to a multiple of 2
|
||||
for (let i = 0; i < len; i += 2) {
|
||||
const temp = buffer[i];
|
||||
buffer[i] = buffer[i + 1];
|
||||
@ -371,7 +232,7 @@ namespace ts {
|
||||
|
||||
try {
|
||||
fd = _fs.openSync(fileName, "w");
|
||||
_fs.writeSync(fd, data, undefined, "utf8");
|
||||
_fs.writeSync(fd, data, /*position*/ undefined, "utf8");
|
||||
}
|
||||
finally {
|
||||
if (fd !== undefined) {
|
||||
@ -485,14 +346,12 @@ namespace ts {
|
||||
// Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
|
||||
// (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
|
||||
let options: any;
|
||||
if (!directoryExists(directoryName) || (isUNCPath(directoryName) && process.platform === "win32")) {
|
||||
// do nothing if either
|
||||
// - target folder does not exist
|
||||
// - this is UNC path on Windows (https://github.com/Microsoft/TypeScript/issues/13874)
|
||||
if (!directoryExists(directoryName)) {
|
||||
// do nothing if target folder does not exist
|
||||
return noOpFileWatcher;
|
||||
}
|
||||
|
||||
if (isNode4OrLater() && (process.platform === "win32" || process.platform === "darwin")) {
|
||||
if (isNode4OrLater && (process.platform === "win32" || process.platform === "darwin")) {
|
||||
options = { persistent: true, recursive: !!recursive };
|
||||
}
|
||||
else {
|
||||
@ -509,13 +368,9 @@ namespace ts {
|
||||
if (eventName === "rename") {
|
||||
// When deleting a file, the passed baseFileName is null
|
||||
callback(!relativeFileName ? relativeFileName : normalizePath(combinePaths(directoryName, relativeFileName)));
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function isUNCPath(s: string): boolean {
|
||||
return s.length > 2 && s.charCodeAt(0) === CharacterCodes.slash && s.charCodeAt(1) === CharacterCodes.slash;
|
||||
}
|
||||
},
|
||||
resolvePath: function(path: string): string {
|
||||
return _path.resolve(path);
|
||||
@ -638,9 +493,6 @@ namespace ts {
|
||||
if (typeof ChakraHost !== "undefined") {
|
||||
sys = getChakraSystem();
|
||||
}
|
||||
else if (typeof WScript !== "undefined" && typeof ActiveXObject === "function") {
|
||||
sys = getWScriptSystem();
|
||||
}
|
||||
else if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof require !== "undefined") {
|
||||
// process and process.nextTick checks if current environment is node-like
|
||||
// process.browser check excludes webpack and browserify
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/// <reference path="visitor.ts" />
|
||||
/// <reference path="visitor.ts" />
|
||||
/// <reference path="transformers/ts.ts" />
|
||||
/// <reference path="transformers/jsx.ts" />
|
||||
/// <reference path="transformers/esnext.ts" />
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
function getModuleTransformer(moduleKind: ModuleKind): Transformer {
|
||||
function getModuleTransformer(moduleKind: ModuleKind): TransformerFactory<SourceFile> {
|
||||
switch (moduleKind) {
|
||||
case ModuleKind.ES2015:
|
||||
return transformES2015Module;
|
||||
@ -24,16 +24,25 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const enum TransformationState {
|
||||
Uninitialized,
|
||||
Initialized,
|
||||
Completed,
|
||||
Disposed
|
||||
}
|
||||
|
||||
const enum SyntaxKindFeatureFlags {
|
||||
Substitution = 1 << 0,
|
||||
EmitNotifications = 1 << 1,
|
||||
}
|
||||
|
||||
export function getTransformers(compilerOptions: CompilerOptions) {
|
||||
export function getTransformers(compilerOptions: CompilerOptions, customTransformers?: CustomTransformers) {
|
||||
const jsx = compilerOptions.jsx;
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
const transformers: Transformer[] = [];
|
||||
const transformers: TransformerFactory<SourceFile>[] = [];
|
||||
|
||||
addRange(transformers, customTransformers && customTransformers.before);
|
||||
|
||||
transformers.push(transformTypeScript);
|
||||
|
||||
@ -66,6 +75,8 @@ namespace ts {
|
||||
transformers.push(transformES5);
|
||||
}
|
||||
|
||||
addRange(transformers, customTransformers && customTransformers.after);
|
||||
|
||||
return transformers;
|
||||
}
|
||||
|
||||
@ -73,28 +84,29 @@ namespace ts {
|
||||
* Transforms an array of SourceFiles by passing them through each transformer.
|
||||
*
|
||||
* @param resolver The emit resolver provided by the checker.
|
||||
* @param host The emit host.
|
||||
* @param sourceFiles An array of source files
|
||||
* @param transforms An array of Transformers.
|
||||
* @param host The emit host object used to interact with the file system.
|
||||
* @param options Compiler options to surface in the `TransformationContext`.
|
||||
* @param nodes An array of nodes to transform.
|
||||
* @param transforms An array of `TransformerFactory` callbacks.
|
||||
* @param allowDtsFiles A value indicating whether to allow the transformation of .d.ts files.
|
||||
*/
|
||||
export function transformFiles(resolver: EmitResolver, host: EmitHost, sourceFiles: SourceFile[], transformers: Transformer[]): TransformationResult {
|
||||
export function transformNodes<T extends Node>(resolver: EmitResolver, host: EmitHost, options: CompilerOptions, nodes: T[], transformers: TransformerFactory<T>[], allowDtsFiles: boolean): TransformationResult<T> {
|
||||
const enabledSyntaxKindFeatures = new Array<SyntaxKindFeatureFlags>(SyntaxKind.Count);
|
||||
|
||||
let lexicalEnvironmentDisabled = false;
|
||||
|
||||
let lexicalEnvironmentVariableDeclarations: VariableDeclaration[];
|
||||
let lexicalEnvironmentFunctionDeclarations: FunctionDeclaration[];
|
||||
let lexicalEnvironmentVariableDeclarationsStack: VariableDeclaration[][] = [];
|
||||
let lexicalEnvironmentFunctionDeclarationsStack: FunctionDeclaration[][] = [];
|
||||
let lexicalEnvironmentStackOffset = 0;
|
||||
let lexicalEnvironmentSuspended = false;
|
||||
|
||||
let emitHelpers: EmitHelper[];
|
||||
let onSubstituteNode: TransformationContext["onSubstituteNode"] = (_, node) => node;
|
||||
let onEmitNode: TransformationContext["onEmitNode"] = (hint, node, callback) => callback(hint, node);
|
||||
let state = TransformationState.Uninitialized;
|
||||
|
||||
// The transformation context is provided to each transformer as part of transformer
|
||||
// initialization.
|
||||
const context: TransformationContext = {
|
||||
getCompilerOptions: () => host.getCompilerOptions(),
|
||||
getCompilerOptions: () => options,
|
||||
getEmitResolver: () => resolver,
|
||||
getEmitHost: () => host,
|
||||
startLexicalEnvironment,
|
||||
@ -105,51 +117,62 @@ namespace ts {
|
||||
hoistFunctionDeclaration,
|
||||
requestEmitHelper,
|
||||
readEmitHelpers,
|
||||
onSubstituteNode: (_, node) => node,
|
||||
enableSubstitution,
|
||||
isSubstitutionEnabled,
|
||||
onEmitNode: (hint, node, callback) => callback(hint, node),
|
||||
enableEmitNotification,
|
||||
isEmitNotificationEnabled
|
||||
isSubstitutionEnabled,
|
||||
isEmitNotificationEnabled,
|
||||
get onSubstituteNode() { return onSubstituteNode; },
|
||||
set onSubstituteNode(value) {
|
||||
Debug.assert(state < TransformationState.Initialized, "Cannot modify transformation hooks after initialization has completed.");
|
||||
Debug.assert(value !== undefined, "Value must not be 'undefined'");
|
||||
onSubstituteNode = value;
|
||||
},
|
||||
get onEmitNode() { return onEmitNode; },
|
||||
set onEmitNode(value) {
|
||||
Debug.assert(state < TransformationState.Initialized, "Cannot modify transformation hooks after initialization has completed.");
|
||||
Debug.assert(value !== undefined, "Value must not be 'undefined'");
|
||||
onEmitNode = value;
|
||||
}
|
||||
};
|
||||
|
||||
// Ensure the parse tree is clean before applying transformations
|
||||
for (const node of nodes) {
|
||||
disposeEmitNodes(getSourceFileOfNode(getParseTreeNode(node)));
|
||||
}
|
||||
|
||||
performance.mark("beforeTransform");
|
||||
|
||||
// Chain together and initialize each transformer.
|
||||
const transformation = chain(...transformers)(context);
|
||||
|
||||
// Transform each source file.
|
||||
const transformed = map(sourceFiles, transformSourceFile);
|
||||
// prevent modification of transformation hooks.
|
||||
state = TransformationState.Initialized;
|
||||
|
||||
// Disable modification of the lexical environment.
|
||||
lexicalEnvironmentDisabled = true;
|
||||
// Transform each node.
|
||||
const transformed = map(nodes, allowDtsFiles ? transformation : transformRoot);
|
||||
|
||||
// prevent modification of the lexical environment.
|
||||
state = TransformationState.Completed;
|
||||
|
||||
performance.mark("afterTransform");
|
||||
performance.measure("transformTime", "beforeTransform", "afterTransform");
|
||||
|
||||
return {
|
||||
transformed,
|
||||
emitNodeWithSubstitution,
|
||||
emitNodeWithNotification
|
||||
substituteNode,
|
||||
emitNodeWithNotification,
|
||||
dispose
|
||||
};
|
||||
|
||||
/**
|
||||
* Transforms a source file.
|
||||
*
|
||||
* @param sourceFile The source file to transform.
|
||||
*/
|
||||
function transformSourceFile(sourceFile: SourceFile) {
|
||||
if (isDeclarationFile(sourceFile)) {
|
||||
return sourceFile;
|
||||
}
|
||||
|
||||
return transformation(sourceFile);
|
||||
function transformRoot(node: T) {
|
||||
return node && (!isSourceFile(node) || !isDeclarationFile(node)) ? transformation(node) : node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables expression substitutions in the pretty printer for the provided SyntaxKind.
|
||||
*/
|
||||
function enableSubstitution(kind: SyntaxKind) {
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed.");
|
||||
enabledSyntaxKindFeatures[kind] |= SyntaxKindFeatureFlags.Substitution;
|
||||
}
|
||||
|
||||
@ -168,19 +191,16 @@ namespace ts {
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback The callback used to emit the node or its substitute.
|
||||
*/
|
||||
function emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (node) {
|
||||
if (isSubstitutionEnabled(node)) {
|
||||
node = context.onSubstituteNode(hint, node) || node;
|
||||
}
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
function substituteNode(hint: EmitHint, node: Node) {
|
||||
Debug.assert(state < TransformationState.Disposed, "Cannot substitute a node after the result is disposed.");
|
||||
return node && isSubstitutionEnabled(node) && onSubstituteNode(hint, node) || node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables before/after emit notifications in the pretty printer for the provided SyntaxKind.
|
||||
*/
|
||||
function enableEmitNotification(kind: SyntaxKind) {
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed.");
|
||||
enabledSyntaxKindFeatures[kind] |= SyntaxKindFeatureFlags.EmitNotifications;
|
||||
}
|
||||
|
||||
@ -201,9 +221,10 @@ namespace ts {
|
||||
* @param emitCallback The callback used to emit the node.
|
||||
*/
|
||||
function emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
Debug.assert(state < TransformationState.Disposed, "Cannot invoke TransformationResult callbacks after the result is disposed.");
|
||||
if (node) {
|
||||
if (isEmitNotificationEnabled(node)) {
|
||||
context.onEmitNode(hint, node, emitCallback);
|
||||
onEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
else {
|
||||
emitCallback(hint, node);
|
||||
@ -215,7 +236,8 @@ namespace ts {
|
||||
* Records a hoisted variable declaration for the provided name within a lexical environment.
|
||||
*/
|
||||
function hoistVariableDeclaration(name: Identifier): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed.");
|
||||
const decl = createVariableDeclaration(name);
|
||||
if (!lexicalEnvironmentVariableDeclarations) {
|
||||
lexicalEnvironmentVariableDeclarations = [decl];
|
||||
@ -229,7 +251,8 @@ namespace ts {
|
||||
* Records a hoisted function declaration within a lexical environment.
|
||||
*/
|
||||
function hoistFunctionDeclaration(func: FunctionDeclaration): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed.");
|
||||
if (!lexicalEnvironmentFunctionDeclarations) {
|
||||
lexicalEnvironmentFunctionDeclarations = [func];
|
||||
}
|
||||
@ -243,7 +266,8 @@ namespace ts {
|
||||
* are pushed onto a stack, and the related storage variables are reset.
|
||||
*/
|
||||
function startLexicalEnvironment(): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot start a lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed.");
|
||||
Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
|
||||
|
||||
// Save the current lexical environment. Rather than resizing the array we adjust the
|
||||
@ -259,14 +283,16 @@ namespace ts {
|
||||
|
||||
/** Suspends the current lexical environment, usually after visiting a parameter list. */
|
||||
function suspendLexicalEnvironment(): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot suspend a lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed.");
|
||||
Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is already suspended.");
|
||||
lexicalEnvironmentSuspended = true;
|
||||
}
|
||||
|
||||
/** Resumes a suspended lexical environment, usually before visiting a function body. */
|
||||
function resumeLexicalEnvironment(): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot resume a lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed.");
|
||||
Debug.assert(lexicalEnvironmentSuspended, "Lexical environment is not suspended.");
|
||||
lexicalEnvironmentSuspended = false;
|
||||
}
|
||||
@ -276,7 +302,8 @@ namespace ts {
|
||||
* any hoisted declarations added in this environment are returned.
|
||||
*/
|
||||
function endLexicalEnvironment(): Statement[] {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot end a lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed.");
|
||||
Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
|
||||
|
||||
let statements: Statement[];
|
||||
@ -312,16 +339,39 @@ namespace ts {
|
||||
}
|
||||
|
||||
function requestEmitHelper(helper: EmitHelper): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the transformation context during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed.");
|
||||
Debug.assert(!helper.scoped, "Cannot request a scoped emit helper.");
|
||||
emitHelpers = append(emitHelpers, helper);
|
||||
}
|
||||
|
||||
function readEmitHelpers(): EmitHelper[] | undefined {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the transformation context during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed.");
|
||||
const helpers = emitHelpers;
|
||||
emitHelpers = undefined;
|
||||
return helpers;
|
||||
}
|
||||
|
||||
function dispose() {
|
||||
if (state < TransformationState.Disposed) {
|
||||
// Clean up emit nodes on parse tree
|
||||
for (const node of nodes) {
|
||||
disposeEmitNodes(getSourceFileOfNode(getParseTreeNode(node)));
|
||||
}
|
||||
|
||||
// Release references to external entries for GC purposes.
|
||||
lexicalEnvironmentVariableDeclarations = undefined;
|
||||
lexicalEnvironmentVariableDeclarationsStack = undefined;
|
||||
lexicalEnvironmentFunctionDeclarations = undefined;
|
||||
lexicalEnvironmentFunctionDeclarationsStack = undefined;
|
||||
onSubstituteNode = undefined;
|
||||
onEmitNode = undefined;
|
||||
emitHelpers = undefined;
|
||||
|
||||
// Prevent further use of the transformation result.
|
||||
state = TransformationState.Disposed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ namespace ts {
|
||||
interface FlattenContext {
|
||||
context: TransformationContext;
|
||||
level: FlattenLevel;
|
||||
downlevelIteration: boolean;
|
||||
hoistTempVariables: boolean;
|
||||
emitExpression: (value: Expression) => void;
|
||||
emitBindingOrAssignment: (target: BindingOrAssignmentElementTarget, value: Expression, location: TextRange, original: Node) => void;
|
||||
@ -42,7 +43,7 @@ namespace ts {
|
||||
let value: Expression;
|
||||
if (isDestructuringAssignment(node)) {
|
||||
value = node.right;
|
||||
while (isEmptyObjectLiteralOrArrayLiteral(node.left)) {
|
||||
while (isEmptyArrayLiteral(node.left) || isEmptyObjectLiteral(node.left)) {
|
||||
if (isDestructuringAssignment(value)) {
|
||||
location = node = value;
|
||||
value = node.right;
|
||||
@ -57,6 +58,7 @@ namespace ts {
|
||||
const flattenContext: FlattenContext = {
|
||||
context,
|
||||
level,
|
||||
downlevelIteration: context.getCompilerOptions().downlevelIteration,
|
||||
hoistTempVariables: true,
|
||||
emitExpression,
|
||||
emitBindingOrAssignment,
|
||||
@ -146,6 +148,7 @@ namespace ts {
|
||||
const flattenContext: FlattenContext = {
|
||||
context,
|
||||
level,
|
||||
downlevelIteration: context.getCompilerOptions().downlevelIteration,
|
||||
hoistTempVariables,
|
||||
emitExpression,
|
||||
emitBindingOrAssignment,
|
||||
@ -312,7 +315,23 @@ namespace ts {
|
||||
function flattenArrayBindingOrAssignmentPattern(flattenContext: FlattenContext, parent: BindingOrAssignmentElement, pattern: ArrayBindingOrAssignmentPattern, value: Expression, location: TextRange) {
|
||||
const elements = getElementsOfBindingOrAssignmentPattern(pattern);
|
||||
const numElements = elements.length;
|
||||
if (numElements !== 1 && (flattenContext.level < FlattenLevel.ObjectRest || numElements === 0)) {
|
||||
if (flattenContext.level < FlattenLevel.ObjectRest && flattenContext.downlevelIteration) {
|
||||
// Read the elements of the iterable into an array
|
||||
value = ensureIdentifier(
|
||||
flattenContext,
|
||||
createReadHelper(
|
||||
flattenContext.context,
|
||||
value,
|
||||
numElements > 0 && getRestIndicatorOfBindingOrAssignmentElement(elements[numElements - 1])
|
||||
? undefined
|
||||
: numElements,
|
||||
location
|
||||
),
|
||||
/*reuseIdentifierExpressions*/ false,
|
||||
location
|
||||
);
|
||||
}
|
||||
else if (numElements !== 1 && (flattenContext.level < FlattenLevel.ObjectRest || numElements === 0)) {
|
||||
// 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
|
||||
// we need to emit *something* to ensure that in case a 'var' keyword was already emitted,
|
||||
@ -448,7 +467,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function makeBindingElement(name: Identifier) {
|
||||
return createBindingElement(/*propertyName*/ undefined, /*dotDotDotToken*/ undefined, name);
|
||||
return createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name);
|
||||
}
|
||||
|
||||
function makeAssignmentElement(name: Identifier) {
|
||||
@ -471,7 +490,8 @@ namespace ts {
|
||||
};
|
||||
|
||||
/** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement
|
||||
* `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);`*/
|
||||
* `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);`
|
||||
*/
|
||||
function createRestCall(context: TransformationContext, value: Expression, elements: BindingOrAssignmentElement[], computedTempVariables: Expression[], location: TextRange): Expression {
|
||||
context.requestEmitHelper(restHelper);
|
||||
const propertyNames: Expression[] = [];
|
||||
@ -498,7 +518,7 @@ namespace ts {
|
||||
}
|
||||
return createCall(
|
||||
getHelperName("__rest"),
|
||||
undefined,
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
value,
|
||||
setTextRange(
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../visitor.ts" />
|
||||
/// <reference path="./destructuring.ts" />
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
@ -268,6 +269,7 @@ namespace ts {
|
||||
hoistVariableDeclaration,
|
||||
} = context;
|
||||
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
const resolver = context.getEmitResolver();
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
const previousOnEmitNode = context.onEmitNode;
|
||||
@ -313,7 +315,7 @@ namespace ts {
|
||||
* Sets the `HierarchyFacts` for this node prior to visiting this node's subtree, returning the facts set prior to modification.
|
||||
* @param excludeFacts The existing `HierarchyFacts` to reset before visiting the subtree.
|
||||
* @param includeFacts The new `HierarchyFacts` to set before visiting the subtree.
|
||||
**/
|
||||
*/
|
||||
function enterSubtree(excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts) {
|
||||
const ancestorFacts = hierarchyFacts;
|
||||
hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & HierarchyFacts.AncestorFactsMask;
|
||||
@ -326,7 +328,7 @@ namespace ts {
|
||||
* @param ancestorFacts The `HierarchyFacts` of the ancestor to restore after visiting the subtree.
|
||||
* @param excludeFacts The existing `HierarchyFacts` of the subtree that should not be propagated.
|
||||
* @param includeFacts The new `HierarchyFacts` of the subtree that should be propagated.
|
||||
**/
|
||||
*/
|
||||
function exitSubtree(ancestorFacts: HierarchyFacts, excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts) {
|
||||
hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & HierarchyFacts.SubtreeFactsMask | ancestorFacts;
|
||||
}
|
||||
@ -464,6 +466,12 @@ namespace ts {
|
||||
case SyntaxKind.TemplateTail:
|
||||
return visitTemplateLiteral(<LiteralExpression>node);
|
||||
|
||||
case SyntaxKind.StringLiteral:
|
||||
return visitStringLiteral(<StringLiteral>node);
|
||||
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return visitNumericLiteral(<NumericLiteral>node);
|
||||
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
return visitTaggedTemplateExpression(<TaggedTemplateExpression>node);
|
||||
|
||||
@ -1716,6 +1724,7 @@ namespace ts {
|
||||
return updateFunctionExpression(
|
||||
node,
|
||||
/*modifiers*/ undefined,
|
||||
node.asteriskToken,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
parameters,
|
||||
@ -1747,6 +1756,7 @@ namespace ts {
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
node.asteriskToken,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
parameters,
|
||||
@ -1936,6 +1946,9 @@ namespace ts {
|
||||
function visitParenthesizedExpression(node: ParenthesizedExpression, needsDestructuringValue: boolean): ParenthesizedExpression {
|
||||
// If we are here it is most likely because our expression is a destructuring assignment.
|
||||
if (!needsDestructuringValue) {
|
||||
// By default we always emit the RHS at the end of a flattened destructuring
|
||||
// expression. If we are in a state where we do not need the destructuring value,
|
||||
// we pass that information along to the children that care about it.
|
||||
switch (node.expression.kind) {
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return updateParen(node, visitParenthesizedExpression(<ParenthesizedExpression>node.expression, /*needsDestructuringValue*/ false));
|
||||
@ -1987,7 +2000,8 @@ namespace ts {
|
||||
else {
|
||||
assignment = createBinary(<Identifier>decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression));
|
||||
}
|
||||
(assignments || (assignments = [])).push(assignment);
|
||||
|
||||
assignments = append(assignments, assignment);
|
||||
}
|
||||
}
|
||||
if (assignments) {
|
||||
@ -2169,12 +2183,26 @@ namespace ts {
|
||||
if (convertedLoopState && !convertedLoopState.labels) {
|
||||
convertedLoopState.labels = createMap<string>();
|
||||
}
|
||||
const statement = unwrapInnermostStatmentOfLabel(node, convertedLoopState && recordLabel);
|
||||
return isIterationStatement(statement, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(statement)
|
||||
const statement = unwrapInnermostStatementOfLabel(node, convertedLoopState && recordLabel);
|
||||
return isIterationStatement(statement, /*lookInLabeledStatements*/ false)
|
||||
? visitIterationStatement(statement, /*outermostLabeledStatement*/ node)
|
||||
: restoreEnclosingLabel(visitNode(statement, visitor, isStatement), node, convertedLoopState && resetLabel);
|
||||
}
|
||||
|
||||
function visitIterationStatement(node: IterationStatement, outermostLabeledStatement: LabeledStatement) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.DoStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
return visitDoOrWhileStatement(<DoStatement | WhileStatement>node, outermostLabeledStatement);
|
||||
case SyntaxKind.ForStatement:
|
||||
return visitForStatement(<ForStatement>node, outermostLabeledStatement);
|
||||
case SyntaxKind.ForInStatement:
|
||||
return visitForInStatement(<ForInStatement>node, outermostLabeledStatement);
|
||||
case SyntaxKind.ForOfStatement:
|
||||
return visitForOfStatement(<ForOfStatement>node, outermostLabeledStatement);
|
||||
}
|
||||
}
|
||||
|
||||
function visitIterationStatementWithFacts(excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts, node: IterationStatement, outermostLabeledStatement: LabeledStatement, convert?: LoopConverter) {
|
||||
const ancestorFacts = enterSubtree(excludeFacts, includeFacts);
|
||||
const updated = convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, convert);
|
||||
@ -2212,54 +2240,17 @@ namespace ts {
|
||||
HierarchyFacts.ForInOrForOfStatementIncludes,
|
||||
node,
|
||||
outermostLabeledStatement,
|
||||
convertForOfToFor);
|
||||
compilerOptions.downlevelIteration ? convertForOfStatementForIterable : convertForOfStatementForArray);
|
||||
}
|
||||
|
||||
function convertForOfToFor(node: ForOfStatement, outermostLabeledStatement: LabeledStatement, convertedLoopBodyStatements: Statement[]): Statement {
|
||||
// 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;
|
||||
function convertForOfStatementHead(node: ForOfStatement, boundValue: Expression, convertedLoopBodyStatements: Statement[]) {
|
||||
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(unescapeIdentifier((<Identifier>expression).text))
|
||||
: createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const elementAccess = createElementAccess(rhsReference, counter);
|
||||
|
||||
// Initialize LHS
|
||||
// var v = _a[_i];
|
||||
if (isVariableDeclarationList(initializer)) {
|
||||
if (initializer.flags & NodeFlags.BlockScoped) {
|
||||
if (isVariableDeclarationList(node.initializer)) {
|
||||
if (node.initializer.flags & NodeFlags.BlockScoped) {
|
||||
enableSubstitutionsForBlockScopedBindings();
|
||||
}
|
||||
|
||||
const firstOriginalDeclaration = firstOrUndefined(initializer.declarations);
|
||||
const firstOriginalDeclaration = firstOrUndefined(node.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.
|
||||
@ -2268,12 +2259,11 @@ namespace ts {
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.All,
|
||||
elementAccess
|
||||
boundValue
|
||||
);
|
||||
|
||||
const declarationList = createVariableDeclarationList(declarations);
|
||||
setOriginalNode(declarationList, initializer);
|
||||
setTextRange(declarationList, initializer);
|
||||
const declarationList = setTextRange(createVariableDeclarationList(declarations), node.initializer);
|
||||
setOriginalNode(declarationList, node.initializer);
|
||||
|
||||
// Adjust the source map range for the first declaration to align with the old
|
||||
// emitter.
|
||||
@ -2301,15 +2291,15 @@ namespace ts {
|
||||
createVariableDeclaration(
|
||||
firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined),
|
||||
/*type*/ undefined,
|
||||
createElementAccess(rhsReference, counter)
|
||||
boundValue
|
||||
)
|
||||
]),
|
||||
moveRangePos(initializer, -1)
|
||||
moveRangePos(node.initializer, -1)
|
||||
),
|
||||
initializer
|
||||
node.initializer
|
||||
)
|
||||
),
|
||||
moveRangeEnd(initializer, -1)
|
||||
moveRangeEnd(node.initializer, -1)
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -2317,25 +2307,14 @@ namespace ts {
|
||||
else {
|
||||
// Initializer is an expression. Emit the expression in the body, so that it's
|
||||
// evaluated on every iteration.
|
||||
const assignment = createAssignment(initializer, elementAccess);
|
||||
const assignment = createAssignment(node.initializer, boundValue);
|
||||
if (isDestructuringAssignment(assignment)) {
|
||||
// This is a destructuring pattern, so we flatten the destructuring instead.
|
||||
statements.push(
|
||||
createStatement(
|
||||
flattenDestructuringAssignment(
|
||||
assignment,
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.All
|
||||
)
|
||||
)
|
||||
);
|
||||
aggregateTransformFlags(assignment);
|
||||
statements.push(createStatement(visitBinaryExpression(assignment, /*needsDestructuringValue*/ false)));
|
||||
}
|
||||
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(setTextRange(createStatement(assignment), moveRangeEnd(initializer, -1)));
|
||||
assignment.end = node.initializer.end;
|
||||
statements.push(setTextRange(createStatement(visitNode(assignment, visitor, isExpression)), moveRangeEnd(node.initializer, -1)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2345,7 +2324,7 @@ namespace ts {
|
||||
addRange(statements, convertedLoopBodyStatements);
|
||||
}
|
||||
else {
|
||||
const statement = visitNode(node.statement, visitor, isStatement, /*optional*/ false, liftToBlock);
|
||||
const statement = visitNode(node.statement, visitor, isStatement, liftToBlock);
|
||||
if (isBlock(statement)) {
|
||||
addRange(statements, statement.statements);
|
||||
bodyLocation = statement;
|
||||
@ -2356,38 +2335,82 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
// The old emitter does not emit source maps for the block.
|
||||
// We add the location to preserve comments.
|
||||
return setEmitFlags(
|
||||
setTextRange(
|
||||
createBlock(
|
||||
setTextRange(createNodeArray(statements), statementsLocation),
|
||||
/*multiLine*/ true
|
||||
),
|
||||
bodyLocation,
|
||||
),
|
||||
EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps
|
||||
);
|
||||
}
|
||||
|
||||
function convertForOfStatementForArray(node: ForOfStatement, outermostLabeledStatement: LabeledStatement, convertedLoopBodyStatements: Statement[]): Statement {
|
||||
// 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);
|
||||
|
||||
// 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 = isIdentifier(expression) ? getGeneratedNameForNode(expression) : createTempVariable(/*recordTempVariable*/ undefined);
|
||||
|
||||
// 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(setTextRange(createNodeArray(statements), /*location*/ statementsLocation));
|
||||
setTextRange(body, bodyLocation);
|
||||
setEmitFlags(body, EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps);
|
||||
|
||||
const forStatement = createFor(
|
||||
setEmitFlags(
|
||||
setTextRange(
|
||||
createVariableDeclarationList([
|
||||
setTextRange(createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0)), moveRangePos(node.expression, -1)),
|
||||
setTextRange(createVariableDeclaration(rhsReference, /*type*/ undefined, expression), node.expression)
|
||||
]),
|
||||
const forStatement = setTextRange(
|
||||
createFor(
|
||||
/*initializer*/ setEmitFlags(
|
||||
setTextRange(
|
||||
createVariableDeclarationList([
|
||||
setTextRange(createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0)), moveRangePos(node.expression, -1)),
|
||||
setTextRange(createVariableDeclaration(rhsReference, /*type*/ undefined, expression), node.expression)
|
||||
]),
|
||||
node.expression
|
||||
),
|
||||
EmitFlags.NoHoisting
|
||||
),
|
||||
/*condition*/ setTextRange(
|
||||
createLessThan(
|
||||
counter,
|
||||
createPropertyAccess(rhsReference, "length")
|
||||
),
|
||||
node.expression
|
||||
),
|
||||
EmitFlags.NoHoisting
|
||||
/*incrementor*/ setTextRange(createPostfixIncrement(counter), node.expression),
|
||||
/*statement*/ convertForOfStatementHead(
|
||||
node,
|
||||
createElementAccess(rhsReference, counter),
|
||||
convertedLoopBodyStatements
|
||||
)
|
||||
),
|
||||
setTextRange(
|
||||
createLessThan(
|
||||
counter,
|
||||
createPropertyAccess(rhsReference, "length")
|
||||
),
|
||||
node.expression
|
||||
),
|
||||
setTextRange(
|
||||
createPostfixIncrement(counter),
|
||||
node.expression
|
||||
),
|
||||
body
|
||||
/*location*/ node
|
||||
);
|
||||
|
||||
// Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter.
|
||||
@ -2396,18 +2419,110 @@ namespace ts {
|
||||
return restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel);
|
||||
}
|
||||
|
||||
function visitIterationStatement(node: IterationStatement, outermostLabeledStatement: LabeledStatement) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.DoStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
return visitDoOrWhileStatement(<DoStatement | WhileStatement>node, outermostLabeledStatement);
|
||||
case SyntaxKind.ForStatement:
|
||||
return visitForStatement(<ForStatement>node, outermostLabeledStatement);
|
||||
case SyntaxKind.ForInStatement:
|
||||
return visitForInStatement(<ForInStatement>node, outermostLabeledStatement);
|
||||
case SyntaxKind.ForOfStatement:
|
||||
return visitForOfStatement(<ForOfStatement>node, outermostLabeledStatement);
|
||||
}
|
||||
function convertForOfStatementForIterable(node: ForOfStatement, outermostLabeledStatement: LabeledStatement, convertedLoopBodyStatements: Statement[]): Statement {
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
const iterator = isIdentifier(expression) ? getGeneratedNameForNode(expression) : createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const result = isIdentifier(expression) ? getGeneratedNameForNode(iterator) : createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const errorRecord = createUniqueName("e");
|
||||
const catchVariable = getGeneratedNameForNode(errorRecord);
|
||||
const returnMethod = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const values = createValuesHelper(context, expression, node.expression);
|
||||
const next = createCall(createPropertyAccess(iterator, "next" ), /*typeArguments*/ undefined, []);
|
||||
|
||||
hoistVariableDeclaration(errorRecord);
|
||||
hoistVariableDeclaration(returnMethod);
|
||||
|
||||
const forStatement = setEmitFlags(
|
||||
setTextRange(
|
||||
createFor(
|
||||
/*initializer*/ setEmitFlags(
|
||||
setTextRange(
|
||||
createVariableDeclarationList([
|
||||
setTextRange(createVariableDeclaration(iterator, /*type*/ undefined, values), node.expression),
|
||||
createVariableDeclaration(result, /*type*/ undefined, next)
|
||||
]),
|
||||
node.expression
|
||||
),
|
||||
EmitFlags.NoHoisting
|
||||
),
|
||||
/*condition*/ createLogicalNot(createPropertyAccess(result, "done")),
|
||||
/*incrementor*/ createAssignment(result, next),
|
||||
/*statement*/ convertForOfStatementHead(
|
||||
node,
|
||||
createPropertyAccess(result, "value"),
|
||||
convertedLoopBodyStatements
|
||||
)
|
||||
),
|
||||
/*location*/ node
|
||||
),
|
||||
EmitFlags.NoTokenTrailingSourceMaps
|
||||
);
|
||||
|
||||
return createTry(
|
||||
createBlock([
|
||||
restoreEnclosingLabel(
|
||||
forStatement,
|
||||
outermostLabeledStatement,
|
||||
convertedLoopState && resetLabel
|
||||
)
|
||||
]),
|
||||
createCatchClause(createVariableDeclaration(catchVariable),
|
||||
setEmitFlags(
|
||||
createBlock([
|
||||
createStatement(
|
||||
createAssignment(
|
||||
errorRecord,
|
||||
createObjectLiteral([
|
||||
createPropertyAssignment("error", catchVariable)
|
||||
])
|
||||
)
|
||||
)
|
||||
]),
|
||||
EmitFlags.SingleLine
|
||||
)
|
||||
),
|
||||
createBlock([
|
||||
createTry(
|
||||
/*tryBlock*/ createBlock([
|
||||
setEmitFlags(
|
||||
createIf(
|
||||
createLogicalAnd(
|
||||
createLogicalAnd(
|
||||
result,
|
||||
createLogicalNot(
|
||||
createPropertyAccess(result, "done")
|
||||
)
|
||||
),
|
||||
createAssignment(
|
||||
returnMethod,
|
||||
createPropertyAccess(iterator, "return")
|
||||
)
|
||||
),
|
||||
createStatement(
|
||||
createFunctionCall(returnMethod, iterator, [])
|
||||
)
|
||||
),
|
||||
EmitFlags.SingleLine
|
||||
),
|
||||
]),
|
||||
/*catchClause*/ undefined,
|
||||
/*finallyBlock*/ setEmitFlags(
|
||||
createBlock([
|
||||
setEmitFlags(
|
||||
createIf(
|
||||
errorRecord,
|
||||
createThrow(
|
||||
createPropertyAccess(errorRecord, "error")
|
||||
)
|
||||
),
|
||||
EmitFlags.SingleLine
|
||||
)
|
||||
]),
|
||||
EmitFlags.SingleLine
|
||||
)
|
||||
)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2567,7 +2682,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
startLexicalEnvironment();
|
||||
let loopBody = visitNode(node.statement, visitor, isStatement, /*optional*/ false, liftToBlock);
|
||||
let loopBody = visitNode(node.statement, visitor, isStatement, liftToBlock);
|
||||
const lexicalEnvironment = endLexicalEnvironment();
|
||||
|
||||
const currentState = convertedLoopState;
|
||||
@ -2578,7 +2693,7 @@ namespace ts {
|
||||
if (loopOutParameters.length) {
|
||||
copyOutParameters(loopOutParameters, CopyDirection.ToOutParameter, statements);
|
||||
}
|
||||
addRange(statements, lexicalEnvironment)
|
||||
addRange(statements, lexicalEnvironment);
|
||||
loopBody = createBlock(statements, /*multiline*/ true);
|
||||
}
|
||||
|
||||
@ -2709,6 +2824,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const convertedLoopBodyStatements = generateCallToConvertedLoop(functionName, loopParameters, currentState, isAsyncBlockContainingAwait);
|
||||
|
||||
let loop: Statement;
|
||||
if (convert) {
|
||||
loop = convert(node, outermostLabeledStatement, convertedLoopBodyStatements);
|
||||
@ -2990,7 +3106,7 @@ namespace ts {
|
||||
const ancestorFacts = enterSubtree(HierarchyFacts.BlockScopeExcludes, HierarchyFacts.BlockScopeIncludes);
|
||||
let updated: CatchClause;
|
||||
if (isBindingPattern(node.variableDeclaration.name)) {
|
||||
const temp = createTempVariable(undefined);
|
||||
const temp = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const newVariableDeclaration = createVariableDeclaration(temp);
|
||||
setTextRange(newVariableDeclaration, node.variableDeclaration);
|
||||
const vars = flattenDestructuringBinding(
|
||||
@ -3236,15 +3352,30 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
|
||||
if (segments.length === 1) {
|
||||
const firstElement = elements[0];
|
||||
return needsUniqueCopy && isSpreadExpression(firstElement) && firstElement.expression.kind !== SyntaxKind.ArrayLiteralExpression
|
||||
? createArraySlice(segments[0])
|
||||
: segments[0];
|
||||
}
|
||||
if (compilerOptions.downlevelIteration) {
|
||||
if (segments.length === 1) {
|
||||
const firstSegment = segments[0];
|
||||
if (isCallExpression(firstSegment)
|
||||
&& isIdentifier(firstSegment.expression)
|
||||
&& (getEmitFlags(firstSegment.expression) & EmitFlags.HelperName)
|
||||
&& firstSegment.expression.text === "___spread") {
|
||||
return segments[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Rewrite using the pattern <segment0>.concat(<segment1>, <segment2>, ...)
|
||||
return createArrayConcat(segments.shift(), segments);
|
||||
return createSpreadHelper(context, segments);
|
||||
}
|
||||
else {
|
||||
if (segments.length === 1) {
|
||||
const firstElement = elements[0];
|
||||
return needsUniqueCopy && isSpreadExpression(firstElement) && firstElement.expression.kind !== SyntaxKind.ArrayLiteralExpression
|
||||
? createArraySlice(segments[0])
|
||||
: segments[0];
|
||||
}
|
||||
|
||||
// Rewrite using the pattern <segment0>.concat(<segment1>, <segment2>, ...)
|
||||
return createArrayConcat(segments.shift(), segments);
|
||||
}
|
||||
}
|
||||
|
||||
function partitionSpread(node: Expression) {
|
||||
@ -3286,6 +3417,30 @@ namespace ts {
|
||||
return setTextRange(createLiteral(node.text), node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a string literal with an extended unicode escape.
|
||||
*
|
||||
* @param node A string literal.
|
||||
*/
|
||||
function visitStringLiteral(node: StringLiteral) {
|
||||
if (node.hasExtendedUnicodeEscape) {
|
||||
return setTextRange(createLiteral(node.text), node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a binary or octal (ES6) numeric literal.
|
||||
*
|
||||
* @param node A string literal.
|
||||
*/
|
||||
function visitNumericLiteral(node: NumericLiteral) {
|
||||
if (node.numericLiteralFlags & NumericLiteralFlags.BinaryOrOctalSpecifier) {
|
||||
return setTextRange(createNumericLiteral(node.text), node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a TaggedTemplateExpression node.
|
||||
*
|
||||
@ -3546,7 +3701,7 @@ namespace ts {
|
||||
if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) {
|
||||
const original = getParseTreeNode(node, isIdentifier);
|
||||
if (original && isNameOfDeclarationWithCollidingName(original)) {
|
||||
return getGeneratedNameForNode(original);
|
||||
return setTextRange(getGeneratedNameForNode(original), node);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3599,7 +3754,7 @@ namespace ts {
|
||||
if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) {
|
||||
const declaration = resolver.getReferencedDeclarationWithCollidingName(node);
|
||||
if (declaration) {
|
||||
return getGeneratedNameForNode(declaration.name);
|
||||
return setTextRange(getGeneratedNameForNode(declaration.name), node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ namespace ts {
|
||||
const {
|
||||
startLexicalEnvironment,
|
||||
resumeLexicalEnvironment,
|
||||
endLexicalEnvironment,
|
||||
endLexicalEnvironment
|
||||
} = context;
|
||||
|
||||
const resolver = context.getEmitResolver();
|
||||
@ -34,7 +34,7 @@ namespace ts {
|
||||
* This keeps track of containers where `super` is valid, for use with
|
||||
* just-in-time substitution for `super` expressions inside of async methods.
|
||||
*/
|
||||
let currentSuperContainer: SuperContainer;
|
||||
let enclosingSuperContainerFlags: NodeCheckFlags = 0;
|
||||
|
||||
// Save the previous transformation hooks.
|
||||
const previousOnEmitNode = context.onEmitNode;
|
||||
@ -71,23 +71,18 @@ namespace ts {
|
||||
return undefined;
|
||||
|
||||
case SyntaxKind.AwaitExpression:
|
||||
// ES2017 'await' expressions must be transformed for targets < ES2017.
|
||||
return visitAwaitExpression(<AwaitExpression>node);
|
||||
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
// ES2017 method declarations may be 'async'
|
||||
return visitMethodDeclaration(<MethodDeclaration>node);
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
// ES2017 function declarations may be 'async'
|
||||
return visitFunctionDeclaration(<FunctionDeclaration>node);
|
||||
|
||||
case SyntaxKind.FunctionExpression:
|
||||
// ES2017 function expressions may be 'async'
|
||||
return visitFunctionExpression(<FunctionExpression>node);
|
||||
|
||||
case SyntaxKind.ArrowFunction:
|
||||
// ES2017 arrow functions may be 'async'
|
||||
return visitArrowFunction(<ArrowFunction>node);
|
||||
|
||||
default:
|
||||
@ -128,11 +123,13 @@ namespace ts {
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*questionToken*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
isAsyncFunctionLike(node)
|
||||
getFunctionFlags(node) & FunctionFlags.Async
|
||||
? transformAsyncFunctionBody(node)
|
||||
: visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
@ -151,11 +148,12 @@ namespace ts {
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
isAsyncFunctionLike(node)
|
||||
getFunctionFlags(node) & FunctionFlags.Async
|
||||
? transformAsyncFunctionBody(node)
|
||||
: visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
@ -170,17 +168,15 @@ namespace ts {
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitFunctionExpression(node: FunctionExpression): Expression {
|
||||
if (nodeIsMissing(node.body)) {
|
||||
return createOmittedExpression();
|
||||
}
|
||||
return updateFunctionExpression(
|
||||
node,
|
||||
/*modifiers*/ undefined,
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
isAsyncFunctionLike(node)
|
||||
getFunctionFlags(node) & FunctionFlags.Async
|
||||
? transformAsyncFunctionBody(node)
|
||||
: visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
@ -201,7 +197,7 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
isAsyncFunctionLike(node)
|
||||
getFunctionFlags(node) & FunctionFlags.Async
|
||||
? transformAsyncFunctionBody(node)
|
||||
: visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
@ -320,6 +316,44 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for node emit.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emit A callback used to emit the node in the printer.
|
||||
*/
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
// If we need to support substitutions for `super` in an async method,
|
||||
// we should track it here.
|
||||
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
|
||||
const superContainerFlags = resolver.getNodeCheckFlags(node) & (NodeCheckFlags.AsyncMethodWithSuper | NodeCheckFlags.AsyncMethodWithSuperBinding);
|
||||
if (superContainerFlags !== enclosingSuperContainerFlags) {
|
||||
const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
|
||||
enclosingSuperContainerFlags = superContainerFlags;
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (hint === EmitHint.Expression && enclosingSuperContainerFlags) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteExpression(node: Expression) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
@ -327,62 +361,45 @@ namespace ts {
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
return substituteElementAccessExpression(<ElementAccessExpression>node);
|
||||
case SyntaxKind.CallExpression:
|
||||
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper) {
|
||||
return substituteCallExpression(<CallExpression>node);
|
||||
}
|
||||
break;
|
||||
return substituteCallExpression(<CallExpression>node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
|
||||
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
const flags = getSuperContainerAsyncMethodFlags();
|
||||
if (flags) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
createLiteral(node.name.text),
|
||||
flags,
|
||||
node
|
||||
);
|
||||
}
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
createLiteral(node.name.text),
|
||||
node
|
||||
);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteElementAccessExpression(node: ElementAccessExpression) {
|
||||
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
const flags = getSuperContainerAsyncMethodFlags();
|
||||
if (flags) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
node.argumentExpression,
|
||||
flags,
|
||||
node
|
||||
);
|
||||
}
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
node.argumentExpression,
|
||||
node
|
||||
);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteCallExpression(node: CallExpression): Expression {
|
||||
const expression = node.expression;
|
||||
if (isSuperProperty(expression)) {
|
||||
const flags = getSuperContainerAsyncMethodFlags();
|
||||
if (flags) {
|
||||
const argumentExpression = isPropertyAccessExpression(expression)
|
||||
? substitutePropertyAccessExpression(expression)
|
||||
: substituteElementAccessExpression(expression);
|
||||
return createCall(
|
||||
createPropertyAccess(argumentExpression, "call"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createThis(),
|
||||
...node.arguments
|
||||
]
|
||||
);
|
||||
}
|
||||
const argumentExpression = isPropertyAccessExpression(expression)
|
||||
? substitutePropertyAccessExpression(expression)
|
||||
: substituteElementAccessExpression(expression);
|
||||
return createCall(
|
||||
createPropertyAccess(argumentExpression, "call"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createThis(),
|
||||
...node.arguments
|
||||
]
|
||||
);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@ -396,44 +413,8 @@ namespace ts {
|
||||
|| kind === SyntaxKind.SetAccessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for node emit.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emit A callback used to emit the node in the printer.
|
||||
*/
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
// If we need to support substitutions for `super` in an async method,
|
||||
// we should track it here.
|
||||
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
|
||||
const savedCurrentSuperContainer = currentSuperContainer;
|
||||
currentSuperContainer = node;
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
currentSuperContainer = savedCurrentSuperContainer;
|
||||
}
|
||||
else {
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (hint === EmitHint.Expression) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function createSuperAccessInAsyncMethod(argumentExpression: Expression, flags: NodeCheckFlags, location: TextRange): LeftHandSideExpression {
|
||||
if (flags & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
function createSuperAccessInAsyncMethod(argumentExpression: Expression, location: TextRange): LeftHandSideExpression {
|
||||
if (enclosingSuperContainerFlags & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
createCall(
|
||||
@ -457,15 +438,26 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getSuperContainerAsyncMethodFlags() {
|
||||
return currentSuperContainer !== undefined
|
||||
&& resolver.getNodeCheckFlags(currentSuperContainer) & (NodeCheckFlags.AsyncMethodWithSuper | NodeCheckFlags.AsyncMethodWithSuperBinding);
|
||||
}
|
||||
}
|
||||
|
||||
const awaiterHelper: EmitHelper = {
|
||||
name: "typescript:awaiter",
|
||||
scoped: false,
|
||||
priority: 5,
|
||||
text: `
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};`
|
||||
};
|
||||
|
||||
function createAwaiterHelper(context: TransformationContext, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) {
|
||||
context.requestEmitHelper(awaiterHelper);
|
||||
|
||||
const generatorFunc = createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
createToken(SyntaxKind.AsteriskToken),
|
||||
@ -491,35 +483,22 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
const awaiterHelper: EmitHelper = {
|
||||
name: "typescript:awaiter",
|
||||
scoped: false,
|
||||
priority: 5,
|
||||
text: `
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};`
|
||||
};
|
||||
|
||||
const asyncSuperHelper: EmitHelper = {
|
||||
export const asyncSuperHelper: EmitHelper = {
|
||||
name: "typescript:async-super",
|
||||
scoped: true,
|
||||
text: `
|
||||
const _super = name => super[name];`
|
||||
const _super = name => super[name];
|
||||
`
|
||||
};
|
||||
|
||||
const advancedAsyncSuperHelper: EmitHelper = {
|
||||
export const advancedAsyncSuperHelper: EmitHelper = {
|
||||
name: "typescript:advanced-async-super",
|
||||
scoped: true,
|
||||
text: `
|
||||
const _super = (function (geti, seti) {
|
||||
const cache = Object.create(null);
|
||||
return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });
|
||||
})(name => super[name], (name, value) => super[name] = value);`
|
||||
})(name => super[name], (name, value) => super[name] = value);
|
||||
`
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,13 +1,35 @@
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../visitor.ts" />
|
||||
/// <reference path="es2017.ts" />
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
const enum ESNextSubstitutionFlags {
|
||||
/** Enables substitutions for async methods with `super` calls. */
|
||||
AsyncMethodsWithSuper = 1 << 0
|
||||
}
|
||||
|
||||
export function transformESNext(context: TransformationContext) {
|
||||
const {
|
||||
resumeLexicalEnvironment,
|
||||
endLexicalEnvironment
|
||||
endLexicalEnvironment,
|
||||
hoistVariableDeclaration
|
||||
} = context;
|
||||
|
||||
const resolver = context.getEmitResolver();
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
|
||||
const previousOnEmitNode = context.onEmitNode;
|
||||
context.onEmitNode = onEmitNode;
|
||||
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
context.onSubstituteNode = onSubstituteNode;
|
||||
|
||||
let enabledSubstitutions: ESNextSubstitutionFlags;
|
||||
let enclosingFunctionFlags: FunctionFlags;
|
||||
let enclosingSuperContainerFlags: NodeCheckFlags = 0;
|
||||
|
||||
return transformSourceFile;
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
@ -28,12 +50,25 @@ namespace ts {
|
||||
return visitorWorker(node, /*noDestructuringValue*/ true);
|
||||
}
|
||||
|
||||
function visitorNoAsyncModifier(node: Node): VisitResult<Node> {
|
||||
if (node.kind === SyntaxKind.AsyncKeyword) {
|
||||
return undefined;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function visitorWorker(node: Node, noDestructuringValue: boolean): VisitResult<Node> {
|
||||
if ((node.transformFlags & TransformFlags.ContainsESNext) === 0) {
|
||||
return node;
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.AwaitExpression:
|
||||
return visitAwaitExpression(node as AwaitExpression);
|
||||
case SyntaxKind.YieldExpression:
|
||||
return visitYieldExpression(node as YieldExpression);
|
||||
case SyntaxKind.LabeledStatement:
|
||||
return visitLabeledStatement(node as LabeledStatement);
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return visitObjectLiteralExpression(node as ObjectLiteralExpression);
|
||||
case SyntaxKind.BinaryExpression:
|
||||
@ -41,7 +76,7 @@ namespace ts {
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return visitVariableDeclaration(node as VariableDeclaration);
|
||||
case SyntaxKind.ForOfStatement:
|
||||
return visitForOfStatement(node as ForOfStatement);
|
||||
return visitForOfStatement(node as ForOfStatement, /*outermostLabeledStatement*/ undefined);
|
||||
case SyntaxKind.ForStatement:
|
||||
return visitForStatement(node as ForStatement);
|
||||
case SyntaxKind.VoidExpression:
|
||||
@ -71,6 +106,52 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function visitAwaitExpression(node: AwaitExpression) {
|
||||
if (enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator) {
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
return setOriginalNode(
|
||||
setTextRange(
|
||||
createYield(
|
||||
/*asteriskToken*/ undefined,
|
||||
createArrayLiteral([createLiteral("await"), expression])
|
||||
),
|
||||
/*location*/ node
|
||||
),
|
||||
node
|
||||
);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitYieldExpression(node: YieldExpression) {
|
||||
if (enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator) {
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
return updateYield(
|
||||
node,
|
||||
node.asteriskToken,
|
||||
node.asteriskToken
|
||||
? createAsyncDelegatorHelper(context, expression, expression)
|
||||
: createArrayLiteral(
|
||||
expression
|
||||
? [createLiteral("yield"), expression]
|
||||
: [createLiteral("yield")]
|
||||
)
|
||||
);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitLabeledStatement(node: LabeledStatement) {
|
||||
if (enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator) {
|
||||
const statement = unwrapInnermostStatementOfLabel(node);
|
||||
if (statement.kind === SyntaxKind.ForOfStatement && (<ForOfStatement>statement).awaitModifier) {
|
||||
return visitForOfStatement(<ForOfStatement>statement, node);
|
||||
}
|
||||
return restoreEnclosingLabel(visitEachChild(node, visitor, context), node);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function chunkObjectLiteralElements(elements: ObjectLiteralElement[]): Expression[] {
|
||||
let chunkObject: (ShorthandPropertyAssignment | PropertyAssignment)[];
|
||||
const objects: Expression[] = [];
|
||||
@ -189,67 +270,199 @@ namespace ts {
|
||||
*
|
||||
* @param node A ForOfStatement.
|
||||
*/
|
||||
function visitForOfStatement(node: ForOfStatement): VisitResult<Statement> {
|
||||
let leadingStatements: Statement[];
|
||||
let temp: Identifier;
|
||||
const initializer = skipParentheses(node.initializer);
|
||||
if (initializer.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (isVariableDeclarationList(initializer)) {
|
||||
temp = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const firstDeclaration = firstOrUndefined(initializer.declarations);
|
||||
const declarations = flattenDestructuringBinding(
|
||||
firstDeclaration,
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.ObjectRest,
|
||||
temp,
|
||||
/*doNotRecordTempVariablesInLine*/ false,
|
||||
/*skipInitializer*/ true,
|
||||
);
|
||||
if (some(declarations)) {
|
||||
const statement = createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
updateVariableDeclarationList(initializer, declarations),
|
||||
);
|
||||
setTextRange(statement, initializer);
|
||||
leadingStatements = append(leadingStatements, statement);
|
||||
}
|
||||
}
|
||||
else if (isAssignmentPattern(initializer)) {
|
||||
temp = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const expression = flattenDestructuringAssignment(
|
||||
aggregateTransformFlags(
|
||||
setTextRange(
|
||||
createAssignment(initializer, temp),
|
||||
node.initializer
|
||||
)
|
||||
),
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.ObjectRest
|
||||
);
|
||||
leadingStatements = append(leadingStatements, setTextRange(createStatement(expression), node.initializer));
|
||||
}
|
||||
function visitForOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement): VisitResult<Statement> {
|
||||
if (node.initializer.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
node = transformForOfStatementWithObjectRest(node);
|
||||
}
|
||||
if (temp) {
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
const statement = visitNode(node.statement, visitor, isStatement);
|
||||
const block = isBlock(statement)
|
||||
? updateBlock(statement, setTextRange(createNodeArray(concatenate(leadingStatements, statement.statements)), statement.statements))
|
||||
: setTextRange(createBlock(append(leadingStatements, statement), /*multiLine*/ true), statement);
|
||||
if (node.awaitModifier) {
|
||||
return transformForAwaitOfStatement(node, outermostLabeledStatement);
|
||||
}
|
||||
else {
|
||||
return restoreEnclosingLabel(visitEachChild(node, visitor, context), outermostLabeledStatement);
|
||||
}
|
||||
}
|
||||
|
||||
function transformForOfStatementWithObjectRest(node: ForOfStatement) {
|
||||
const initializerWithoutParens = skipParentheses(node.initializer) as ForInitializer;
|
||||
if (isVariableDeclarationList(initializerWithoutParens) || isAssignmentPattern(initializerWithoutParens)) {
|
||||
let bodyLocation: TextRange;
|
||||
let statementsLocation: TextRange;
|
||||
const temp = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const statements: Statement[] = [createForOfBindingStatement(initializerWithoutParens, temp)];
|
||||
if (isBlock(node.statement)) {
|
||||
addRange(statements, node.statement.statements);
|
||||
bodyLocation = node.statement;
|
||||
statementsLocation = node.statement.statements;
|
||||
}
|
||||
return updateForOf(
|
||||
node,
|
||||
node.awaitModifier,
|
||||
setTextRange(
|
||||
createVariableDeclarationList([
|
||||
setTextRange(createVariableDeclaration(temp), node.initializer)
|
||||
], NodeFlags.Let),
|
||||
createVariableDeclarationList(
|
||||
[
|
||||
setTextRange(createVariableDeclaration(temp), node.initializer)
|
||||
],
|
||||
NodeFlags.Let
|
||||
),
|
||||
node.initializer
|
||||
),
|
||||
expression,
|
||||
block
|
||||
node.expression,
|
||||
setTextRange(
|
||||
createBlock(
|
||||
setTextRange(createNodeArray(statements), statementsLocation),
|
||||
/*multiLine*/ true
|
||||
),
|
||||
bodyLocation
|
||||
)
|
||||
);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
return node;
|
||||
}
|
||||
|
||||
function convertForOfStatementHead(node: ForOfStatement, boundValue: Expression) {
|
||||
const binding = createForOfBindingStatement(node.initializer, boundValue);
|
||||
|
||||
let bodyLocation: TextRange;
|
||||
let statementsLocation: TextRange;
|
||||
const statements: Statement[] = [visitNode(binding, visitor, isStatement)];
|
||||
const statement = visitNode(node.statement, visitor, isStatement);
|
||||
if (isBlock(statement)) {
|
||||
addRange(statements, statement.statements);
|
||||
bodyLocation = statement;
|
||||
statementsLocation = statement.statements;
|
||||
}
|
||||
else {
|
||||
statements.push(statement);
|
||||
}
|
||||
|
||||
return setEmitFlags(
|
||||
setTextRange(
|
||||
createBlock(
|
||||
setTextRange(createNodeArray(statements), statementsLocation),
|
||||
/*multiLine*/ true
|
||||
),
|
||||
bodyLocation
|
||||
),
|
||||
EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps
|
||||
);
|
||||
}
|
||||
|
||||
function transformForAwaitOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement) {
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
const iterator = isIdentifier(expression) ? getGeneratedNameForNode(expression) : createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const result = isIdentifier(expression) ? getGeneratedNameForNode(iterator) : createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const errorRecord = createUniqueName("e");
|
||||
const catchVariable = getGeneratedNameForNode(errorRecord);
|
||||
const returnMethod = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const values = createAsyncValuesHelper(context, expression, /*location*/ node.expression);
|
||||
const next = createYield(
|
||||
/*asteriskToken*/ undefined,
|
||||
enclosingFunctionFlags & FunctionFlags.Generator
|
||||
? createArrayLiteral([
|
||||
createLiteral("await"),
|
||||
createCall(createPropertyAccess(iterator, "next" ), /*typeArguments*/ undefined, [])
|
||||
])
|
||||
: createCall(createPropertyAccess(iterator, "next" ), /*typeArguments*/ undefined, [])
|
||||
);
|
||||
|
||||
hoistVariableDeclaration(errorRecord);
|
||||
hoistVariableDeclaration(returnMethod);
|
||||
|
||||
const forStatement = setEmitFlags(
|
||||
setTextRange(
|
||||
createFor(
|
||||
/*initializer*/ setEmitFlags(
|
||||
setTextRange(
|
||||
createVariableDeclarationList([
|
||||
setTextRange(createVariableDeclaration(iterator, /*type*/ undefined, values), node.expression),
|
||||
createVariableDeclaration(result, /*type*/ undefined, next)
|
||||
]),
|
||||
node.expression
|
||||
),
|
||||
EmitFlags.NoHoisting
|
||||
),
|
||||
/*condition*/ createLogicalNot(createPropertyAccess(result, "done")),
|
||||
/*incrementor*/ createAssignment(result, next),
|
||||
/*statement*/ convertForOfStatementHead(node, createPropertyAccess(result, "value"))
|
||||
),
|
||||
/*location*/ node
|
||||
),
|
||||
EmitFlags.NoTokenTrailingSourceMaps
|
||||
);
|
||||
|
||||
return createTry(
|
||||
createBlock([
|
||||
restoreEnclosingLabel(
|
||||
forStatement,
|
||||
outermostLabeledStatement
|
||||
)
|
||||
]),
|
||||
createCatchClause(
|
||||
createVariableDeclaration(catchVariable),
|
||||
setEmitFlags(
|
||||
createBlock([
|
||||
createStatement(
|
||||
createAssignment(
|
||||
errorRecord,
|
||||
createObjectLiteral([
|
||||
createPropertyAssignment("error", catchVariable)
|
||||
])
|
||||
)
|
||||
)
|
||||
]),
|
||||
EmitFlags.SingleLine
|
||||
)
|
||||
),
|
||||
createBlock([
|
||||
createTry(
|
||||
/*tryBlock*/ createBlock([
|
||||
setEmitFlags(
|
||||
createIf(
|
||||
createLogicalAnd(
|
||||
createLogicalAnd(
|
||||
result,
|
||||
createLogicalNot(
|
||||
createPropertyAccess(result, "done")
|
||||
)
|
||||
),
|
||||
createAssignment(
|
||||
returnMethod,
|
||||
createPropertyAccess(iterator, "return")
|
||||
)
|
||||
),
|
||||
createStatement(
|
||||
createYield(
|
||||
/*asteriskToken*/ undefined,
|
||||
enclosingFunctionFlags & FunctionFlags.Generator
|
||||
? createArrayLiteral([
|
||||
createLiteral("await"),
|
||||
createFunctionCall(returnMethod, iterator, [])
|
||||
])
|
||||
: createFunctionCall(returnMethod, iterator, [])
|
||||
)
|
||||
)
|
||||
),
|
||||
EmitFlags.SingleLine
|
||||
)
|
||||
]),
|
||||
/*catchClause*/ undefined,
|
||||
/*finallyBlock*/ setEmitFlags(
|
||||
createBlock([
|
||||
setEmitFlags(
|
||||
createIf(
|
||||
errorRecord,
|
||||
createThrow(
|
||||
createPropertyAccess(errorRecord, "error")
|
||||
)
|
||||
),
|
||||
EmitFlags.SingleLine
|
||||
)
|
||||
]),
|
||||
EmitFlags.SingleLine
|
||||
)
|
||||
)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
function visitParameter(node: ParameterDeclaration): ParameterDeclaration {
|
||||
@ -262,6 +475,7 @@ namespace ts {
|
||||
/*modifiers*/ undefined,
|
||||
node.dotDotDotToken,
|
||||
getGeneratedNameForNode(node),
|
||||
/*questionToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
visitNode(node.initializer, visitor, isExpression)
|
||||
);
|
||||
@ -270,17 +484,23 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitConstructorDeclaration(node: ConstructorDeclaration) {
|
||||
return updateConstructor(
|
||||
const savedEnclosingFunctionFlags = enclosingFunctionFlags;
|
||||
enclosingFunctionFlags = FunctionFlags.Normal;
|
||||
const updated = updateConstructor(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
transformFunctionBody(node)
|
||||
);
|
||||
enclosingFunctionFlags = savedEnclosingFunctionFlags;
|
||||
return updated;
|
||||
}
|
||||
|
||||
function visitGetAccessorDeclaration(node: GetAccessorDeclaration) {
|
||||
return updateGetAccessor(
|
||||
const savedEnclosingFunctionFlags = enclosingFunctionFlags;
|
||||
enclosingFunctionFlags = FunctionFlags.Normal;
|
||||
const updated = updateGetAccessor(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
@ -289,10 +509,14 @@ namespace ts {
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
);
|
||||
enclosingFunctionFlags = savedEnclosingFunctionFlags;
|
||||
return updated;
|
||||
}
|
||||
|
||||
function visitSetAccessorDeclaration(node: SetAccessorDeclaration) {
|
||||
return updateSetAccessor(
|
||||
const savedEnclosingFunctionFlags = enclosingFunctionFlags;
|
||||
enclosingFunctionFlags = FunctionFlags.Normal;
|
||||
const updated = updateSetAccessor(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
@ -300,36 +524,63 @@ namespace ts {
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
transformFunctionBody(node)
|
||||
);
|
||||
enclosingFunctionFlags = savedEnclosingFunctionFlags;
|
||||
return updated;
|
||||
}
|
||||
|
||||
function visitMethodDeclaration(node: MethodDeclaration) {
|
||||
return updateMethod(
|
||||
const savedEnclosingFunctionFlags = enclosingFunctionFlags;
|
||||
enclosingFunctionFlags = getFunctionFlags(node);
|
||||
const updated = updateMethod(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
enclosingFunctionFlags & FunctionFlags.Generator
|
||||
? visitNodes(node.modifiers, visitorNoAsyncModifier, isModifier)
|
||||
: node.modifiers,
|
||||
enclosingFunctionFlags & FunctionFlags.Async
|
||||
? undefined
|
||||
: node.asteriskToken,
|
||||
visitNode(node.name, visitor, isPropertyName),
|
||||
visitNode(/*questionToken*/ undefined, visitor, isToken),
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator
|
||||
? transformAsyncGeneratorFunctionBody(node)
|
||||
: transformFunctionBody(node)
|
||||
);
|
||||
enclosingFunctionFlags = savedEnclosingFunctionFlags;
|
||||
return updated;
|
||||
}
|
||||
|
||||
function visitFunctionDeclaration(node: FunctionDeclaration) {
|
||||
return updateFunctionDeclaration(
|
||||
const savedEnclosingFunctionFlags = enclosingFunctionFlags;
|
||||
enclosingFunctionFlags = getFunctionFlags(node);
|
||||
const updated = updateFunctionDeclaration(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
enclosingFunctionFlags & FunctionFlags.Generator
|
||||
? visitNodes(node.modifiers, visitorNoAsyncModifier, isModifier)
|
||||
: node.modifiers,
|
||||
enclosingFunctionFlags & FunctionFlags.Async
|
||||
? undefined
|
||||
: node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator
|
||||
? transformAsyncGeneratorFunctionBody(node)
|
||||
: transformFunctionBody(node)
|
||||
);
|
||||
enclosingFunctionFlags = savedEnclosingFunctionFlags;
|
||||
return updated;
|
||||
}
|
||||
|
||||
function visitArrowFunction(node: ArrowFunction) {
|
||||
return updateArrowFunction(
|
||||
const savedEnclosingFunctionFlags = enclosingFunctionFlags;
|
||||
enclosingFunctionFlags = getFunctionFlags(node);
|
||||
const updated = updateArrowFunction(
|
||||
node,
|
||||
node.modifiers,
|
||||
/*typeParameters*/ undefined,
|
||||
@ -337,25 +588,92 @@ namespace ts {
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
);
|
||||
enclosingFunctionFlags = savedEnclosingFunctionFlags;
|
||||
return updated;
|
||||
}
|
||||
|
||||
function visitFunctionExpression(node: FunctionExpression) {
|
||||
return updateFunctionExpression(
|
||||
const savedEnclosingFunctionFlags = enclosingFunctionFlags;
|
||||
enclosingFunctionFlags = getFunctionFlags(node);
|
||||
const updated = updateFunctionExpression(
|
||||
node,
|
||||
node.modifiers,
|
||||
enclosingFunctionFlags & FunctionFlags.Generator
|
||||
? visitNodes(node.modifiers, visitorNoAsyncModifier, isModifier)
|
||||
: node.modifiers,
|
||||
enclosingFunctionFlags & FunctionFlags.Async
|
||||
? undefined
|
||||
: node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator
|
||||
? transformAsyncGeneratorFunctionBody(node)
|
||||
: transformFunctionBody(node)
|
||||
);
|
||||
enclosingFunctionFlags = savedEnclosingFunctionFlags;
|
||||
return updated;
|
||||
}
|
||||
|
||||
function transformAsyncGeneratorFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody {
|
||||
resumeLexicalEnvironment();
|
||||
const statements: Statement[] = [];
|
||||
const statementOffset = addPrologueDirectives(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
|
||||
appendObjectRestAssignmentsIfNeeded(statements, node);
|
||||
|
||||
statements.push(
|
||||
createReturn(
|
||||
createAsyncGeneratorHelper(
|
||||
context,
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
createToken(SyntaxKind.AsteriskToken),
|
||||
node.name && getGeneratedNameForNode(node.name),
|
||||
/*typeParameters*/ undefined,
|
||||
/*parameters*/ [],
|
||||
/*type*/ undefined,
|
||||
updateBlock(
|
||||
node.body,
|
||||
visitLexicalEnvironment(node.body.statements, visitor, context, statementOffset)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
const block = updateBlock(node.body, statements);
|
||||
|
||||
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
|
||||
// This step isn't needed if we eventually transform this to ES5.
|
||||
if (languageVersion >= ScriptTarget.ES2015) {
|
||||
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
enableSubstitutionForAsyncMethodsWithSuper();
|
||||
addEmitHelper(block, advancedAsyncSuperHelper);
|
||||
}
|
||||
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuper) {
|
||||
enableSubstitutionForAsyncMethodsWithSuper();
|
||||
addEmitHelper(block, asyncSuperHelper);
|
||||
}
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
function transformFunctionBody(node: FunctionDeclaration | FunctionExpression | ConstructorDeclaration | MethodDeclaration | AccessorDeclaration): FunctionBody;
|
||||
function transformFunctionBody(node: ArrowFunction): ConciseBody;
|
||||
function transformFunctionBody(node: FunctionLikeDeclaration): ConciseBody {
|
||||
resumeLexicalEnvironment();
|
||||
let leadingStatements: Statement[];
|
||||
const leadingStatements = appendObjectRestAssignmentsIfNeeded(/*statements*/ undefined, node);
|
||||
const body = visitNode(node.body, visitor, isConciseBody);
|
||||
const trailingStatements = endLexicalEnvironment();
|
||||
if (some(leadingStatements) || some(trailingStatements)) {
|
||||
const block = convertToFunctionBody(body, /*multiLine*/ true);
|
||||
return updateBlock(block, setTextRange(createNodeArray(concatenate(concatenate(leadingStatements, block.statements), trailingStatements)), block.statements));
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
function appendObjectRestAssignmentsIfNeeded(statements: Statement[], node: FunctionLikeDeclaration): Statement[] {
|
||||
for (const parameter of node.parameters) {
|
||||
if (parameter.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
const temp = getGeneratedNameForNode(parameter);
|
||||
@ -376,17 +694,153 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
setEmitFlags(statement, EmitFlags.CustomPrologue);
|
||||
leadingStatements = append(leadingStatements, statement);
|
||||
statements = append(statements, statement);
|
||||
}
|
||||
}
|
||||
}
|
||||
const body = visitNode(node.body, visitor, isConciseBody);
|
||||
const trailingStatements = endLexicalEnvironment();
|
||||
if (some(leadingStatements) || some(trailingStatements)) {
|
||||
const block = convertToFunctionBody(body, /*multiLine*/ true);
|
||||
return updateBlock(block, setTextRange(createNodeArray(concatenate(concatenate(leadingStatements, block.statements), trailingStatements)), block.statements));
|
||||
return statements;
|
||||
}
|
||||
|
||||
function enableSubstitutionForAsyncMethodsWithSuper() {
|
||||
if ((enabledSubstitutions & ESNextSubstitutionFlags.AsyncMethodsWithSuper) === 0) {
|
||||
enabledSubstitutions |= ESNextSubstitutionFlags.AsyncMethodsWithSuper;
|
||||
|
||||
// We need to enable substitutions for call, property access, and element access
|
||||
// if we need to rewrite super calls.
|
||||
context.enableSubstitution(SyntaxKind.CallExpression);
|
||||
context.enableSubstitution(SyntaxKind.PropertyAccessExpression);
|
||||
context.enableSubstitution(SyntaxKind.ElementAccessExpression);
|
||||
|
||||
// We need to be notified when entering and exiting declarations that bind super.
|
||||
context.enableEmitNotification(SyntaxKind.ClassDeclaration);
|
||||
context.enableEmitNotification(SyntaxKind.MethodDeclaration);
|
||||
context.enableEmitNotification(SyntaxKind.GetAccessor);
|
||||
context.enableEmitNotification(SyntaxKind.SetAccessor);
|
||||
context.enableEmitNotification(SyntaxKind.Constructor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the printer just before a node is printed.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to be printed.
|
||||
* @param emitCallback The callback used to emit the node.
|
||||
*/
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
// If we need to support substitutions for `super` in an async method,
|
||||
// we should track it here.
|
||||
if (enabledSubstitutions & ESNextSubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
|
||||
const superContainerFlags = resolver.getNodeCheckFlags(node) & (NodeCheckFlags.AsyncMethodWithSuper | NodeCheckFlags.AsyncMethodWithSuperBinding);
|
||||
if (superContainerFlags !== enclosingSuperContainerFlags) {
|
||||
const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
|
||||
enclosingSuperContainerFlags = superContainerFlags;
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param hint The context for the emitter.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (hint === EmitHint.Expression && enclosingSuperContainerFlags) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteExpression(node: Expression) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return substitutePropertyAccessExpression(<PropertyAccessExpression>node);
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
return substituteElementAccessExpression(<ElementAccessExpression>node);
|
||||
case SyntaxKind.CallExpression:
|
||||
return substituteCallExpression(<CallExpression>node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
createLiteral(node.name.text),
|
||||
node
|
||||
);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteElementAccessExpression(node: ElementAccessExpression) {
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
node.argumentExpression,
|
||||
node
|
||||
);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteCallExpression(node: CallExpression): Expression {
|
||||
const expression = node.expression;
|
||||
if (isSuperProperty(expression)) {
|
||||
const argumentExpression = isPropertyAccessExpression(expression)
|
||||
? substitutePropertyAccessExpression(expression)
|
||||
: substituteElementAccessExpression(expression);
|
||||
return createCall(
|
||||
createPropertyAccess(argumentExpression, "call"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createThis(),
|
||||
...node.arguments
|
||||
]
|
||||
);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function isSuperContainer(node: Node) {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.ClassDeclaration
|
||||
|| kind === SyntaxKind.Constructor
|
||||
|| kind === SyntaxKind.MethodDeclaration
|
||||
|| kind === SyntaxKind.GetAccessor
|
||||
|| kind === SyntaxKind.SetAccessor;
|
||||
}
|
||||
|
||||
function createSuperAccessInAsyncMethod(argumentExpression: Expression, location: TextRange): LeftHandSideExpression {
|
||||
if (enclosingSuperContainerFlags & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
createCall(
|
||||
createIdentifier("_super"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression]
|
||||
),
|
||||
"value"
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
else {
|
||||
return setTextRange(
|
||||
createCall(
|
||||
createIdentifier("_super"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression]
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
}
|
||||
|
||||
@ -418,4 +872,89 @@ namespace ts {
|
||||
attributesSegments
|
||||
);
|
||||
}
|
||||
|
||||
const asyncGeneratorHelper: EmitHelper = {
|
||||
name: "typescript:asyncGenerator",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
var g = generator.apply(thisArg, _arguments || []), q = [], c, i;
|
||||
return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i;
|
||||
function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }
|
||||
function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }
|
||||
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }
|
||||
function step(r) { r.done ? settle(c[2], r) : r.value[0] === "yield" ? settle(c[2], { value: r.value[1], done: false }) : Promise.resolve(r.value[1]).then(r.value[0] === "delegate" ? delegate : fulfill, reject); }
|
||||
function delegate(r) { step(r.done ? r : { value: ["yield", r.value], done: false }); }
|
||||
function fulfill(value) { resume("next", value); }
|
||||
function reject(value) { resume("throw", value); }
|
||||
function settle(f, v) { c = void 0, f(v), next(); }
|
||||
};
|
||||
`
|
||||
};
|
||||
|
||||
function createAsyncGeneratorHelper(context: TransformationContext, generatorFunc: FunctionExpression) {
|
||||
context.requestEmitHelper(asyncGeneratorHelper);
|
||||
|
||||
// Mark this node as originally an async function
|
||||
(generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= EmitFlags.AsyncFunctionBody;
|
||||
|
||||
return createCall(
|
||||
getHelperName("__asyncGenerator"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createThis(),
|
||||
createIdentifier("arguments"),
|
||||
generatorFunc
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
const asyncDelegator: EmitHelper = {
|
||||
name: "typescript:asyncDelegator",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i = { next: verb("next"), "throw": verb("throw", function (e) { throw e; }), "return": verb("return", function (v) { return { value: v, done: true }; }) };
|
||||
return o = __asyncValues(o), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { return function (v) { return { value: ["delegate", (o[n] || f).call(o, v)], done: false }; }; }
|
||||
};
|
||||
`
|
||||
};
|
||||
|
||||
function createAsyncDelegatorHelper(context: TransformationContext, expression: Expression, location?: TextRange) {
|
||||
context.requestEmitHelper(asyncDelegator);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__asyncDelegator"),
|
||||
/*typeArguments*/ undefined,
|
||||
[expression]
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
const asyncValues: EmitHelper = {
|
||||
name: "typescript:asyncValues",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
var m = o[Symbol.asyncIterator];
|
||||
return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator]();
|
||||
};
|
||||
`
|
||||
};
|
||||
|
||||
function createAsyncValuesHelper(context: TransformationContext, expression: Expression, location?: TextRange) {
|
||||
context.requestEmitHelper(asyncValues);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__asyncValues"),
|
||||
/*typeArguments*/ undefined,
|
||||
[expression]
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../visitor.ts" />
|
||||
|
||||
// Transforms generator functions into a compatible ES5 representation with similar runtime
|
||||
@ -232,7 +232,7 @@ namespace ts {
|
||||
resumeLexicalEnvironment,
|
||||
endLexicalEnvironment,
|
||||
hoistFunctionDeclaration,
|
||||
hoistVariableDeclaration,
|
||||
hoistVariableDeclaration
|
||||
} = context;
|
||||
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
@ -448,7 +448,7 @@ namespace ts {
|
||||
*/
|
||||
function visitFunctionDeclaration(node: FunctionDeclaration): Statement {
|
||||
// Currently, we only support generators that were originally async functions.
|
||||
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
if (node.asteriskToken) {
|
||||
node = setOriginalNode(
|
||||
setTextRange(
|
||||
createFunctionDeclaration(
|
||||
@ -498,7 +498,7 @@ namespace ts {
|
||||
*/
|
||||
function visitFunctionExpression(node: FunctionExpression): Expression {
|
||||
// Currently, we only support generators that were originally async functions.
|
||||
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
if (node.asteriskToken) {
|
||||
node = setOriginalNode(
|
||||
setTextRange(
|
||||
createFunctionExpression(
|
||||
@ -936,11 +936,10 @@ namespace ts {
|
||||
// .mark resumeLabel
|
||||
// x = %sent%;
|
||||
|
||||
// NOTE: we are explicitly not handling YieldStar at this time.
|
||||
const resumeLabel = defineLabel();
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
if (node.asteriskToken) {
|
||||
emitYieldStar(expression, /*location*/ node);
|
||||
emitYieldStar(createValuesHelper(context, expression, /*location*/ node), /*location*/ node);
|
||||
}
|
||||
else {
|
||||
emitYield(expression, /*location*/ node);
|
||||
@ -978,9 +977,10 @@ namespace ts {
|
||||
// ar = _a.concat([%sent%, 2]);
|
||||
|
||||
const numInitialElements = countInitialNodesWithoutYield(elements);
|
||||
const temp = declareLocal();
|
||||
let hasAssignedTemp = false;
|
||||
|
||||
let temp: Identifier;
|
||||
if (numInitialElements > 0) {
|
||||
temp = declareLocal();
|
||||
const initialElements = visitNodes(elements, visitor, isExpression, 0, numInitialElements);
|
||||
emitAssignment(temp,
|
||||
createArrayLiteral(
|
||||
@ -990,11 +990,10 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
leadingElement = undefined;
|
||||
hasAssignedTemp = true;
|
||||
}
|
||||
|
||||
const expressions = reduceLeft(elements, reduceElement, <Expression[]>[], numInitialElements);
|
||||
return hasAssignedTemp
|
||||
return temp
|
||||
? createArrayConcat(temp, [createArrayLiteral(expressions, multiLine)])
|
||||
: setTextRange(
|
||||
createArrayLiteral(leadingElement ? [leadingElement, ...expressions] : expressions, multiLine),
|
||||
@ -1003,6 +1002,11 @@ namespace ts {
|
||||
|
||||
function reduceElement(expressions: Expression[], element: Expression) {
|
||||
if (containsYield(element) && expressions.length > 0) {
|
||||
const hasAssignedTemp = temp !== undefined;
|
||||
if (!temp) {
|
||||
temp = declareLocal();
|
||||
}
|
||||
|
||||
emitAssignment(
|
||||
temp,
|
||||
hasAssignedTemp
|
||||
@ -1015,7 +1019,6 @@ namespace ts {
|
||||
multiLine
|
||||
)
|
||||
);
|
||||
hasAssignedTemp = true;
|
||||
leadingElement = undefined;
|
||||
expressions = [];
|
||||
}
|
||||
@ -1227,7 +1230,7 @@ namespace ts {
|
||||
case SyntaxKind.TryStatement:
|
||||
return transformAndEmitTryStatement(<TryStatement>node);
|
||||
default:
|
||||
return emitStatement(visitNode(node, visitor, isStatement, /*optional*/ true));
|
||||
return emitStatement(visitNode(node, visitor, isStatement));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1475,7 +1478,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const initializer = node.initializer;
|
||||
if (isVariableDeclarationList(initializer)) {
|
||||
if (initializer && isVariableDeclarationList(initializer)) {
|
||||
for (const variable of initializer.declarations) {
|
||||
hoistVariableDeclaration(<Identifier>variable.name);
|
||||
}
|
||||
@ -1485,9 +1488,9 @@ namespace ts {
|
||||
variables.length > 0
|
||||
? inlineExpressions(map(variables, transformInitializedVariable))
|
||||
: undefined,
|
||||
visitNode(node.condition, visitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.incrementor, visitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.statement, visitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.condition, visitor, isExpression),
|
||||
visitNode(node.incrementor, visitor, isExpression),
|
||||
visitNode(node.statement, visitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
else {
|
||||
@ -1609,7 +1612,7 @@ namespace ts {
|
||||
node = updateForIn(node,
|
||||
<Identifier>initializer.declarations[0].name,
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
visitNode(node.statement, visitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, visitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
else {
|
||||
@ -1659,14 +1662,14 @@ namespace ts {
|
||||
|
||||
function transformAndEmitReturnStatement(node: ReturnStatement): void {
|
||||
emitReturn(
|
||||
visitNode(node.expression, visitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
|
||||
function visitReturnStatement(node: ReturnStatement) {
|
||||
return createInlineReturn(
|
||||
visitNode(node.expression, visitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
@ -1939,7 +1942,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function substituteExpressionIdentifier(node: Identifier) {
|
||||
if (renamedCatchVariables && renamedCatchVariables.has(node.text)) {
|
||||
if (!isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(node.text)) {
|
||||
const original = getOriginalNode(node);
|
||||
if (isIdentifier(original) && original.parent) {
|
||||
const declaration = resolver.getReferencedValueDeclaration(original);
|
||||
@ -1960,7 +1963,7 @@ namespace ts {
|
||||
|
||||
function cacheExpression(node: Expression): Identifier {
|
||||
let temp: Identifier;
|
||||
if (isGeneratedIdentifier(node)) {
|
||||
if (isGeneratedIdentifier(node) || getEmitFlags(node) & EmitFlags.HelperName) {
|
||||
return <Identifier>node;
|
||||
}
|
||||
|
||||
@ -2105,17 +2108,24 @@ namespace ts {
|
||||
function beginCatchBlock(variable: VariableDeclaration): void {
|
||||
Debug.assert(peekBlockKind() === CodeBlockKind.Exception);
|
||||
|
||||
const text = (<Identifier>variable.name).text;
|
||||
const name = declareLocal(text);
|
||||
|
||||
if (!renamedCatchVariables) {
|
||||
renamedCatchVariables = createMap<boolean>();
|
||||
renamedCatchVariableDeclarations = [];
|
||||
context.enableSubstitution(SyntaxKind.Identifier);
|
||||
// generated identifiers should already be unique within a file
|
||||
let name: Identifier;
|
||||
if (isGeneratedIdentifier(variable.name)) {
|
||||
name = variable.name;
|
||||
hoistVariableDeclaration(variable.name);
|
||||
}
|
||||
else {
|
||||
const text = (<Identifier>variable.name).text;
|
||||
name = declareLocal(text);
|
||||
if (!renamedCatchVariables) {
|
||||
renamedCatchVariables = createMap<boolean>();
|
||||
renamedCatchVariableDeclarations = [];
|
||||
context.enableSubstitution(SyntaxKind.Identifier);
|
||||
}
|
||||
|
||||
renamedCatchVariables.set(text, true);
|
||||
renamedCatchVariableDeclarations[getOriginalNodeId(variable)] = name;
|
||||
renamedCatchVariables.set(text, true);
|
||||
renamedCatchVariableDeclarations[getOriginalNodeId(variable)] = name;
|
||||
}
|
||||
|
||||
const exception = <ExceptionBlock>peekBlock();
|
||||
Debug.assert(exception.state < ExceptionBlockState.Catch);
|
||||
@ -2419,7 +2429,7 @@ namespace ts {
|
||||
*/
|
||||
function createInstruction(instruction: Instruction): NumericLiteral {
|
||||
const literal = createLiteral(instruction);
|
||||
literal.trailingComment = getInstructionName(instruction);
|
||||
addSyntheticTrailingComment(literal, SyntaxKind.MultiLineCommentTrivia, getInstructionName(instruction));
|
||||
return literal;
|
||||
}
|
||||
|
||||
@ -3229,8 +3239,8 @@ namespace ts {
|
||||
priority: 6,
|
||||
text: `
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t;
|
||||
return { next: verb(0), "throw": verb(1), "return": verb(2) };
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
namespace ts {
|
||||
export function transformJsx(context: TransformationContext) {
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
let currentSourceFile: SourceFile;
|
||||
|
||||
return transformSourceFile;
|
||||
|
||||
@ -20,12 +19,8 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
currentSourceFile = node;
|
||||
|
||||
const visited = visitEachChild(node, visitor, context);
|
||||
addEmitHelpers(visited, context.readEmitHelpers());
|
||||
|
||||
currentSourceFile = undefined;
|
||||
return visited;
|
||||
}
|
||||
|
||||
@ -85,7 +80,7 @@ namespace ts {
|
||||
function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: JsxChild[], isChild: boolean, location: TextRange) {
|
||||
const tagName = getTagName(node);
|
||||
let objectProperties: Expression;
|
||||
const attrs = node.attributes;
|
||||
const attrs = node.attributes.properties;
|
||||
if (attrs.length === 0) {
|
||||
// When there are no attributes, React wants "null"
|
||||
objectProperties = createNull();
|
||||
|
||||
@ -101,6 +101,7 @@ namespace ts {
|
||||
if (isIdentifier(node) && hint === EmitHint.Expression) {
|
||||
return substituteExpressionIdentifier(node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/// <reference path="../../factory.ts" />
|
||||
/// <reference path="../../factory.ts" />
|
||||
/// <reference path="../../visitor.ts" />
|
||||
/// <reference path="../destructuring.ts" />
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
@ -54,9 +55,7 @@ namespace ts {
|
||||
* @param node The SourceFile node.
|
||||
*/
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
if (isDeclarationFile(node)
|
||||
|| !(isExternalModule(node)
|
||||
|| compilerOptions.isolatedModules)) {
|
||||
if (isDeclarationFile(node) || !(isExternalModule(node) || compilerOptions.isolatedModules)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -73,6 +72,14 @@ namespace ts {
|
||||
return aggregateTransformFlags(updated);
|
||||
}
|
||||
|
||||
|
||||
function shouldEmitUnderscoreUnderscoreESModule() {
|
||||
if (!currentModuleInfo.exportEquals && isExternalModule(currentSourceFile)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a SourceFile into a CommonJS module.
|
||||
*
|
||||
@ -82,19 +89,22 @@ namespace ts {
|
||||
startLexicalEnvironment();
|
||||
|
||||
const statements: Statement[] = [];
|
||||
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
|
||||
const ensureUseStrict = compilerOptions.alwaysStrict || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile));
|
||||
const statementOffset = addPrologueDirectives(statements, node.statements, ensureUseStrict, sourceElementVisitor);
|
||||
|
||||
if (!currentModuleInfo.exportEquals) {
|
||||
if (shouldEmitUnderscoreUnderscoreESModule()) {
|
||||
append(statements, createUnderscoreUnderscoreESModule());
|
||||
}
|
||||
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement, /*optional*/ true));
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement));
|
||||
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false);
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
|
||||
const updated = updateSourceFileNode(node, setTextRange(createNodeArray(statements), node.statements));
|
||||
if (currentModuleInfo.hasExportStarsToExportValues) {
|
||||
// If we have any `export * from ...` declarations
|
||||
// we need to inform the emitter to add the __export helper.
|
||||
addEmitHelper(updated, exportStarHelper);
|
||||
}
|
||||
return updated;
|
||||
@ -349,15 +359,20 @@ namespace ts {
|
||||
|
||||
// Find the name of the module alias, if there is one
|
||||
const importAliasName = getLocalNameForExternalImport(importNode, currentSourceFile);
|
||||
if (includeNonAmdDependencies && importAliasName) {
|
||||
// Set emitFlags on the name of the classDeclaration
|
||||
// This is so that when printer will not substitute the identifier
|
||||
setEmitFlags(importAliasName, EmitFlags.NoSubstitution);
|
||||
aliasedModuleNames.push(externalModuleName);
|
||||
importAliasNames.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, importAliasName));
|
||||
}
|
||||
else {
|
||||
unaliasedModuleNames.push(externalModuleName);
|
||||
// It is possible that externalModuleName is undefined if it is not string literal.
|
||||
// This can happen in the invalid import syntax.
|
||||
// E.g : "import * from alias from 'someLib';"
|
||||
if (externalModuleName) {
|
||||
if (includeNonAmdDependencies && importAliasName) {
|
||||
// Set emitFlags on the name of the classDeclaration
|
||||
// This is so that when printer will not substitute the identifier
|
||||
setEmitFlags(importAliasName, EmitFlags.NoSubstitution);
|
||||
aliasedModuleNames.push(externalModuleName);
|
||||
importAliasNames.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, importAliasName));
|
||||
}
|
||||
else {
|
||||
unaliasedModuleNames.push(externalModuleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,21 +390,21 @@ namespace ts {
|
||||
const statements: Statement[] = [];
|
||||
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
|
||||
|
||||
if (!currentModuleInfo.exportEquals) {
|
||||
if (shouldEmitUnderscoreUnderscoreESModule()) {
|
||||
append(statements, createUnderscoreUnderscoreESModule());
|
||||
}
|
||||
|
||||
// Visit each statement of the module body.
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement, /*optional*/ true));
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement));
|
||||
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
|
||||
|
||||
// Append the 'export =' statement if provided.
|
||||
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ true);
|
||||
|
||||
// End the lexical environment for the module body
|
||||
// and merge any new lexical declarations.
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
|
||||
// Append the 'export =' statement if provided.
|
||||
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ true);
|
||||
|
||||
const body = createBlock(statements, /*multiLine*/ true);
|
||||
if (currentModuleInfo.hasExportStarsToExportValues) {
|
||||
// If we have any `export * from ...` declarations
|
||||
@ -1147,9 +1162,9 @@ namespace ts {
|
||||
statement = createStatement(
|
||||
createExportExpression(
|
||||
createIdentifier("__esModule"),
|
||||
createLiteral(true)
|
||||
createLiteral(/*value*/ true)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
statement = createStatement(
|
||||
@ -1160,7 +1175,7 @@ namespace ts {
|
||||
createIdentifier("exports"),
|
||||
createLiteral("__esModule"),
|
||||
createObjectLiteral([
|
||||
createPropertyAssignment("value", createLiteral(true))
|
||||
createPropertyAssignment("value", createLiteral(/*value*/ true))
|
||||
])
|
||||
]
|
||||
)
|
||||
@ -1334,6 +1349,7 @@ namespace ts {
|
||||
if (externalHelpersModuleName) {
|
||||
return createPropertyAccess(externalHelpersModuleName, node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/// <reference path="../../factory.ts" />
|
||||
/// <reference path="../../factory.ts" />
|
||||
/// <reference path="../../visitor.ts" />
|
||||
/// <reference path="../destructuring.ts" />
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
@ -136,7 +137,6 @@ namespace ts {
|
||||
contextObject = undefined;
|
||||
hoistedStatements = undefined;
|
||||
enclosingBlockScopedContainer = undefined;
|
||||
|
||||
return aggregateTransformFlags(updated);
|
||||
}
|
||||
|
||||
@ -151,18 +151,20 @@ namespace ts {
|
||||
for (let i = 0; i < externalImports.length; i++) {
|
||||
const externalImport = externalImports[i];
|
||||
const externalModuleName = getExternalModuleNameLiteral(externalImport, currentSourceFile, host, resolver, compilerOptions);
|
||||
const text = externalModuleName.text;
|
||||
const groupIndex = groupIndices.get(text);
|
||||
if (groupIndex !== undefined) {
|
||||
// deduplicate/group entries in dependency list by the dependency name
|
||||
dependencyGroups[groupIndex].externalImports.push(externalImport);
|
||||
}
|
||||
else {
|
||||
groupIndices.set(text, dependencyGroups.length);
|
||||
dependencyGroups.push({
|
||||
name: externalModuleName,
|
||||
externalImports: [externalImport]
|
||||
});
|
||||
if (externalModuleName) {
|
||||
const text = externalModuleName.text;
|
||||
const groupIndex = groupIndices.get(text);
|
||||
if (groupIndex !== undefined) {
|
||||
// deduplicate/group entries in dependency list by the dependency name
|
||||
dependencyGroups[groupIndex].externalImports.push(externalImport);
|
||||
}
|
||||
else {
|
||||
groupIndices.set(text, dependencyGroups.length);
|
||||
dependencyGroups.push({
|
||||
name: externalModuleName,
|
||||
externalImports: [externalImport]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,7 +227,8 @@ namespace ts {
|
||||
startLexicalEnvironment();
|
||||
|
||||
// Add any prologue directives.
|
||||
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
|
||||
const ensureUseStrict = compilerOptions.alwaysStrict || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile));
|
||||
const statementOffset = addPrologueDirectives(statements, node.statements, ensureUseStrict, sourceElementVisitor);
|
||||
|
||||
// var __moduleName = context_1 && context_1.id;
|
||||
statements.push(
|
||||
@ -245,7 +248,7 @@ namespace ts {
|
||||
);
|
||||
|
||||
// Visit the synthetic external helpers import declaration if present
|
||||
visitNode(moduleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement, /*optional*/ true);
|
||||
visitNode(moduleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement);
|
||||
|
||||
// Visit the statements of the source file, emitting any transformations into
|
||||
// the `executeStatements` array. We do this *before* we fill the `setters` array
|
||||
@ -669,6 +672,7 @@ namespace ts {
|
||||
node,
|
||||
node.decorators,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
node.asteriskToken,
|
||||
getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, destructuringVisitor, isParameterDeclaration),
|
||||
@ -1218,8 +1222,8 @@ namespace ts {
|
||||
node = updateFor(
|
||||
node,
|
||||
visitForInitializer(node.initializer),
|
||||
visitNode(node.condition, destructuringVisitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.incrementor, destructuringVisitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.condition, destructuringVisitor, isExpression),
|
||||
visitNode(node.incrementor, destructuringVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement)
|
||||
);
|
||||
|
||||
@ -1240,7 +1244,7 @@ namespace ts {
|
||||
node,
|
||||
visitForInitializer(node.initializer),
|
||||
visitNode(node.expression, destructuringVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
|
||||
enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
|
||||
@ -1258,9 +1262,10 @@ namespace ts {
|
||||
|
||||
node = updateForOf(
|
||||
node,
|
||||
node.awaitModifier,
|
||||
visitForInitializer(node.initializer),
|
||||
visitNode(node.expression, destructuringVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
|
||||
enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
|
||||
@ -1284,6 +1289,10 @@ namespace ts {
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitForInitializer(node: ForInitializer): ForInitializer {
|
||||
if (!node) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (shouldHoistForInitializer(node)) {
|
||||
let expressions: Expression[];
|
||||
for (const variable of node.declarations) {
|
||||
@ -1305,7 +1314,7 @@ namespace ts {
|
||||
function visitDoStatement(node: DoStatement): VisitResult<Statement> {
|
||||
return updateDo(
|
||||
node,
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock),
|
||||
visitNode(node.expression, destructuringVisitor, isExpression)
|
||||
);
|
||||
}
|
||||
@ -1319,7 +1328,7 @@ namespace ts {
|
||||
return updateWhile(
|
||||
node,
|
||||
visitNode(node.expression, destructuringVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
|
||||
@ -1332,7 +1341,7 @@ namespace ts {
|
||||
return updateLabel(
|
||||
node,
|
||||
node.label,
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
|
||||
@ -1345,7 +1354,7 @@ namespace ts {
|
||||
return updateWith(
|
||||
node,
|
||||
visitNode(node.expression, destructuringVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
|
||||
@ -1492,7 +1501,7 @@ namespace ts {
|
||||
* @param node The destructuring target.
|
||||
*/
|
||||
function hasExportedReferenceInDestructuringTarget(node: Expression | ObjectLiteralElementLike): boolean {
|
||||
if (isAssignmentExpression(node)) {
|
||||
if (isAssignmentExpression(node, /*excludeCompoundAssignment*/ true)) {
|
||||
return hasExportedReferenceInDestructuringTarget(node.left);
|
||||
}
|
||||
else if (isSpreadExpression(node)) {
|
||||
@ -1625,6 +1634,7 @@ namespace ts {
|
||||
if (externalHelpersModuleName) {
|
||||
return createPropertyAccess(externalHelpersModuleName, node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../visitor.ts" />
|
||||
/// <reference path="./destructuring.ts" />
|
||||
|
||||
@ -472,7 +472,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitSourceFile(node: SourceFile) {
|
||||
const alwaysStrict = compilerOptions.alwaysStrict && !(isExternalModule(node) && moduleKind === ModuleKind.ES2015);
|
||||
const alwaysStrict = (compilerOptions.alwaysStrict === undefined ? compilerOptions.strict : compilerOptions.alwaysStrict) &&
|
||||
!(isExternalModule(node) && moduleKind === ModuleKind.ES2015);
|
||||
return updateSourceFileNode(
|
||||
node,
|
||||
visitLexicalEnvironment(node.statements, sourceElementVisitor, context, /*start*/ 0, alwaysStrict));
|
||||
@ -872,7 +873,7 @@ namespace ts {
|
||||
* @param hasExtendsClause A value indicating whether the class has an extends clause.
|
||||
*/
|
||||
function transformConstructorBody(node: ClassExpression | ClassDeclaration, constructor: ConstructorDeclaration, hasExtendsClause: boolean) {
|
||||
const statements: Statement[] = [];
|
||||
let statements: Statement[] = [];
|
||||
let indexOfFirstStatement = 0;
|
||||
|
||||
resumeLexicalEnvironment();
|
||||
@ -930,7 +931,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// End the lexical environment.
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
statements = mergeLexicalEnvironment(statements, endLexicalEnvironment());
|
||||
return setTextRange(
|
||||
createBlock(
|
||||
setTextRange(
|
||||
@ -1651,7 +1652,7 @@ namespace ts {
|
||||
if (isFunctionLike(node) && node.type) {
|
||||
return serializeTypeNode(node.type);
|
||||
}
|
||||
else if (isAsyncFunctionLike(node)) {
|
||||
else if (isAsyncFunction(node)) {
|
||||
return createIdentifier("Promise");
|
||||
}
|
||||
|
||||
@ -2019,7 +2020,13 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return visitEachChild(node, visitor, context);
|
||||
return updateConstructor(
|
||||
node,
|
||||
visitNodes(node.decorators, visitor, isDecorator),
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2040,7 +2047,9 @@ namespace ts {
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
node.asteriskToken,
|
||||
visitPropertyNameOfClassElement(node),
|
||||
/*questionToken*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
@ -2144,6 +2153,7 @@ namespace ts {
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
@ -2167,17 +2177,18 @@ namespace ts {
|
||||
* @param node The function expression node.
|
||||
*/
|
||||
function visitFunctionExpression(node: FunctionExpression): Expression {
|
||||
if (nodeIsMissing(node.body)) {
|
||||
if (!shouldEmitFunctionLikeDeclaration(node)) {
|
||||
return createOmittedExpression();
|
||||
}
|
||||
const updated = updateFunctionExpression(
|
||||
node,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
visitFunctionBody(node.body, visitor, context)
|
||||
visitFunctionBody(node.body, visitor, context) || createBlock([])
|
||||
);
|
||||
return updated;
|
||||
}
|
||||
@ -2313,13 +2324,13 @@ namespace ts {
|
||||
// code if the casted expression has a lower precedence than the rest of the
|
||||
// expression.
|
||||
//
|
||||
// To preserve comments, we return a "PartiallyEmittedExpression" here which will
|
||||
// preserve the position information of the original expression.
|
||||
//
|
||||
// Due to the auto-parenthesization rules used by the visitor and factory functions
|
||||
// we can safely elide the parentheses here, as a new synthetic
|
||||
// ParenthesizedExpression will be inserted if we remove parentheses too
|
||||
// aggressively.
|
||||
//
|
||||
// To preserve comments, we return a "PartiallyEmittedExpression" here which will
|
||||
// preserve the position information of the original expression.
|
||||
return createPartiallyEmittedExpression(expression, node);
|
||||
}
|
||||
|
||||
@ -2833,7 +2844,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Elide the declaration if the import clause was elided.
|
||||
const importClause = visitNode(node.importClause, visitImportClause, isImportClause, /*optional*/ true);
|
||||
const importClause = visitNode(node.importClause, visitImportClause, isImportClause);
|
||||
return importClause
|
||||
? updateImportDeclaration(
|
||||
node,
|
||||
@ -2852,7 +2863,7 @@ namespace ts {
|
||||
function visitImportClause(node: ImportClause): VisitResult<ImportClause> {
|
||||
// Elide the import clause if we elide both its name and its named bindings.
|
||||
const name = resolver.isReferencedAliasDeclaration(node) ? node.name : undefined;
|
||||
const namedBindings = visitNode(node.namedBindings, visitNamedImportBindings, isNamedImportBindings, /*optional*/ true);
|
||||
const namedBindings = visitNode(node.namedBindings, visitNamedImportBindings, isNamedImportBindings);
|
||||
return (name || namedBindings) ? updateImportClause(node, name, namedBindings) : undefined;
|
||||
}
|
||||
|
||||
@ -2914,7 +2925,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Elide the export declaration if all of its named exports are elided.
|
||||
const exportClause = visitNode(node.exportClause, visitNamedExports, isNamedExports, /*optional*/ true);
|
||||
const exportClause = visitNode(node.exportClause, visitNamedExports, isNamedExports);
|
||||
return exportClause
|
||||
? updateExportDeclaration(
|
||||
node,
|
||||
@ -3187,6 +3198,11 @@ namespace ts {
|
||||
*/
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
const savedApplicableSubstitutions = applicableSubstitutions;
|
||||
const savedCurrentSourceFile = currentSourceFile;
|
||||
|
||||
if (isSourceFile(node)) {
|
||||
currentSourceFile = node;
|
||||
}
|
||||
|
||||
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && isTransformedModuleDeclaration(node)) {
|
||||
applicableSubstitutions |= TypeScriptSubstitutionFlags.NamespaceExports;
|
||||
@ -3199,6 +3215,7 @@ namespace ts {
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
|
||||
applicableSubstitutions = savedApplicableSubstitutions;
|
||||
currentSourceFile = savedCurrentSourceFile;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3312,17 +3329,18 @@ namespace ts {
|
||||
function substituteConstantValue(node: PropertyAccessExpression | ElementAccessExpression): LeftHandSideExpression {
|
||||
const constantValue = tryGetConstEnumValue(node);
|
||||
if (constantValue !== undefined) {
|
||||
// track the constant value on the node for the printer in needsDotDotForPropertyAccess
|
||||
setConstantValue(node, constantValue);
|
||||
|
||||
const substitute = createLiteral(constantValue);
|
||||
setSourceMapRange(substitute, node);
|
||||
setCommentRange(substitute, node);
|
||||
if (!compilerOptions.removeComments) {
|
||||
const propertyName = isPropertyAccessExpression(node)
|
||||
? declarationNameToString(node.name)
|
||||
: getTextOfNode(node.argumentExpression);
|
||||
substitute.trailingComment = ` ${propertyName} `;
|
||||
|
||||
addSyntheticTrailingComment(substitute, SyntaxKind.MultiLineCommentTrivia, ` ${propertyName} `);
|
||||
}
|
||||
|
||||
setConstantValue(node, constantValue);
|
||||
return substitute;
|
||||
}
|
||||
|
||||
@ -3340,13 +3358,60 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const paramHelper: EmitHelper = {
|
||||
name: "typescript:param",
|
||||
function createDecorateHelper(context: TransformationContext, decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression, location?: TextRange) {
|
||||
const argumentsArray: Expression[] = [];
|
||||
argumentsArray.push(createArrayLiteral(decoratorExpressions, /*multiLine*/ true));
|
||||
argumentsArray.push(target);
|
||||
if (memberName) {
|
||||
argumentsArray.push(memberName);
|
||||
if (descriptor) {
|
||||
argumentsArray.push(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
context.requestEmitHelper(decorateHelper);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__decorate"),
|
||||
/*typeArguments*/ undefined,
|
||||
argumentsArray
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
const decorateHelper: EmitHelper = {
|
||||
name: "typescript:decorate",
|
||||
scoped: false,
|
||||
priority: 4,
|
||||
priority: 2,
|
||||
text: `
|
||||
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
return function (target, key) { decorator(target, key, paramIndex); }
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};`
|
||||
};
|
||||
|
||||
function createMetadataHelper(context: TransformationContext, metadataKey: string, metadataValue: Expression) {
|
||||
context.requestEmitHelper(metadataHelper);
|
||||
return createCall(
|
||||
getHelperName("__metadata"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createLiteral(metadataKey),
|
||||
metadataValue
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
const metadataHelper: EmitHelper = {
|
||||
name: "typescript:metadata",
|
||||
scoped: false,
|
||||
priority: 3,
|
||||
text: `
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};`
|
||||
};
|
||||
|
||||
@ -3365,60 +3430,13 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
const metadataHelper: EmitHelper = {
|
||||
name: "typescript:metadata",
|
||||
const paramHelper: EmitHelper = {
|
||||
name: "typescript:param",
|
||||
scoped: false,
|
||||
priority: 3,
|
||||
priority: 4,
|
||||
text: `
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
return function (target, key) { decorator(target, key, paramIndex); }
|
||||
};`
|
||||
};
|
||||
|
||||
function createMetadataHelper(context: TransformationContext, metadataKey: string, metadataValue: Expression) {
|
||||
context.requestEmitHelper(metadataHelper);
|
||||
return createCall(
|
||||
getHelperName("__metadata"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createLiteral(metadataKey),
|
||||
metadataValue
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
const decorateHelper: EmitHelper = {
|
||||
name: "typescript:decorate",
|
||||
scoped: false,
|
||||
priority: 2,
|
||||
text: `
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};`
|
||||
};
|
||||
|
||||
function createDecorateHelper(context: TransformationContext, decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression, location?: TextRange) {
|
||||
context.requestEmitHelper(decorateHelper);
|
||||
const argumentsArray: Expression[] = [];
|
||||
argumentsArray.push(createArrayLiteral(decoratorExpressions, /*multiLine*/ true));
|
||||
argumentsArray.push(target);
|
||||
if (memberName) {
|
||||
argumentsArray.push(memberName);
|
||||
if (descriptor) {
|
||||
argumentsArray.push(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__decorate"),
|
||||
/*typeArguments*/ undefined,
|
||||
argumentsArray
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/// <reference path="program.ts"/>
|
||||
/// <reference path="program.ts"/>
|
||||
/// <reference path="commandLineParser.ts"/>
|
||||
|
||||
namespace ts {
|
||||
@ -225,9 +225,9 @@ namespace ts {
|
||||
return sys.exit(ExitStatus.Success);
|
||||
}
|
||||
|
||||
if (commandLine.options.help) {
|
||||
if (commandLine.options.help || commandLine.options.all) {
|
||||
printVersion();
|
||||
printHelp();
|
||||
printHelp(commandLine.options.all);
|
||||
return sys.exit(ExitStatus.Success);
|
||||
}
|
||||
|
||||
@ -264,7 +264,7 @@ namespace ts {
|
||||
|
||||
if (commandLine.fileNames.length === 0 && !configFileName) {
|
||||
printVersion();
|
||||
printHelp();
|
||||
printHelp(commandLine.options.all);
|
||||
return sys.exit(ExitStatus.Success);
|
||||
}
|
||||
|
||||
@ -336,7 +336,7 @@ namespace ts {
|
||||
// is an absolute file name.
|
||||
directory == "" ? "." : directory,
|
||||
watchedDirectoryChanged, /*recursive*/ true);
|
||||
};
|
||||
}
|
||||
}
|
||||
return configParseResult;
|
||||
}
|
||||
@ -618,7 +618,7 @@ namespace ts {
|
||||
sys.write(getDiagnosticText(Diagnostics.Version_0, ts.version) + sys.newLine);
|
||||
}
|
||||
|
||||
function printHelp() {
|
||||
function printHelp(showAllOptions: boolean) {
|
||||
const output: string[] = [];
|
||||
|
||||
// We want to align our "syntax" and "examples" commands to a certain margin.
|
||||
@ -643,8 +643,9 @@ namespace ts {
|
||||
output.push(getDiagnosticText(Diagnostics.Options_Colon) + sys.newLine);
|
||||
|
||||
// Sort our options by their names, (e.g. "--noImplicitAny" comes before "--watch")
|
||||
const optsList = filter(optionDeclarations.slice(), v => !v.experimental);
|
||||
optsList.sort((a, b) => compareValues<string>(a.name.toLowerCase(), b.name.toLowerCase()));
|
||||
const optsList = showAllOptions ?
|
||||
optionDeclarations.slice().sort((a, b) => compareValues<string>(a.name.toLowerCase(), b.name.toLowerCase())) :
|
||||
filter(optionDeclarations.slice(), v => v.showInSimplifiedHelpView);
|
||||
|
||||
// We want our descriptions to align at the same column in our output,
|
||||
// so we keep track of the longest option usage string.
|
||||
@ -738,7 +739,7 @@ namespace ts {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.A_tsconfig_json_file_is_already_defined_at_Colon_0, file), /* host */ undefined);
|
||||
}
|
||||
else {
|
||||
sys.writeFile(file, JSON.stringify(generateTSConfig(options, fileNames), undefined, 4));
|
||||
sys.writeFile(file, generateTSConfig(options, fileNames, sys.newLine));
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Successfully_created_a_tsconfig_json_file), /* host */ undefined);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/// <reference path="sys.ts" />
|
||||
/// <reference path="sys.ts" />
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
@ -24,6 +24,20 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function findDeclaration<T extends Declaration>(symbol: Symbol, predicate: (node: Declaration) => node is T): T | undefined;
|
||||
export function findDeclaration(symbol: Symbol, predicate: (node: Declaration) => boolean): Declaration | undefined;
|
||||
export function findDeclaration(symbol: Symbol, predicate: (node: Declaration) => boolean): Declaration | undefined {
|
||||
const declarations = symbol.declarations;
|
||||
if (declarations) {
|
||||
for (const declaration of declarations) {
|
||||
if (predicate(declaration)) {
|
||||
return declaration;
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export interface StringSymbolWriter extends SymbolWriter {
|
||||
string(): string;
|
||||
}
|
||||
@ -53,7 +67,8 @@ namespace ts {
|
||||
decreaseIndent: noop,
|
||||
clear: () => str = "",
|
||||
trackSymbol: noop,
|
||||
reportInaccessibleThisError: noop
|
||||
reportInaccessibleThisError: noop,
|
||||
reportIllegalExtends: noop
|
||||
};
|
||||
}
|
||||
|
||||
@ -169,7 +184,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getStartPositionOfLine(line: number, sourceFile: SourceFile): number {
|
||||
export function getStartPositionOfLine(line: number, sourceFile: SourceFileLike): number {
|
||||
Debug.assert(line >= 0);
|
||||
return getLineStarts(sourceFile)[line];
|
||||
}
|
||||
@ -189,7 +204,7 @@ namespace ts {
|
||||
return value !== undefined;
|
||||
}
|
||||
|
||||
export function getEndLinePosition(line: number, sourceFile: SourceFile): number {
|
||||
export function getEndLinePosition(line: number, sourceFile: SourceFileLike): number {
|
||||
Debug.assert(line >= 0);
|
||||
const lineStarts = getLineStarts(sourceFile);
|
||||
|
||||
@ -240,7 +255,11 @@ namespace ts {
|
||||
return !nodeIsMissing(node);
|
||||
}
|
||||
|
||||
export function getTokenPosOfNode(node: Node, sourceFile?: SourceFile, includeJsDoc?: boolean): number {
|
||||
export function isToken(n: Node): boolean {
|
||||
return n.kind >= SyntaxKind.FirstToken && n.kind <= SyntaxKind.LastToken;
|
||||
}
|
||||
|
||||
export function getTokenPosOfNode(node: Node, sourceFile?: SourceFileLike, includeJsDoc?: boolean): number {
|
||||
// With nodes that have no width (i.e. 'Missing' nodes), we actually *don't*
|
||||
// want to skip trivia because this will launch us forward to the next token.
|
||||
if (nodeIsMissing(node)) {
|
||||
@ -274,7 +293,7 @@ namespace ts {
|
||||
return node.kind >= SyntaxKind.FirstJSDocTagNode && node.kind <= SyntaxKind.LastJSDocTagNode;
|
||||
}
|
||||
|
||||
export function getNonDecoratorTokenPosOfNode(node: Node, sourceFile?: SourceFile): number {
|
||||
export function getNonDecoratorTokenPosOfNode(node: Node, sourceFile?: SourceFileLike): number {
|
||||
if (nodeIsMissing(node) || !node.decorators) {
|
||||
return getTokenPosOfNode(node, sourceFile);
|
||||
}
|
||||
@ -303,21 +322,11 @@ namespace ts {
|
||||
return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia);
|
||||
}
|
||||
|
||||
export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile, languageVersion: ScriptTarget) {
|
||||
// Any template literal or string literal with an extended escape
|
||||
// (e.g. "\u{0067}") will need to be downleveled as a escaped string literal.
|
||||
if (languageVersion < ScriptTarget.ES2015 && (isTemplateLiteralKind(node.kind) || node.hasExtendedUnicodeEscape)) {
|
||||
return getQuotedEscapedLiteralText('"', node.text, '"');
|
||||
}
|
||||
|
||||
export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile) {
|
||||
// If we don't need to downlevel and we can reach the original source text using
|
||||
// the node's parent reference, then simply get the text as it was originally written.
|
||||
if (!nodeIsSynthesized(node) && node.parent) {
|
||||
const text = getSourceTextOfNodeFromSourceFile(sourceFile, node);
|
||||
if (languageVersion < ScriptTarget.ES2015 && isBinaryOrOctalIntegerLiteral(node, text)) {
|
||||
return node.text;
|
||||
}
|
||||
return text;
|
||||
return getSourceTextOfNodeFromSourceFile(sourceFile, node);
|
||||
}
|
||||
|
||||
// If we can't reach the original source text, use the canonical form if it's a number,
|
||||
@ -340,55 +349,6 @@ namespace ts {
|
||||
Debug.fail(`Literal kind '${node.kind}' not accounted for.`);
|
||||
}
|
||||
|
||||
export function isBinaryOrOctalIntegerLiteral(node: LiteralLikeNode, text: string) {
|
||||
return node.kind === SyntaxKind.NumericLiteral
|
||||
&& (getNumericLiteralFlags(text, /*hint*/ NumericLiteralFlags.BinaryOrOctal) & NumericLiteralFlags.BinaryOrOctal) !== 0;
|
||||
}
|
||||
|
||||
export const enum NumericLiteralFlags {
|
||||
None = 0,
|
||||
Hexadecimal = 1 << 0,
|
||||
Binary = 1 << 1,
|
||||
Octal = 1 << 2,
|
||||
Scientific = 1 << 3,
|
||||
|
||||
BinaryOrOctal = Binary | Octal,
|
||||
BinaryOrOctalOrHexadecimal = BinaryOrOctal | Hexadecimal,
|
||||
All = Hexadecimal | Binary | Octal | Scientific,
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans a numeric literal string to determine the form of the number.
|
||||
* @param text Numeric literal text
|
||||
* @param hint If `Scientific` or `All` is specified, performs a more expensive check to scan for scientific notation.
|
||||
*/
|
||||
export function getNumericLiteralFlags(text: string, hint?: NumericLiteralFlags) {
|
||||
if (text.length > 1) {
|
||||
switch (text.charCodeAt(1)) {
|
||||
case CharacterCodes.b:
|
||||
case CharacterCodes.B:
|
||||
return NumericLiteralFlags.Binary;
|
||||
case CharacterCodes.o:
|
||||
case CharacterCodes.O:
|
||||
return NumericLiteralFlags.Octal;
|
||||
case CharacterCodes.x:
|
||||
case CharacterCodes.X:
|
||||
return NumericLiteralFlags.Hexadecimal;
|
||||
}
|
||||
|
||||
if (hint & NumericLiteralFlags.Scientific) {
|
||||
for (let i = text.length - 1; i >= 0; i--) {
|
||||
switch (text.charCodeAt(i)) {
|
||||
case CharacterCodes.e:
|
||||
case CharacterCodes.E:
|
||||
return NumericLiteralFlags.Scientific;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NumericLiteralFlags.None;
|
||||
}
|
||||
|
||||
function getQuotedEscapedLiteralText(leftQuote: string, text: string, rightQuote: string) {
|
||||
return leftQuote + escapeNonAsciiCharacters(escapeString(text)) + rightQuote;
|
||||
}
|
||||
@ -398,11 +358,6 @@ namespace ts {
|
||||
return identifier.length >= 2 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ ? "_" + identifier : identifier;
|
||||
}
|
||||
|
||||
// Remove extra underscore from escaped identifier
|
||||
export function unescapeIdentifier(identifier: string): string {
|
||||
return identifier.length >= 3 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ && identifier.charCodeAt(2) === CharacterCodes._ ? identifier.substr(1) : identifier;
|
||||
}
|
||||
|
||||
// Make an identifier from an external module name by extracting the string after the last "/" and replacing
|
||||
// all non-alphanumeric characters with underscores
|
||||
export function makeIdentifierFromModuleName(moduleName: string): string {
|
||||
@ -424,7 +379,7 @@ namespace ts {
|
||||
((<ModuleDeclaration>node).name.kind === SyntaxKind.StringLiteral || isGlobalScopeAugmentation(<ModuleDeclaration>node));
|
||||
}
|
||||
|
||||
/** Given a symbol for a module, checks that it is either an untyped import or a shorthand ambient module. */
|
||||
/** Given a symbol for a module, checks that it is a shorthand ambient module. */
|
||||
export function isShorthandAmbientModuleSymbol(moduleSymbol: Symbol): boolean {
|
||||
return isShorthandAmbientModule(moduleSymbol.valueDeclaration);
|
||||
}
|
||||
@ -511,6 +466,10 @@ namespace ts {
|
||||
return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name);
|
||||
}
|
||||
|
||||
export function getNameFromIndexInfo(info: IndexInfo) {
|
||||
return info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : undefined;
|
||||
}
|
||||
|
||||
export function getTextOfPropertyName(name: PropertyName): string {
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
@ -726,8 +685,8 @@ namespace ts {
|
||||
//
|
||||
// let a: A.B.C;
|
||||
//
|
||||
// Calling isPartOfTypeNode would consider the qualified name A.B a type node. Only C or
|
||||
// A.B.C is a type node.
|
||||
// Calling isPartOfTypeNode would consider the qualified name A.B a type node.
|
||||
// Only C and A.B.C are type nodes.
|
||||
if (SyntaxKind.FirstTypeNode <= parent.kind && parent.kind <= SyntaxKind.LastTypeNode) {
|
||||
return true;
|
||||
}
|
||||
@ -950,7 +909,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function unwrapInnermostStatmentOfLabel(node: LabeledStatement, beforeUnwrapLabelCallback?: (node: LabeledStatement) => void) {
|
||||
export function unwrapInnermostStatementOfLabel(node: LabeledStatement, beforeUnwrapLabelCallback?: (node: LabeledStatement) => void) {
|
||||
while (true) {
|
||||
if (beforeUnwrapLabelCallback) {
|
||||
beforeUnwrapLabelCallback(node);
|
||||
@ -1077,13 +1036,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an super call/property node, returns the closest node where
|
||||
* - a super call/property access is legal in the node and not legal in the parent node the node.
|
||||
* i.e. super call is legal in constructor but not legal in the class body.
|
||||
* - the container is an arrow function (so caller might need to call getSuperContainer again in case it needs to climb higher)
|
||||
* - a super call/property is definitely illegal in the container (but might be legal in some subnode)
|
||||
* i.e. super property access is illegal in function declaration but can be legal in the statement list
|
||||
*/
|
||||
* Given an super call/property node, returns the closest node where
|
||||
* - a super call/property access is legal in the node and not legal in the parent node the node.
|
||||
* i.e. super call is legal in constructor but not legal in the class body.
|
||||
* - the container is an arrow function (so caller might need to call getSuperContainer again in case it needs to climb higher)
|
||||
* - a super call/property is definitely illegal in the container (but might be legal in some subnode)
|
||||
* i.e. super property access is illegal in function declaration but can be legal in the statement list
|
||||
*/
|
||||
export function getSuperContainer(node: Node, stopOnFunctions: boolean): Node {
|
||||
while (true) {
|
||||
node = node.parent;
|
||||
@ -1169,6 +1128,8 @@ namespace ts {
|
||||
|
||||
export function isCallLikeExpression(node: Node): node is CallLikeExpression {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
@ -1183,6 +1144,9 @@ namespace ts {
|
||||
if (node.kind === SyntaxKind.TaggedTemplateExpression) {
|
||||
return (<TaggedTemplateExpression>node).tag;
|
||||
}
|
||||
else if (isJsxOpeningLikeElement(node)) {
|
||||
return node.tagName;
|
||||
}
|
||||
|
||||
// Will either be a CallExpression, NewExpression, or Decorator.
|
||||
return (<CallExpression | Decorator>node).expression;
|
||||
@ -1381,17 +1345,24 @@ namespace ts {
|
||||
|
||||
/**
|
||||
* Returns true if the node is a CallExpression to the identifier 'require' with
|
||||
* exactly one argument.
|
||||
* exactly one argument (of the form 'require("name")').
|
||||
* This function does not test if the node is in a JavaScript file or not.
|
||||
*/
|
||||
export function isRequireCall(expression: Node, checkArgumentIsStringLiteral: boolean): expression is CallExpression {
|
||||
// of the form 'require("name")'
|
||||
const isRequire = expression.kind === SyntaxKind.CallExpression &&
|
||||
(<CallExpression>expression).expression.kind === SyntaxKind.Identifier &&
|
||||
(<Identifier>(<CallExpression>expression).expression).text === "require" &&
|
||||
(<CallExpression>expression).arguments.length === 1;
|
||||
*/
|
||||
export function isRequireCall(callExpression: Node, checkArgumentIsStringLiteral: boolean): callExpression is CallExpression {
|
||||
if (callExpression.kind !== SyntaxKind.CallExpression) {
|
||||
return false;
|
||||
}
|
||||
const { expression, arguments: args } = callExpression as CallExpression;
|
||||
|
||||
return isRequire && (!checkArgumentIsStringLiteral || (<CallExpression>expression).arguments[0].kind === SyntaxKind.StringLiteral);
|
||||
if (expression.kind !== SyntaxKind.Identifier || (expression as Identifier).text !== "require") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args.length !== 1) {
|
||||
return false;
|
||||
}
|
||||
const arg = args[0];
|
||||
return !checkArgumentIsStringLiteral || arg.kind === SyntaxKind.StringLiteral || arg.kind === SyntaxKind.NoSubstitutionTemplateLiteral;
|
||||
}
|
||||
|
||||
export function isSingleOrDoubleQuote(charCode: number) {
|
||||
@ -1402,23 +1373,35 @@ namespace ts {
|
||||
* Returns true if the node is a variable declaration whose initializer is a function expression.
|
||||
* This function does not test if the node is in a JavaScript file or not.
|
||||
*/
|
||||
export function isDeclarationOfFunctionExpression(s: Symbol) {
|
||||
export function isDeclarationOfFunctionOrClassExpression(s: Symbol) {
|
||||
if (s.valueDeclaration && s.valueDeclaration.kind === SyntaxKind.VariableDeclaration) {
|
||||
const declaration = s.valueDeclaration as VariableDeclaration;
|
||||
return declaration.initializer && declaration.initializer.kind === SyntaxKind.FunctionExpression;
|
||||
return declaration.initializer && (declaration.initializer.kind === SyntaxKind.FunctionExpression || declaration.initializer.kind === SyntaxKind.ClassExpression);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getRightMostAssignedExpression(node: Node) {
|
||||
while (isAssignmentExpression(node, /*excludeCompoundAssignements*/ true)) {
|
||||
node = node.right;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
export function isExportsIdentifier(node: Node) {
|
||||
return isIdentifier(node) && node.text === "exports";
|
||||
}
|
||||
|
||||
export function isModuleExportsPropertyAccessExpression(node: Node) {
|
||||
return isPropertyAccessExpression(node) && isIdentifier(node.expression) && node.expression.text === "module" && node.name.text === "exports";
|
||||
}
|
||||
|
||||
/// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
|
||||
/// assignments we treat as special in the binder
|
||||
export function getSpecialPropertyAssignmentKind(expression: Node): SpecialPropertyAssignmentKind {
|
||||
export function getSpecialPropertyAssignmentKind(expression: ts.BinaryExpression): SpecialPropertyAssignmentKind {
|
||||
if (!isInJavaScriptFile(expression)) {
|
||||
return SpecialPropertyAssignmentKind.None;
|
||||
}
|
||||
if (expression.kind !== SyntaxKind.BinaryExpression) {
|
||||
return SpecialPropertyAssignmentKind.None;
|
||||
}
|
||||
const expr = <BinaryExpression>expression;
|
||||
if (expr.operatorToken.kind !== SyntaxKind.EqualsToken || expr.left.kind !== SyntaxKind.PropertyAccessExpression) {
|
||||
return SpecialPropertyAssignmentKind.None;
|
||||
@ -1434,6 +1417,10 @@ namespace ts {
|
||||
// module.exports = expr
|
||||
return SpecialPropertyAssignmentKind.ModuleExports;
|
||||
}
|
||||
else {
|
||||
// F.x = expr
|
||||
return SpecialPropertyAssignmentKind.Property;
|
||||
}
|
||||
}
|
||||
else if (lhs.expression.kind === SyntaxKind.ThisKeyword) {
|
||||
return SpecialPropertyAssignmentKind.ThisProperty;
|
||||
@ -1453,6 +1440,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return SpecialPropertyAssignmentKind.None;
|
||||
}
|
||||
|
||||
@ -1534,7 +1522,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
result.push(...filter((doc as JSDoc).tags, tag => tag.kind === kind));
|
||||
const tags = (doc as JSDoc).tags;
|
||||
if (tags) {
|
||||
result.push(...filter(tags, tag => tag.kind === kind));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -1545,7 +1536,7 @@ namespace ts {
|
||||
return node && firstOrUndefined(getJSDocTags(node, kind));
|
||||
}
|
||||
|
||||
function getJSDocs(node: Node): (JSDoc | JSDocTag)[] {
|
||||
export function getJSDocs(node: Node): (JSDoc | JSDocTag)[] {
|
||||
let cache: (JSDoc | JSDocTag)[] = node.jsDocCache;
|
||||
if (!cache) {
|
||||
getJSDocsWorker(node);
|
||||
@ -1930,8 +1921,55 @@ namespace ts {
|
||||
return SyntaxKind.FirstTriviaToken <= token && token <= SyntaxKind.LastTriviaToken;
|
||||
}
|
||||
|
||||
export function isAsyncFunctionLike(node: Node): boolean {
|
||||
return isFunctionLike(node) && hasModifier(node, ModifierFlags.Async) && !isAccessor(node);
|
||||
export const enum FunctionFlags {
|
||||
Normal = 0,
|
||||
Generator = 1 << 0,
|
||||
Async = 1 << 1,
|
||||
AsyncOrAsyncGenerator = Async | Generator,
|
||||
Invalid = 1 << 2,
|
||||
InvalidAsyncOrAsyncGenerator = AsyncOrAsyncGenerator | Invalid,
|
||||
InvalidGenerator = Generator | Invalid,
|
||||
}
|
||||
|
||||
export function getFunctionFlags(node: FunctionLikeDeclaration) {
|
||||
let flags = FunctionFlags.Normal;
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
if (node.asteriskToken) {
|
||||
flags |= FunctionFlags.Generator;
|
||||
}
|
||||
// fall through
|
||||
case SyntaxKind.ArrowFunction:
|
||||
if (hasModifier(node, ModifierFlags.Async)) {
|
||||
flags |= FunctionFlags.Async;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!node.body) {
|
||||
flags |= FunctionFlags.Invalid;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
export function isAsyncFunction(node: Node): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
return (<FunctionLikeDeclaration>node).body !== undefined
|
||||
&& (<FunctionLikeDeclaration>node).asteriskToken === undefined
|
||||
&& hasModifier(node, ModifierFlags.Async);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isNumericLiteral(node: Node): node is NumericLiteral {
|
||||
return node.kind === SyntaxKind.NumericLiteral;
|
||||
}
|
||||
|
||||
export function isStringOrNumericLiteral(node: Node): node is StringLiteral | NumericLiteral {
|
||||
@ -2410,7 +2448,7 @@ namespace ts {
|
||||
return indentStrings[1].length;
|
||||
}
|
||||
|
||||
export function createTextWriter(newLine: String): EmitTextWriter {
|
||||
export function createTextWriter(newLine: string): EmitTextWriter {
|
||||
let output: string;
|
||||
let indent: number;
|
||||
let lineStart: boolean;
|
||||
@ -2590,7 +2628,7 @@ namespace ts {
|
||||
if (sourceFiles.length) {
|
||||
const jsFilePath = options.outFile || options.out;
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : undefined;
|
||||
const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : "";
|
||||
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles);
|
||||
}
|
||||
}
|
||||
@ -3063,6 +3101,15 @@ namespace ts {
|
||||
return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined;
|
||||
}
|
||||
|
||||
export function isExpressionWithTypeArgumentsInClassImplementsClause(node: Node): node is ExpressionWithTypeArguments {
|
||||
return node.kind === SyntaxKind.ExpressionWithTypeArguments
|
||||
&& isEntityNameExpression((node as ExpressionWithTypeArguments).expression)
|
||||
&& node.parent
|
||||
&& (<HeritageClause>node.parent).token === SyntaxKind.ImplementsKeyword
|
||||
&& node.parent.parent
|
||||
&& isClassLike(node.parent.parent);
|
||||
}
|
||||
|
||||
export function isEntityNameExpression(node: Expression): node is EntityNameExpression {
|
||||
return node.kind === SyntaxKind.Identifier ||
|
||||
node.kind === SyntaxKind.PropertyAccessExpression && isEntityNameExpression((<PropertyAccessExpression>node).expression);
|
||||
@ -3073,15 +3120,14 @@ namespace ts {
|
||||
(node.parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>node.parent).name === node);
|
||||
}
|
||||
|
||||
export function isEmptyObjectLiteralOrArrayLiteral(expression: Node): boolean {
|
||||
const kind = expression.kind;
|
||||
if (kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
return (<ObjectLiteralExpression>expression).properties.length === 0;
|
||||
}
|
||||
if (kind === SyntaxKind.ArrayLiteralExpression) {
|
||||
return (<ArrayLiteralExpression>expression).elements.length === 0;
|
||||
}
|
||||
return false;
|
||||
export function isEmptyObjectLiteral(expression: Node): boolean {
|
||||
return expression.kind === SyntaxKind.ObjectLiteralExpression &&
|
||||
(<ObjectLiteralExpression>expression).properties.length === 0;
|
||||
}
|
||||
|
||||
export function isEmptyArrayLiteral(expression: Node): boolean {
|
||||
return expression.kind === SyntaxKind.ArrayLiteralExpression &&
|
||||
(<ArrayLiteralExpression>expression).elements.length === 0;
|
||||
}
|
||||
|
||||
export function getLocalSymbolForExportDefault(symbol: Symbol) {
|
||||
@ -3620,10 +3666,14 @@ namespace ts {
|
||||
return (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode)
|
||||
|| kind === SyntaxKind.AnyKeyword
|
||||
|| kind === SyntaxKind.NumberKeyword
|
||||
|| kind === SyntaxKind.ObjectKeyword
|
||||
|| kind === SyntaxKind.BooleanKeyword
|
||||
|| kind === SyntaxKind.StringKeyword
|
||||
|| kind === SyntaxKind.SymbolKeyword
|
||||
|| kind === SyntaxKind.ThisKeyword
|
||||
|| kind === SyntaxKind.VoidKeyword
|
||||
|| kind === SyntaxKind.UndefinedKeyword
|
||||
|| kind === SyntaxKind.NullKeyword
|
||||
|| kind === SyntaxKind.NeverKeyword
|
||||
|| kind === SyntaxKind.ExpressionWithTypeArguments;
|
||||
}
|
||||
@ -3736,6 +3786,12 @@ namespace ts {
|
||||
return node.kind === SyntaxKind.PropertyAccessExpression;
|
||||
}
|
||||
|
||||
export function isPropertyAccessOrQualifiedName(node: Node): node is PropertyAccessExpression | QualifiedName {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.PropertyAccessExpression
|
||||
|| kind === SyntaxKind.QualifiedName;
|
||||
}
|
||||
|
||||
export function isElementAccessExpression(node: Node): node is ElementAccessExpression {
|
||||
return node.kind === SyntaxKind.ElementAccessExpression;
|
||||
}
|
||||
@ -3954,6 +4010,7 @@ namespace ts {
|
||||
|| kind === SyntaxKind.ImportEqualsDeclaration
|
||||
|| kind === SyntaxKind.ImportSpecifier
|
||||
|| kind === SyntaxKind.InterfaceDeclaration
|
||||
|| kind === SyntaxKind.JsxAttribute
|
||||
|| kind === SyntaxKind.MethodDeclaration
|
||||
|| kind === SyntaxKind.MethodSignature
|
||||
|| kind === SyntaxKind.ModuleDeclaration
|
||||
@ -4066,6 +4123,11 @@ namespace ts {
|
||||
|| kind === SyntaxKind.JsxText;
|
||||
}
|
||||
|
||||
export function isJsxAttributes(node: Node): node is JsxAttributes {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.JsxAttributes;
|
||||
}
|
||||
|
||||
export function isJsxAttributeLike(node: Node): node is JsxAttributeLike {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.JsxAttribute
|
||||
@ -4086,6 +4148,12 @@ namespace ts {
|
||||
|| kind === SyntaxKind.JsxExpression;
|
||||
}
|
||||
|
||||
export function isJsxOpeningLikeElement(node: Node): node is JsxOpeningLikeElement {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.JsxOpeningElement
|
||||
|| kind === SyntaxKind.JsxSelfClosingElement;
|
||||
}
|
||||
|
||||
// Clauses
|
||||
|
||||
export function isCaseOrDefaultClause(node: Node): node is CaseOrDefaultClause {
|
||||
@ -4140,7 +4208,6 @@ namespace ts {
|
||||
return "lib.es2016.d.ts";
|
||||
case ScriptTarget.ES2015:
|
||||
return "lib.es6.d.ts";
|
||||
|
||||
default:
|
||||
return "lib.d.ts";
|
||||
}
|
||||
@ -4432,9 +4499,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the locale is in the appropriate format,
|
||||
* and if it is, attempts to set the appropriate language.
|
||||
*/
|
||||
* Checks to see if the locale is in the appropriate format,
|
||||
* and if it is, attempts to set the appropriate language.
|
||||
*/
|
||||
export function validateLocaleAndSetLanguage(
|
||||
locale: string,
|
||||
sys: { getExecutingFilePath(): string, resolvePath(path: string): string, fileExists(fileName: string): boolean, readFile(fileName: string): string },
|
||||
@ -4536,7 +4603,7 @@ namespace ts {
|
||||
*/
|
||||
export function getParseTreeNode<T extends Node>(node: Node, nodeTest?: (node: Node) => node is T): T;
|
||||
export function getParseTreeNode(node: Node, nodeTest?: (node: Node) => boolean): Node {
|
||||
if (isParseTreeNode(node)) {
|
||||
if (node == undefined || isParseTreeNode(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -4548,4 +4615,14 @@ namespace ts {
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove extra underscore from escaped identifier text content.
|
||||
*
|
||||
* @param identifier The escaped identifier text.
|
||||
* @returns The unescaped identifier text.
|
||||
*/
|
||||
export function unescapeIdentifier(identifier: string): string {
|
||||
return identifier.length >= 3 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ && identifier.charCodeAt(2) === CharacterCodes._ ? identifier.substr(1) : identifier;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -51,7 +51,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
const path = ts.toPath(name, root, (fileName) => Harness.Compiler.getCanonicalFileName(fileName));
|
||||
const pathStart = ts.toPath(Harness.IO.getCurrentDirectory(), "", (fileName) => Harness.Compiler.getCanonicalFileName(fileName));
|
||||
return pathStart ? path.replace(pathStart, "/") : path;
|
||||
};
|
||||
}
|
||||
|
||||
public checkTestCodeOutput(fileName: string) {
|
||||
describe("compiler tests for " + fileName, () => {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
//
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -22,6 +22,10 @@
|
||||
namespace FourSlash {
|
||||
ts.disableIncrementalParsing = false;
|
||||
|
||||
function normalizeNewLines(s: string) {
|
||||
return s.replace(/\r\n/g, "\n");
|
||||
}
|
||||
|
||||
// Represents a parsed source file with metadata
|
||||
export interface FourSlashFile {
|
||||
// The contents of the file (with markers, etc stripped out)
|
||||
@ -585,7 +589,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
private getGoToDefinition(): ts.DefinitionInfo[] {
|
||||
return this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition)
|
||||
return this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
}
|
||||
|
||||
public verifyGoToType(arg0: any, endMarkerNames?: string | string[]) {
|
||||
@ -854,7 +858,7 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public verifyCompletionEntryDetails(entryName: string, expectedText: string, expectedDocumentation?: string, kind?: string) {
|
||||
public verifyCompletionEntryDetails(entryName: string, expectedText: string, expectedDocumentation?: string, kind?: string, tags?: ts.JSDocTagInfo[]) {
|
||||
const details = this.getCompletionEntryDetails(entryName);
|
||||
|
||||
assert(details, "no completion entry available");
|
||||
@ -868,6 +872,14 @@ namespace FourSlash {
|
||||
if (kind !== undefined) {
|
||||
assert.equal(details.kind, kind, this.assertionMessageAtLastKnownMarker("completion entry kind"));
|
||||
}
|
||||
|
||||
if (tags !== undefined) {
|
||||
assert.equal(details.tags.length, tags.length, this.messageAtLastKnownMarker("QuickInfo tags"));
|
||||
ts.zipWith(tags, details.tags, (expectedTag, actualTag) => {
|
||||
assert.equal(expectedTag.name, actualTag.name);
|
||||
assert.equal(expectedTag.text, actualTag.text, this.messageAtLastKnownMarker("QuickInfo tag " + actualTag.name));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public verifyReferencesAre(expectedReferences: Range[]) {
|
||||
@ -923,10 +935,13 @@ namespace FourSlash {
|
||||
this.assertObjectsEqual<ReferencesJson>(fullActual, fullExpected);
|
||||
}
|
||||
|
||||
function rangeToReferenceEntry(r: Range) {
|
||||
let { isWriteAccess, isDefinition } = (r.marker && r.marker.data) || { isWriteAccess: false, isDefinition: false };
|
||||
isWriteAccess = !!isWriteAccess; isDefinition = !!isDefinition;
|
||||
return { fileName: r.fileName, textSpan: { start: r.start, length: r.end - r.start }, isWriteAccess, isDefinition }
|
||||
function rangeToReferenceEntry(r: Range): ts.ReferenceEntry {
|
||||
const { isWriteAccess, isDefinition, isInString } = (r.marker && r.marker.data) || { isWriteAccess: false, isDefinition: false, isInString: undefined };
|
||||
const result: ts.ReferenceEntry = { fileName: r.fileName, textSpan: { start: r.start, length: r.end - r.start }, isWriteAccess: !!isWriteAccess, isDefinition: !!isDefinition };
|
||||
if (isInString !== undefined) {
|
||||
result.isInString = isInString;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1076,7 +1091,9 @@ namespace FourSlash {
|
||||
|
||||
public verifyQuickInfoDisplayParts(kind: string, kindModifiers: string, textSpan: { start: number; length: number; },
|
||||
displayParts: ts.SymbolDisplayPart[],
|
||||
documentation: ts.SymbolDisplayPart[]) {
|
||||
documentation: ts.SymbolDisplayPart[],
|
||||
tags: ts.JSDocTagInfo[]
|
||||
) {
|
||||
|
||||
const actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
assert.equal(actualQuickInfo.kind, kind, this.messageAtLastKnownMarker("QuickInfo kind"));
|
||||
@ -1084,6 +1101,11 @@ namespace FourSlash {
|
||||
assert.equal(JSON.stringify(actualQuickInfo.textSpan), JSON.stringify(textSpan), this.messageAtLastKnownMarker("QuickInfo textSpan"));
|
||||
assert.equal(TestState.getDisplayPartsJson(actualQuickInfo.displayParts), TestState.getDisplayPartsJson(displayParts), this.messageAtLastKnownMarker("QuickInfo displayParts"));
|
||||
assert.equal(TestState.getDisplayPartsJson(actualQuickInfo.documentation), TestState.getDisplayPartsJson(documentation), this.messageAtLastKnownMarker("QuickInfo documentation"));
|
||||
assert.equal(actualQuickInfo.tags.length, tags.length, this.messageAtLastKnownMarker("QuickInfo tags"));
|
||||
ts.zipWith(tags, actualQuickInfo.tags, (expectedTag, actualTag) => {
|
||||
assert.equal(expectedTag.name, actualTag.name);
|
||||
assert.equal(expectedTag.text, actualTag.text, this.messageAtLastKnownMarker("QuickInfo tag " + actualTag.name));
|
||||
});
|
||||
}
|
||||
|
||||
public verifyRenameLocations(findInStrings: boolean, findInComments: boolean, ranges?: Range[]) {
|
||||
@ -1177,6 +1199,16 @@ namespace FourSlash {
|
||||
assert.equal(ts.displayPartsToString(actualDocComment), docComment, this.assertionMessageAtLastKnownMarker("current signature help doc comment"));
|
||||
}
|
||||
|
||||
public verifyCurrentSignatureHelpTags(tags: ts.JSDocTagInfo[]) {
|
||||
const actualTags = this.getActiveSignatureHelpItem().tags;
|
||||
|
||||
assert.equal(actualTags.length, tags.length, this.assertionMessageAtLastKnownMarker("signature help tags"));
|
||||
ts.zipWith(tags, actualTags, (expectedTag, actualTag) => {
|
||||
assert.equal(expectedTag.name, actualTag.name);
|
||||
assert.equal(expectedTag.text, actualTag.text, this.assertionMessageAtLastKnownMarker("signature help tag " + actualTag.name));
|
||||
});
|
||||
}
|
||||
|
||||
public verifySignatureHelpCount(expected: number) {
|
||||
const help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition);
|
||||
const actual = help && help.items ? help.items.length : 0;
|
||||
@ -1662,7 +1694,7 @@ namespace FourSlash {
|
||||
if (ch === "\r") {
|
||||
this.currentCaretPosition--;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private applyEdits(fileName: string, edits: ts.TextChange[], isFormattingEdit = false): number {
|
||||
@ -1851,17 +1883,41 @@ namespace FourSlash {
|
||||
|
||||
const unsatisfiedRanges: Range[] = [];
|
||||
|
||||
const delayedErrors: string[] = [];
|
||||
for (const range of ranges) {
|
||||
const length = range.end - range.start;
|
||||
const matchingImpl = ts.find(implementations, impl =>
|
||||
range.fileName === impl.fileName && range.start === impl.textSpan.start && length === impl.textSpan.length);
|
||||
if (matchingImpl) {
|
||||
if (range.marker && range.marker.data) {
|
||||
const expected = <{ displayParts?: ts.SymbolDisplayPart[], parts: string[], kind?: string }>range.marker.data;
|
||||
if (expected.displayParts) {
|
||||
if (!ts.arrayIsEqualTo(expected.displayParts, matchingImpl.displayParts, displayPartIsEqualTo)) {
|
||||
delayedErrors.push(`Mismatched display parts: expected ${JSON.stringify(expected.displayParts)}, actual ${JSON.stringify(matchingImpl.displayParts)}`);
|
||||
}
|
||||
}
|
||||
else if (expected.parts) {
|
||||
const actualParts = matchingImpl.displayParts.map(p => p.text);
|
||||
if (!ts.arrayIsEqualTo(expected.parts, actualParts)) {
|
||||
delayedErrors.push(`Mismatched non-tagged display parts: expected ${JSON.stringify(expected.parts)}, actual ${JSON.stringify(actualParts)}`);
|
||||
}
|
||||
}
|
||||
if (expected.kind !== undefined) {
|
||||
if (expected.kind !== matchingImpl.kind) {
|
||||
delayedErrors.push(`Mismatched kind: expected ${JSON.stringify(expected.kind)}, actual ${JSON.stringify(matchingImpl.kind)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
matchingImpl.matched = true;
|
||||
}
|
||||
else {
|
||||
unsatisfiedRanges.push(range);
|
||||
}
|
||||
}
|
||||
if (delayedErrors.length) {
|
||||
this.raiseError(delayedErrors.join("\n"));
|
||||
}
|
||||
|
||||
const unmatchedImplementations = implementations.filter(impl => !impl.matched);
|
||||
if (unmatchedImplementations.length || unsatisfiedRanges.length) {
|
||||
@ -1886,6 +1942,10 @@ namespace FourSlash {
|
||||
function implementationsAreEqual(a: ImplementationLocationInformation, b: ImplementationLocationInformation) {
|
||||
return a.fileName === b.fileName && TestState.textSpansEqual(a.textSpan, b.textSpan);
|
||||
}
|
||||
|
||||
function displayPartIsEqualTo(a: ts.SymbolDisplayPart, b: ts.SymbolDisplayPart): boolean {
|
||||
return a.kind === b.kind && a.text === b.text;
|
||||
}
|
||||
}
|
||||
|
||||
public getMarkers(): Marker[] {
|
||||
@ -1958,8 +2018,7 @@ namespace FourSlash {
|
||||
|
||||
public verifyCurrentFileContent(text: string) {
|
||||
const actual = this.getFileContent(this.activeFile.fileName);
|
||||
const replaceNewlines = (str: string) => str.replace(/\r\n/g, "\n");
|
||||
if (replaceNewlines(actual) !== replaceNewlines(text)) {
|
||||
if (normalizeNewLines(actual) !== normalizeNewLines(text)) {
|
||||
throw new Error("verifyCurrentFileContent\n" +
|
||||
"\tExpected: \"" + text + "\"\n" +
|
||||
"\t Actual: \"" + actual + "\"");
|
||||
@ -2122,7 +2181,7 @@ namespace FourSlash {
|
||||
* Because codefixes are only applied on the working file, it is unsafe
|
||||
* to apply this more than once (consider a refactoring across files).
|
||||
*/
|
||||
public verifyRangeAfterCodeFix(expectedText: string, errorCode?: number, includeWhiteSpace?: boolean) {
|
||||
public verifyRangeAfterCodeFix(expectedText: string, includeWhiteSpace?: boolean, errorCode?: number, index?: number) {
|
||||
const ranges = this.getRanges();
|
||||
if (ranges.length !== 1) {
|
||||
this.raiseError("Exactly one range should be specified in the testfile.");
|
||||
@ -2130,13 +2189,13 @@ namespace FourSlash {
|
||||
|
||||
const fileName = this.activeFile.fileName;
|
||||
|
||||
this.applyCodeFixActions(fileName, this.getCodeFixActions(fileName, errorCode));
|
||||
this.applyCodeAction(fileName, this.getCodeFixActions(fileName, errorCode), index);
|
||||
|
||||
const actualText = this.rangeText(ranges[0]);
|
||||
|
||||
const result = includeWhiteSpace
|
||||
? actualText === expectedText
|
||||
: this.removeWhitespace(actualText) === this.removeWhitespace(expectedText)
|
||||
? normalizeNewLines(actualText) === normalizeNewLines(expectedText)
|
||||
: this.removeWhitespace(actualText) === this.removeWhitespace(expectedText);
|
||||
|
||||
if (!result) {
|
||||
this.raiseError(`Actual text doesn't match expected text. Actual:\n'${actualText}'\nExpected:\n'${expectedText}'`);
|
||||
@ -2146,7 +2205,7 @@ namespace FourSlash {
|
||||
/**
|
||||
* Applies fixes for the errors in fileName and compares the results to
|
||||
* expectedContents after all fixes have been applied.
|
||||
|
||||
*
|
||||
* Note: applying one codefix may generate another (eg: remove duplicate implements
|
||||
* may generate an extends -> interface conversion fix).
|
||||
* @param expectedContents The contents of the file after the fixes are applied.
|
||||
@ -2155,7 +2214,7 @@ namespace FourSlash {
|
||||
public verifyFileAfterCodeFix(expectedContents: string, fileName?: string) {
|
||||
fileName = fileName ? fileName : this.activeFile.fileName;
|
||||
|
||||
this.applyCodeFixActions(fileName, this.getCodeFixActions(fileName));
|
||||
this.applyCodeAction(fileName, this.getCodeFixActions(fileName));
|
||||
|
||||
const actualContents: string = this.getFileContent(fileName);
|
||||
if (this.removeWhitespace(actualContents) !== this.removeWhitespace(expectedContents)) {
|
||||
@ -2173,7 +2232,7 @@ namespace FourSlash {
|
||||
start: diagnostic.start,
|
||||
length: diagnostic.length,
|
||||
code: diagnostic.code
|
||||
}
|
||||
};
|
||||
});
|
||||
const dedupedDiagnositcs = ts.deduplicate(diagnosticsForCodeFix, ts.equalOwnProperties);
|
||||
|
||||
@ -2185,7 +2244,7 @@ namespace FourSlash {
|
||||
continue;
|
||||
}
|
||||
|
||||
const newActions = this.languageService.getCodeFixesAtPosition(fileName, diagnostic.start, diagnostic.length, [diagnostic.code]);
|
||||
const newActions = this.languageService.getCodeFixesAtPosition(fileName, diagnostic.start, diagnostic.length, [diagnostic.code], this.formatCodeSettings);
|
||||
if (newActions && newActions.length) {
|
||||
actions = actions ? actions.concat(newActions) : newActions;
|
||||
}
|
||||
@ -2193,12 +2252,20 @@ namespace FourSlash {
|
||||
return actions;
|
||||
}
|
||||
|
||||
private applyCodeFixActions(fileName: string, actions: ts.CodeAction[]): void {
|
||||
if (!(actions && actions.length === 1)) {
|
||||
this.raiseError(`Should find exactly one codefix, but ${actions ? actions.length : "none"} found.`);
|
||||
private applyCodeAction(fileName: string, actions: ts.CodeAction[], index?: number): void {
|
||||
if (index === undefined) {
|
||||
if (!(actions && actions.length === 1)) {
|
||||
this.raiseError(`Should find exactly one codefix, but ${actions ? actions.length : "none"} found.`);
|
||||
}
|
||||
index = 0;
|
||||
}
|
||||
else {
|
||||
if (!(actions && actions.length >= index + 1)) {
|
||||
this.raiseError(`Should find at least ${index + 1} codefix(es), but ${actions ? actions.length : "none"} found.`);
|
||||
}
|
||||
}
|
||||
|
||||
const fileChanges = ts.find(actions[0].changes, change => change.fileName === fileName);
|
||||
const fileChanges = ts.find(actions[index].changes, change => change.fileName === fileName);
|
||||
if (!fileChanges) {
|
||||
this.raiseError("The CodeFix found doesn't provide any changes in this file.");
|
||||
}
|
||||
@ -2240,22 +2307,22 @@ namespace FourSlash {
|
||||
|
||||
if (expected === undefined) {
|
||||
if (actual) {
|
||||
this.raiseError(name + " failed - expected no template but got {newText: \"" + actual.newText + "\" caretOffset: " + actual.caretOffset + "}");
|
||||
this.raiseError(`${name} failed - expected no template but got {newText: "${actual.newText}", caretOffset: ${actual.caretOffset}}`);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if (actual === undefined) {
|
||||
this.raiseError(name + " failed - expected the template {newText: \"" + actual.newText + "\" caretOffset: " + actual.caretOffset + "} but got nothing instead");
|
||||
this.raiseError(`${name} failed - expected the template {newText: "${expected.newText}", caretOffset: "${expected.caretOffset}"} but got nothing instead`);
|
||||
}
|
||||
|
||||
if (actual.newText !== expected.newText) {
|
||||
this.raiseError(name + " failed - expected insertion:\n" + this.clarifyNewlines(expected.newText) + "\nactual insertion:\n" + this.clarifyNewlines(actual.newText));
|
||||
this.raiseError(`${name} failed - expected insertion:\n"${this.clarifyNewlines(expected.newText)}"\nactual insertion:\n"${this.clarifyNewlines(actual.newText)}"`);
|
||||
}
|
||||
|
||||
if (actual.caretOffset !== expected.caretOffset) {
|
||||
this.raiseError(name + " failed - expected caretOffset: " + expected.caretOffset + ",\nactual caretOffset:" + actual.caretOffset);
|
||||
this.raiseError(`${name} failed - expected caretOffset: ${expected.caretOffset}\nactual caretOffset:${actual.caretOffset}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2542,6 +2609,11 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public printAvailableCodeFixes() {
|
||||
const codeFixes = this.getCodeFixActions(this.activeFile.fileName);
|
||||
Harness.IO.log(stringify(codeFixes));
|
||||
}
|
||||
|
||||
// Get the text of the entire line the caret is currently at
|
||||
private getCurrentLineContent() {
|
||||
const text = this.getFileContent(this.activeFile.fileName);
|
||||
@ -3119,7 +3191,7 @@ ${code}
|
||||
}
|
||||
|
||||
// Add the remaining text
|
||||
flush(undefined);
|
||||
flush(/*lastSafeCharIndex*/ undefined);
|
||||
|
||||
if (openRanges.length > 0) {
|
||||
const openRange = openRanges[0];
|
||||
@ -3467,6 +3539,10 @@ namespace FourSlashInterface {
|
||||
this.state.verifyCurrentSignatureHelpDocComment(docComment);
|
||||
}
|
||||
|
||||
public currentSignatureHelpTagsAre(tags: ts.JSDocTagInfo[]) {
|
||||
this.state.verifyCurrentSignatureHelpTags(tags);
|
||||
}
|
||||
|
||||
public signatureHelpCountIs(expected: number) {
|
||||
this.state.verifySignatureHelpCount(expected);
|
||||
}
|
||||
@ -3535,8 +3611,8 @@ namespace FourSlashInterface {
|
||||
this.DocCommentTemplate(/*expectedText*/ undefined, /*expectedOffset*/ undefined, /*empty*/ true);
|
||||
}
|
||||
|
||||
public rangeAfterCodeFix(expectedText: string, errorCode?: number, includeWhiteSpace?: boolean): void {
|
||||
this.state.verifyRangeAfterCodeFix(expectedText, errorCode, includeWhiteSpace);
|
||||
public rangeAfterCodeFix(expectedText: string, includeWhiteSpace?: boolean, errorCode?: number, index?: number): void {
|
||||
this.state.verifyRangeAfterCodeFix(expectedText, includeWhiteSpace, errorCode, index);
|
||||
}
|
||||
|
||||
public importFixAtPosition(expectedTextArray: string[], errorCode?: number): void {
|
||||
@ -3595,8 +3671,8 @@ namespace FourSlashInterface {
|
||||
this.state.verifyRangesWithSameTextAreDocumentHighlights();
|
||||
}
|
||||
|
||||
public completionEntryDetailIs(entryName: string, text: string, documentation?: string, kind?: string) {
|
||||
this.state.verifyCompletionEntryDetails(entryName, text, documentation, kind);
|
||||
public completionEntryDetailIs(entryName: string, text: string, documentation?: string, kind?: string, tags?: ts.JSDocTagInfo[]) {
|
||||
this.state.verifyCompletionEntryDetails(entryName, text, documentation, kind, tags);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3626,8 +3702,8 @@ namespace FourSlashInterface {
|
||||
}
|
||||
|
||||
public verifyQuickInfoDisplayParts(kind: string, kindModifiers: string, textSpan: { start: number; length: number; },
|
||||
displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[]) {
|
||||
this.state.verifyQuickInfoDisplayParts(kind, kindModifiers, textSpan, displayParts, documentation);
|
||||
displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[], tags: ts.JSDocTagInfo[]) {
|
||||
this.state.verifyQuickInfoDisplayParts(kind, kindModifiers, textSpan, displayParts, documentation, tags);
|
||||
}
|
||||
|
||||
public getSyntacticDiagnostics(expected: string) {
|
||||
@ -3711,11 +3787,11 @@ namespace FourSlashInterface {
|
||||
}
|
||||
|
||||
public printCurrentFileStateWithWhitespace() {
|
||||
this.state.printCurrentFileState(/*makeWhitespaceVisible*/true);
|
||||
this.state.printCurrentFileState(/*makeWhitespaceVisible*/ true);
|
||||
}
|
||||
|
||||
public printCurrentFileStateWithoutCaret() {
|
||||
this.state.printCurrentFileState(/*makeWhitespaceVisible*/false, /*makeCaretVisible*/false);
|
||||
this.state.printCurrentFileState(/*makeWhitespaceVisible*/ false, /*makeCaretVisible*/ false);
|
||||
}
|
||||
|
||||
public printCurrentQuickInfo() {
|
||||
@ -3730,6 +3806,10 @@ namespace FourSlashInterface {
|
||||
this.state.printCompletionListMembers();
|
||||
}
|
||||
|
||||
public printAvailableCodeFixes() {
|
||||
this.state.printAvailableCodeFixes();
|
||||
}
|
||||
|
||||
public printBreakpointLocation(pos: number) {
|
||||
this.state.printBreakpointLocation(pos);
|
||||
}
|
||||
|
||||
@ -34,17 +34,11 @@ var _chai: typeof chai = require("chai");
|
||||
var assert: typeof _chai.assert = _chai.assert;
|
||||
declare var __dirname: string; // Node-specific
|
||||
var global: NodeJS.Global = <any>Function("return this").call(undefined);
|
||||
declare namespace NodeJS {
|
||||
export interface Global {
|
||||
WScript: typeof WScript;
|
||||
ActiveXObject: typeof ActiveXObject;
|
||||
}
|
||||
}
|
||||
|
||||
declare var window: {};
|
||||
declare var XMLHttpRequest: {
|
||||
new(): XMLHttpRequest;
|
||||
}
|
||||
};
|
||||
interface XMLHttpRequest {
|
||||
readonly readyState: number;
|
||||
readonly responseText: string;
|
||||
@ -60,14 +54,10 @@ namespace Utils {
|
||||
export const enum ExecutionEnvironment {
|
||||
Node,
|
||||
Browser,
|
||||
CScript
|
||||
}
|
||||
|
||||
export function getExecutionEnvironment() {
|
||||
if (typeof WScript !== "undefined" && typeof ActiveXObject === "function") {
|
||||
return ExecutionEnvironment.CScript;
|
||||
}
|
||||
else if (typeof window !== "undefined") {
|
||||
if (typeof window !== "undefined") {
|
||||
return ExecutionEnvironment.Browser;
|
||||
}
|
||||
else {
|
||||
@ -93,7 +83,6 @@ namespace Utils {
|
||||
export function evalFile(fileContents: string, fileName: string, nodeContext?: any) {
|
||||
const environment = getExecutionEnvironment();
|
||||
switch (environment) {
|
||||
case ExecutionEnvironment.CScript:
|
||||
case ExecutionEnvironment.Browser:
|
||||
eval(fileContents);
|
||||
break;
|
||||
@ -202,7 +191,7 @@ namespace Utils {
|
||||
for (const childName in node) {
|
||||
if (childName === "parent" || childName === "nextContainer" || childName === "modifiers" || childName === "externalModuleIndicator" ||
|
||||
// for now ignore jsdoc comments
|
||||
childName === "jsDocComment") {
|
||||
childName === "jsDocComment" || childName === "checkJsDirective") {
|
||||
continue;
|
||||
}
|
||||
const child = (<any>node)[childName];
|
||||
@ -516,83 +505,6 @@ namespace Harness {
|
||||
export const virtualFileSystemRoot = "/";
|
||||
|
||||
namespace IOImpl {
|
||||
declare class Enumerator {
|
||||
public atEnd(): boolean;
|
||||
public moveNext(): boolean;
|
||||
public item(): any;
|
||||
constructor(o: any);
|
||||
}
|
||||
|
||||
export namespace CScript {
|
||||
let fso: any;
|
||||
if (global.ActiveXObject) {
|
||||
fso = new global.ActiveXObject("Scripting.FileSystemObject");
|
||||
}
|
||||
else {
|
||||
fso = {};
|
||||
}
|
||||
|
||||
export const args = () => ts.sys.args;
|
||||
export const getExecutingFilePath = () => ts.sys.getExecutingFilePath();
|
||||
export const exit = (exitCode: number) => ts.sys.exit(exitCode);
|
||||
export const resolvePath = (path: string) => ts.sys.resolvePath(path);
|
||||
export const getCurrentDirectory = () => ts.sys.getCurrentDirectory();
|
||||
export const newLine = () => harnessNewLine;
|
||||
export const useCaseSensitiveFileNames = () => ts.sys.useCaseSensitiveFileNames;
|
||||
|
||||
export const readFile: typeof IO.readFile = path => ts.sys.readFile(path);
|
||||
export const writeFile: typeof IO.writeFile = (path, content) => ts.sys.writeFile(path, content);
|
||||
export const directoryName: typeof IO.directoryName = fso.GetParentFolderName;
|
||||
export const getDirectories: typeof IO.getDirectories = dir => ts.sys.getDirectories(dir);
|
||||
export const directoryExists: typeof IO.directoryExists = fso.FolderExists;
|
||||
export const fileExists: typeof IO.fileExists = fso.FileExists;
|
||||
export const log: typeof IO.log = global.WScript && global.WScript.StdOut.WriteLine;
|
||||
export const getEnvironmentVariable: typeof IO.getEnvironmentVariable = name => ts.sys.getEnvironmentVariable(name);
|
||||
export const readDirectory: typeof IO.readDirectory = (path, extension, exclude, include) => ts.sys.readDirectory(path, extension, exclude, include);
|
||||
|
||||
export function createDirectory(path: string) {
|
||||
if (directoryExists(path)) {
|
||||
fso.CreateFolder(path);
|
||||
}
|
||||
}
|
||||
|
||||
export function deleteFile(path: string) {
|
||||
if (fileExists(path)) {
|
||||
fso.DeleteFile(path, true); // true: delete read-only files
|
||||
}
|
||||
}
|
||||
|
||||
export let listFiles: typeof IO.listFiles = (path, spec?, options?) => {
|
||||
options = options || <{ recursive?: boolean; }>{};
|
||||
function filesInFolder(folder: any, root: string): string[] {
|
||||
let paths: string[] = [];
|
||||
let fc: any;
|
||||
|
||||
if (options.recursive) {
|
||||
fc = new Enumerator(folder.subfolders);
|
||||
|
||||
for (; !fc.atEnd(); fc.moveNext()) {
|
||||
paths = paths.concat(filesInFolder(fc.item(), root + "\\" + fc.item().Name));
|
||||
}
|
||||
}
|
||||
|
||||
fc = new Enumerator(folder.files);
|
||||
|
||||
for (; !fc.atEnd(); fc.moveNext()) {
|
||||
if (!spec || fc.item().Name.match(spec)) {
|
||||
paths.push(root + "\\" + fc.item().Name);
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
const folder: any = fso.GetFolder(path);
|
||||
|
||||
return filesInFolder(folder, path);
|
||||
};
|
||||
}
|
||||
|
||||
export namespace Node {
|
||||
declare const require: any;
|
||||
let fs: any, pathModule: any;
|
||||
@ -840,16 +752,16 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
switch (Utils.getExecutionEnvironment()) {
|
||||
case Utils.ExecutionEnvironment.CScript:
|
||||
IO = IOImpl.CScript;
|
||||
break;
|
||||
const environment = Utils.getExecutionEnvironment();
|
||||
switch (environment) {
|
||||
case Utils.ExecutionEnvironment.Node:
|
||||
IO = IOImpl.Node;
|
||||
break;
|
||||
case Utils.ExecutionEnvironment.Browser:
|
||||
IO = IOImpl.Network;
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown value '${environment}' for ExecutionEnvironment.`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -873,7 +785,7 @@ namespace Harness {
|
||||
/** Aggregate various writes into a single array of lines. Useful for passing to the
|
||||
* TypeScript compiler to fill with source code or errors.
|
||||
*/
|
||||
export class WriterAggregator implements ITextWriter {
|
||||
export class WriterAggregator {
|
||||
public lines: string[] = [];
|
||||
public currentLine = <string>undefined;
|
||||
|
||||
@ -922,10 +834,15 @@ namespace Harness {
|
||||
export const defaultLibFileName = "lib.d.ts";
|
||||
export const es2015DefaultLibFileName = "lib.es2015.d.ts";
|
||||
|
||||
// Cache of lib files from "built/local"
|
||||
const libFileNameSourceFileMap = ts.createMapFromTemplate<ts.SourceFile>({
|
||||
[defaultLibFileName]: createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.es5.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest)
|
||||
});
|
||||
|
||||
// Cache of lib files from "tests/lib/"
|
||||
const testLibFileNameSourceFileMap = ts.createMap<ts.SourceFile>();
|
||||
const es6TestLibFileNameSourceFileMap = ts.createMap<ts.SourceFile>();
|
||||
|
||||
export function getDefaultLibrarySourceFile(fileName = defaultLibFileName): ts.SourceFile {
|
||||
if (!isDefaultLibraryFile(fileName)) {
|
||||
return undefined;
|
||||
@ -967,7 +884,8 @@ namespace Harness {
|
||||
useCaseSensitiveFileNames: boolean,
|
||||
// the currentDirectory is needed for rwcRunner to passed in specified current directory to compiler host
|
||||
currentDirectory: string,
|
||||
newLineKind?: ts.NewLineKind): ts.CompilerHost {
|
||||
newLineKind?: ts.NewLineKind,
|
||||
libFiles?: string): ts.CompilerHost {
|
||||
|
||||
// Local get canonical file name function, that depends on passed in parameter for useCaseSensitiveFileNames
|
||||
const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
@ -999,6 +917,24 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
if (libFiles) {
|
||||
// Because @libFiles don't change between execution. We would cache the result of the files and reuse it to speed help compilation
|
||||
for (const fileName of libFiles.split(",")) {
|
||||
const libFileName = "tests/lib/" + fileName;
|
||||
|
||||
if (scriptTarget <= ts.ScriptTarget.ES5) {
|
||||
if (!testLibFileNameSourceFileMap.get(libFileName)) {
|
||||
testLibFileNameSourceFileMap.set(libFileName, createSourceFileAndAssertInvariants(libFileName, IO.readFile(libFileName), scriptTarget));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!es6TestLibFileNameSourceFileMap.get(libFileName)) {
|
||||
es6TestLibFileNameSourceFileMap.set(libFileName, createSourceFileAndAssertInvariants(libFileName, IO.readFile(libFileName), scriptTarget));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getSourceFile(fileName: string) {
|
||||
fileName = ts.normalizePath(fileName);
|
||||
const fromFileMap = fileMap.get(toPath(fileName));
|
||||
@ -1010,6 +946,9 @@ namespace Harness {
|
||||
fourslashSourceFile = fourslashSourceFile || createSourceFileAndAssertInvariants(tsFn, Harness.IO.readFile(tsFn), scriptTarget);
|
||||
return fourslashSourceFile;
|
||||
}
|
||||
else if (ts.startsWith(fileName, "tests/lib/")) {
|
||||
return scriptTarget <= ts.ScriptTarget.ES5 ? testLibFileNameSourceFileMap.get(fileName) : es6TestLibFileNameSourceFileMap.get(fileName);
|
||||
}
|
||||
else {
|
||||
// Don't throw here -- the compiler might be looking for a test that actually doesn't exist as part of the TC
|
||||
// Return if it is other library file, otherwise return undefined
|
||||
@ -1221,7 +1160,8 @@ namespace Harness {
|
||||
if (options.libFiles) {
|
||||
for (const fileName of options.libFiles.split(",")) {
|
||||
const libFileName = "tests/lib/" + fileName;
|
||||
programFiles.push({ unitName: libFileName, content: normalizeLineEndings(IO.readFile(libFileName), Harness.IO.newLine()) });
|
||||
// Content is undefined here because in createCompilerHost we will create sourceFile for the lib file and cache the result
|
||||
programFiles.push({ unitName: libFileName, content: undefined });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1234,7 +1174,8 @@ namespace Harness {
|
||||
options.target,
|
||||
useCaseSensitiveFileNames,
|
||||
currentDirectory,
|
||||
options.newLine);
|
||||
options.newLine,
|
||||
options.libFiles);
|
||||
|
||||
let traceResults: string[];
|
||||
if (options.traceResolution) {
|
||||
@ -1856,7 +1797,7 @@ namespace Harness {
|
||||
if (currentFileContent === undefined) {
|
||||
currentFileContent = "";
|
||||
}
|
||||
else {
|
||||
else if (currentFileContent !== "") {
|
||||
// End-of-line
|
||||
currentFileContent = currentFileContent + "\n";
|
||||
}
|
||||
|
||||
@ -169,9 +169,9 @@ namespace Harness.LanguageService {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param line 0 based index
|
||||
* @param col 0 based index
|
||||
*/
|
||||
* @param line 0 based index
|
||||
* @param col 0 based index
|
||||
*/
|
||||
public positionToLineAndCharacter(fileName: string, position: number): ts.LineAndCharacter {
|
||||
const script: ScriptInfo = this.getScriptInfo(fileName);
|
||||
assert.isOk(script);
|
||||
@ -210,7 +210,7 @@ namespace Harness.LanguageService {
|
||||
}
|
||||
readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[] {
|
||||
return ts.matchFiles(path, extensions, exclude, include,
|
||||
/*useCaseSensitiveFileNames*/false,
|
||||
/*useCaseSensitiveFileNames*/ false,
|
||||
this.getCurrentDirectory(),
|
||||
(p) => this.virtualFileSystem.getAccessibleFileSystemEntries(p));
|
||||
}
|
||||
@ -779,7 +779,7 @@ namespace Harness.LanguageService {
|
||||
start: 0
|
||||
});
|
||||
return prev;
|
||||
}
|
||||
};
|
||||
return proxy;
|
||||
}
|
||||
}),
|
||||
@ -795,7 +795,7 @@ namespace Harness.LanguageService {
|
||||
|
||||
function makeDefaultProxy(info: ts.server.PluginCreateInfo) {
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
const proxy = Object.create(null);
|
||||
const proxy = Object.create(/*prototype*/ null);
|
||||
const langSvc: any = info.languageService;
|
||||
for (const k of Object.keys(langSvc)) {
|
||||
proxy[k] = function () {
|
||||
|
||||
@ -422,7 +422,7 @@ namespace Harness.SourceMapRecorder {
|
||||
const jsFileText = getTextOfLine(currentJsLine, jsLineMap, jsFile.code);
|
||||
if (prevEmittedCol < jsFileText.length) {
|
||||
// There is remaining text on this line that will be part of next source span so write marker that continues
|
||||
writeSourceMapMarker(undefined, spansOnSingleLine.length, /*endColumn*/ jsFileText.length, /*endContinues*/ true);
|
||||
writeSourceMapMarker(/*currentSpan*/ undefined, spansOnSingleLine.length, /*endColumn*/ jsFileText.length, /*endContinues*/ true);
|
||||
}
|
||||
|
||||
// Emit Source text
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
{
|
||||
{
|
||||
"extends": "../tsconfig-base",
|
||||
"compilerOptions": {
|
||||
"removeComments": false,
|
||||
@ -6,6 +6,10 @@
|
||||
"declaration": false,
|
||||
"types": [
|
||||
"node", "mocha", "chai"
|
||||
],
|
||||
"lib": [
|
||||
"es6",
|
||||
"scripthost"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
@ -77,8 +81,9 @@
|
||||
"../services/codefixes/helpers.ts",
|
||||
"../services/codefixes/importFixes.ts",
|
||||
"../services/codefixes/unusedIdentifierFixes.ts",
|
||||
"../services/harness.ts",
|
||||
"../services/codefixes/disableJsDiagnostics.ts",
|
||||
|
||||
"harness.ts",
|
||||
"sourceMapRecorder.ts",
|
||||
"harnessLanguageService.ts",
|
||||
"fourslash.ts",
|
||||
@ -91,7 +96,7 @@
|
||||
"rwcRunner.ts",
|
||||
"test262Runner.ts",
|
||||
"runner.ts",
|
||||
"../server/protocol.d.ts",
|
||||
"../server/protocol.ts",
|
||||
"../server/session.ts",
|
||||
"../server/client.ts",
|
||||
"../server/editorServices.ts",
|
||||
@ -119,6 +124,9 @@
|
||||
"./unittests/compileOnSave.ts",
|
||||
"./unittests/typingsInstaller.ts",
|
||||
"./unittests/projectErrors.ts",
|
||||
"./unittests/printer.ts"
|
||||
"./unittests/printer.ts",
|
||||
"./unittests/transform.ts",
|
||||
"./unittests/customTransforms.ts",
|
||||
"./unittests/textChanges.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
|
||||
namespace ts {
|
||||
interface File {
|
||||
@ -65,7 +65,7 @@ namespace ts {
|
||||
};
|
||||
|
||||
const projectService = new server.ProjectService(serverHost, logger, { isCancellationRequested: () => false }, /*useOneInferredProject*/ false, /*typingsInstaller*/ undefined);
|
||||
const rootScriptInfo = projectService.getOrCreateScriptInfo(rootFile, /* openedByClient */true, /*containingProject*/ undefined);
|
||||
const rootScriptInfo = projectService.getOrCreateScriptInfo(rootFile, /*openedByClient*/ true, /*containingProject*/ undefined);
|
||||
const project = projectService.createInferredProjectWithRootFileIfNecessary(rootScriptInfo);
|
||||
project.setCompilerOptions({ module: ts.ModuleKind.AMD } );
|
||||
return {
|
||||
@ -203,4 +203,4 @@ namespace ts {
|
||||
assert.isTrue(diags.length === 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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', 'es2017.string'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', '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', 'esnext.asynciterable'.",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@ -87,7 +87,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'",
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'.",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@ -113,7 +113,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'.",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@ -139,7 +139,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'.",
|
||||
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', 'esnext'",
|
||||
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,
|
||||
|
||||
@ -191,7 +191,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'.",
|
||||
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', 'es2017.string'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', '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', 'esnext.asynciterable'.",
|
||||
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', 'es2017.string'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', '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', 'esnext.asynciterable'.",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
|
||||
@ -496,7 +496,7 @@ namespace ts.projectSystem {
|
||||
const emitOutput = host.readFile(path + ".js");
|
||||
assert.equal(emitOutput, f.content + newLine, "content of emit output should be identical with the input + newline");
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
it("should emit specified file", () => {
|
||||
const file1 = {
|
||||
|
||||
@ -94,7 +94,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'",
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'.",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@ -122,7 +122,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'.",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@ -150,7 +150,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'.",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@ -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', 'esnext'",
|
||||
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
|
||||
}]
|
||||
@ -202,7 +202,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'.",
|
||||
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', 'es2017.string'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', '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', 'esnext.asynciterable'.",
|
||||
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', 'es2017.string'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', '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', 'esnext.asynciterable'.",
|
||||
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', 'es2017.string'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', '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', 'esnext.asynciterable'.",
|
||||
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', 'es2017.string'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', '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', 'esnext.asynciterable'.",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
|
||||
@ -22,7 +22,7 @@ namespace ts {
|
||||
});
|
||||
|
||||
it("Converts simple code snippet correctly", () => {
|
||||
runTest(`/// <reference path="file.ts" />
|
||||
runTest(`/// <reference path="file.ts" />
|
||||
var x: string = "string";
|
||||
console.log(x);`);
|
||||
});
|
||||
|
||||
86
src/harness/unittests/customTransforms.ts
Normal file
86
src/harness/unittests/customTransforms.ts
Normal file
@ -0,0 +1,86 @@
|
||||
/// <reference path="..\..\compiler\emitter.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
|
||||
namespace ts {
|
||||
describe("customTransforms", () => {
|
||||
function emitsCorrectly(name: string, sources: { file: string, text: string }[], customTransformers: CustomTransformers) {
|
||||
it(name, () => {
|
||||
const roots = sources.map(source => createSourceFile(source.file, source.text, ScriptTarget.ES2015));
|
||||
const fileMap = arrayToMap(roots, file => file.fileName);
|
||||
const outputs = createMap<string>();
|
||||
const options: CompilerOptions = {};
|
||||
const host: CompilerHost = {
|
||||
getSourceFile: (fileName) => fileMap.get(fileName),
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
getCurrentDirectory: () => "",
|
||||
getDirectories: () => [],
|
||||
getCanonicalFileName: (fileName) => fileName,
|
||||
useCaseSensitiveFileNames: () => true,
|
||||
getNewLine: () => "\n",
|
||||
fileExists: (fileName) => fileMap.has(fileName),
|
||||
readFile: (fileName) => fileMap.has(fileName) ? fileMap.get(fileName).text : undefined,
|
||||
writeFile: (fileName, text) => outputs.set(fileName, text),
|
||||
};
|
||||
|
||||
const program = createProgram(arrayFrom(fileMap.keys()), options, host);
|
||||
program.emit(/*targetSourceFile*/ undefined, host.writeFile, /*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ false, customTransformers);
|
||||
Harness.Baseline.runBaseline(`customTransforms/${name}.js`, () => {
|
||||
let content = "";
|
||||
for (const [file, text] of arrayFrom(outputs.entries())) {
|
||||
if (content) content += "\n\n";
|
||||
content += `// [${file}]\n`;
|
||||
content += text;
|
||||
}
|
||||
return content;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const sources = [{
|
||||
file: "source.ts",
|
||||
text: `
|
||||
function f1() { }
|
||||
class c() { }
|
||||
enum e { }
|
||||
// leading
|
||||
function f2() { } // trailing
|
||||
`
|
||||
}];
|
||||
|
||||
const before: TransformerFactory<SourceFile> = context => {
|
||||
return file => visitEachChild(file, visit, context);
|
||||
function visit(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
return visitFunction(<FunctionDeclaration>node);
|
||||
default:
|
||||
return visitEachChild(node, visit, context);
|
||||
}
|
||||
}
|
||||
function visitFunction(node: FunctionDeclaration) {
|
||||
addSyntheticLeadingComment(node, SyntaxKind.MultiLineCommentTrivia, "@before", /*hasTrailingNewLine*/ true);
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
const after: TransformerFactory<SourceFile> = context => {
|
||||
return file => visitEachChild(file, visit, context);
|
||||
function visit(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
return visitVariableStatement(<VariableStatement>node);
|
||||
default:
|
||||
return visitEachChild(node, visit, context);
|
||||
}
|
||||
}
|
||||
function visitVariableStatement(node: VariableStatement) {
|
||||
addSyntheticLeadingComment(node, SyntaxKind.SingleLineCommentTrivia, "@after");
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
emitsCorrectly("before", sources, { before: [before] });
|
||||
emitsCorrectly("after", sources, { after: [after] });
|
||||
emitsCorrectly("both", sources, { before: [before], after: [after] });
|
||||
});
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\..\compiler\commandLineParser.ts" />
|
||||
|
||||
namespace ts {
|
||||
@ -6,21 +6,11 @@ namespace ts {
|
||||
function initTSConfigCorrectly(name: string, commandLinesArgs: string[]) {
|
||||
describe(name, () => {
|
||||
const commandLine = parseCommandLine(commandLinesArgs);
|
||||
const initResult = generateTSConfig(commandLine.options, commandLine.fileNames);
|
||||
const initResult = generateTSConfig(commandLine.options, commandLine.fileNames, "\n");
|
||||
const outputFileName = `tsConfig/${name.replace(/[^a-z0-9\-. ]/ig, "")}/tsconfig.json`;
|
||||
|
||||
it(`Correct output for ${outputFileName}`, () => {
|
||||
Harness.Baseline.runBaseline(outputFileName, () => {
|
||||
if (initResult) {
|
||||
return JSON.stringify(initResult, undefined, 4);
|
||||
}
|
||||
else {
|
||||
// This can happen if compiler recieve invalid compiler-options
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
});
|
||||
Harness.Baseline.runBaseline(outputFileName, () => initResult);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -212,7 +212,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with missing files are excluded", () => {
|
||||
@ -231,7 +231,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with literal excludes", () => {
|
||||
@ -584,7 +584,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("always include literal files", () => {
|
||||
@ -728,7 +728,7 @@ namespace ts {
|
||||
"c:/dev/js": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("include .js files when allowJs=true", () => {
|
||||
@ -846,7 +846,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("include files with .. in their name", () => {
|
||||
@ -1087,7 +1087,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("in excludes", () => {
|
||||
@ -1108,7 +1108,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
});
|
||||
@ -1129,7 +1129,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("in excludes", () => {
|
||||
@ -1178,7 +1178,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
|
||||
@ -1198,7 +1198,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
|
||||
@ -1382,7 +1382,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
@ -144,18 +144,16 @@ namespace ts {
|
||||
|
||||
const resolution = nodeModuleNameResolver("b", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile, indexFile));
|
||||
|
||||
checkResolvedModule(resolution.resolvedModule, createResolvedModule(indexPath, /*isExternalLibraryImport*/true));
|
||||
checkResolvedModule(resolution.resolvedModule, createResolvedModule(indexPath, /*isExternalLibraryImport*/ true));
|
||||
}
|
||||
}
|
||||
|
||||
it("module name as directory - handle invalid 'typings'", () => {
|
||||
testTypingsIgnored(["a", "b"]);
|
||||
testTypingsIgnored({ "a": "b" });
|
||||
testTypingsIgnored(true);
|
||||
/* tslint:disable no-null-keyword */
|
||||
testTypingsIgnored(null);
|
||||
/* tslint:enable no-null-keyword */
|
||||
testTypingsIgnored(undefined);
|
||||
testTypingsIgnored(/*typings*/ true);
|
||||
testTypingsIgnored(/*typings*/ null); // tslint:disable-line no-null-keyword
|
||||
testTypingsIgnored(/*typings*/ undefined);
|
||||
});
|
||||
it("module name as directory - load index.d.ts", () => {
|
||||
test(/*hasDirectoryExists*/ false);
|
||||
@ -532,7 +530,7 @@ import b = require("./moduleB");
|
||||
check("m1", main, m1);
|
||||
check("m2", main, m2);
|
||||
check("m3", main, m3Typings);
|
||||
check("m4", main, m4, /*isExternalLibraryImport*/true);
|
||||
check("m4", main, m4, /*isExternalLibraryImport*/ true);
|
||||
|
||||
function check(name: string, caller: File, expected: File, isExternalLibraryImport = false) {
|
||||
const result = resolveModuleName(name, caller.name, options, host);
|
||||
|
||||
@ -9,7 +9,7 @@ namespace ts {
|
||||
Harness.Baseline.runBaseline(`printerApi/${prefix}.${name}.js`, () =>
|
||||
printCallback(createPrinter({ newLine: NewLineKind.CarriageReturnLineFeed, ...options })));
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
describe("printFile", () => {
|
||||
@ -45,10 +45,16 @@ namespace ts {
|
||||
|
||||
// comment9
|
||||
console.log(1 + 2);
|
||||
|
||||
// comment10
|
||||
function functionWithDefaultArgValue(argument: string = "defaultValue"): void { }
|
||||
`, ScriptTarget.ES2015);
|
||||
|
||||
printsCorrectly("default", {}, printer => printer.printFile(sourceFile));
|
||||
printsCorrectly("removeComments", { removeComments: true }, printer => printer.printFile(sourceFile));
|
||||
|
||||
// github #14948
|
||||
printsCorrectly("templateLiteral", {}, printer => printer.printFile(createSourceFile("source.ts", "let greeting = `Hi ${name}, how are you?`;", ScriptTarget.ES2017)));
|
||||
});
|
||||
|
||||
describe("printBundle", () => {
|
||||
@ -74,6 +80,7 @@ namespace ts {
|
||||
describe("printNode", () => {
|
||||
const printsCorrectly = makePrintsCorrectly("printsNodeCorrectly");
|
||||
const sourceFile = createSourceFile("source.ts", "", ScriptTarget.ES2015);
|
||||
// tslint:disable boolean-trivia
|
||||
const syntheticNode = createClassDeclaration(
|
||||
undefined,
|
||||
undefined,
|
||||
@ -91,6 +98,7 @@ namespace ts {
|
||||
)
|
||||
])
|
||||
);
|
||||
// tslint:enable boolean-trivia
|
||||
printsCorrectly("class", {}, printer => printer.printNode(EmitHint.Unspecified, syntheticNode, sourceFile));
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\..\harness\harnessLanguageService.ts" />
|
||||
|
||||
namespace ts {
|
||||
@ -323,7 +323,7 @@ namespace ts {
|
||||
|
||||
const program_1 = newProgram(files, ["a.ts"], options);
|
||||
checkResolvedModulesCache(program_1, "a.ts", createMapFromTemplate({ "b": createResolvedModule("b.ts") }));
|
||||
checkResolvedModulesCache(program_1, "b.ts", undefined);
|
||||
checkResolvedModulesCache(program_1, "b.ts", /*expectedContent*/ undefined);
|
||||
|
||||
const program_2 = updateProgram(program_1, ["a.ts"], options, files => {
|
||||
files[0].text = files[0].text.updateProgram("var x = 2");
|
||||
@ -332,14 +332,14 @@ namespace ts {
|
||||
|
||||
// content of resolution cache should not change
|
||||
checkResolvedModulesCache(program_1, "a.ts", createMapFromTemplate({ "b": createResolvedModule("b.ts") }));
|
||||
checkResolvedModulesCache(program_1, "b.ts", undefined);
|
||||
checkResolvedModulesCache(program_1, "b.ts", /*expectedContent*/ undefined);
|
||||
|
||||
// imports has changed - program is not reused
|
||||
const program_3 = updateProgram(program_2, ["a.ts"], options, files => {
|
||||
files[0].text = files[0].text.updateImportsAndExports("");
|
||||
});
|
||||
assert.isTrue(!program_2.structureIsReused);
|
||||
checkResolvedModulesCache(program_3, "a.ts", undefined);
|
||||
checkResolvedModulesCache(program_3, "a.ts", /*expectedContent*/ undefined);
|
||||
|
||||
const program_4 = updateProgram(program_3, ["a.ts"], options, files => {
|
||||
const newImports = `import x from 'b'
|
||||
@ -360,7 +360,7 @@ namespace ts {
|
||||
|
||||
const program_1 = newProgram(files, ["/a.ts"], options);
|
||||
checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMapFromTemplate({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }));
|
||||
checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", undefined);
|
||||
checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", /*expectedContent*/ undefined);
|
||||
|
||||
const program_2 = updateProgram(program_1, ["/a.ts"], options, files => {
|
||||
files[0].text = files[0].text.updateProgram("var x = 2");
|
||||
@ -369,7 +369,7 @@ namespace ts {
|
||||
|
||||
// content of resolution cache should not change
|
||||
checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMapFromTemplate({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }));
|
||||
checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", undefined);
|
||||
checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", /*expectedContent*/ undefined);
|
||||
|
||||
// type reference directives has changed - program is not reused
|
||||
const program_3 = updateProgram(program_2, ["/a.ts"], options, files => {
|
||||
@ -377,7 +377,7 @@ namespace ts {
|
||||
});
|
||||
|
||||
assert.isTrue(!program_2.structureIsReused);
|
||||
checkResolvedTypeDirectivesCache(program_3, "/a.ts", undefined);
|
||||
checkResolvedTypeDirectivesCache(program_3, "/a.ts", /*expectedContent*/ undefined);
|
||||
|
||||
updateProgram(program_3, ["/a.ts"], options, files => {
|
||||
const newReferences = `/// <reference types="typedefs"/>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/// <reference path="..\..\harnessLanguageService.ts" />
|
||||
/// <reference path="..\..\harnessLanguageService.ts" />
|
||||
|
||||
interface ClassificationEntry {
|
||||
value: any;
|
||||
|
||||
@ -1,80 +0,0 @@
|
||||
{ input: "function foo () {}", rules: [ ], span: { start: 0, length: 20 }, expected: "function foo() { }" },
|
||||
{ input: "var a = (0);\r\na = (1 % 2);\r\nvar b = new Array(1, 2);\r\nfunction c(d) {\r\n try { }\r\n catch (e) { }\r\n for (f = 0; f < 10; ++f) { }\r\n for (g in h) { }\r\n if (true) {\r\n } else if (false) { }\r\n switch (i) {\r\n case (0):\r\n break;\r\n }\r\n do { } while (true);\r\n with (j) {\r\n }\r\n delete (h);\r\n void (i);\r\n}", rules: [ "SpaceAfterOpenParen", "SpaceBeforeCloseParen", "NoSpaceBetweenParens" ], span: { start: 0, length: 349 }, expected: "var a = ( 0 );\r\na = ( 1 % 2 );\r\nvar b = new Array( 1, 2 );\r\nfunction c( d ) {\r\n try { }\r\n catch ( e ) { }\r\n for ( f = 0; f < 10; ++f ) { }\r\n for ( g in h ) { }\r\n if ( true ) {\r\n } else if ( false ) { }\r\n switch ( i ) {\r\n case ( 0 ):\r\n break;\r\n }\r\n do { } while ( true );\r\n with ( j ) {\r\n }\r\n delete ( h );\r\n void ( i );\r\n}" },
|
||||
{ input: "var a = ( 0 );\r\na = ( 1 % 2 );\r\nvar b = new Array( 1, 2 );\r\nfunction c( d ) {\r\n try { }\r\n catch ( e ) { }\r\n for ( f = 0; f < 10; ++f ) { }\r\n for ( g in h ) { }\r\n if ( true ) {\r\n } else if ( false ) { }\r\n switch ( i ) {\r\n case ( 0 ):\r\n break;\r\n }\r\n do { } while ( true );\r\n with ( j ) {\r\n }\r\n delete ( h );\r\n void ( i );\r\n}", rules: [ "NoSpaceAfterOpenParen", "NoSpaceBeforeCloseParen", "NoSpaceBetweenParens" ], span: { start: 0, length: 379 }, expected: "var a = (0);\r\na = (1 % 2);\r\nvar b = new Array(1, 2);\r\nfunction c(d) {\r\n try { }\r\n catch (e) { }\r\n for (f = 0; f < 10; ++f) { }\r\n for (g in h) { }\r\n if (true) {\r\n } else if (false) { }\r\n switch (i) {\r\n case (0):\r\n break;\r\n }\r\n do { } while (true);\r\n with (j) {\r\n }\r\n delete (h);\r\n void (i);\r\n}" },
|
||||
{ input: "this . alert( \"Hello, World!\" );", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 32 }, expected: "this.alert( \"Hello, World!\" );" },
|
||||
{ input: "a\r\n;b;", rules: [ ], span: { start: 0, length: 6 }, expected: "a\r\n; b;" },
|
||||
{ input: "a\r\n; b;", rules: [ ], span: { start: 0, length: 8 }, expected: "a\r\n; b;" },
|
||||
{ input: "var a , b;\r\nf(a , b);", rules: [ ], span: { start: 0, length: 40 }, expected: "var a, b;\r\nf(a, b);" },
|
||||
{ input: "function a() {\r\n while(false)\r\n switch(b) { }\r\n\r\n for(c in d)\r\n if(c)\r\n break;\r\n\r\n do { } while(true);\r\n with(f)\r\n g = null;\r\n}", rules: [ "SpaceAfterKeywordInControl" ], span: { start: 0, length: 171 }, expected: "function a() {\r\n while (false)\r\n switch (b) { }\r\n\r\n for (c in d)\r\n if (c)\r\n break;\r\n\r\n do { } while (true);\r\n with (f)\r\n g = null;\r\n}" },
|
||||
{ input: "function a() {\r\n while (false)\r\n switch (b) { }\r\n\r\n for (c in d)\r\n if (c)\r\n break;\r\n\r\n do { } while (true);\r\n with (f)\r\n g = null;\r\n}", rules: [ "NoSpaceAfterKeywordInControl" ], span: { start: 0, length: 177 }, expected: "function a() {\r\n while(false)\r\n switch(b) { }\r\n\r\n for(c in d)\r\n if(c)\r\n break;\r\n\r\n do { } while(true);\r\n with(f)\r\n g = null;\r\n}" },
|
||||
{ input: "{\r\n(a);\r\n}", rules: [ ], span: { start: 0, length: 10 }, expected: "{\r\n (a);\r\n}" },
|
||||
{ input: "var a=[1,2];\r\nvar b=8>>2 ;\r\nvar c=1+2;", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 14, length: 12 }, expected: "var a=[1,2];\r\nvar b = 8 >> 2;\r\nvar c=1+2;" },
|
||||
{ input: "if (true) {\r\n(a);\r\n}", rules: [ ], span: { start: 0, length: 20 }, expected: "if (true) {\r\n (a);\r\n}" },
|
||||
{ input: " // var a=[1,2];\r\n /*var a=[3,4];*/\r\n /*\r\n var a=[5,6];\r\n */", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 62 }, expected: "// var a=[1,2];\r\n/*var a=[3,4];*/\r\n/*\r\n var a=[5,6];\r\n */" },
|
||||
{ input: "f ();", rules: [ ], span: { start: 0, length: 14 }, expected: "f();" },
|
||||
{ input: "var a = { b: 1 , c: 2 };\r\nvar d = [1 , 2];", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 44 }, expected: "var a = { b: 1, c: 2 };\r\nvar d = [1, 2];" },
|
||||
{ input: "if (a)\r\n if (b)\r\n if (c)\r\n c();\r\n else\r\n b();\r\n else\r\n b();\r\nelse\r\n a();", rules: [ ], span: { start: 0, length: 124 }, expected: "if (a)\r\n if (b)\r\n if (c)\r\n c();\r\n else\r\n b();\r\n else\r\n b();\r\nelse\r\n a();" },
|
||||
{ input: "function a() { };", rules: [ ], span: { start: 0, length: 20 }, expected: "function a() { };" },
|
||||
{ input: "var a =[1.2,\"JavaScript\",true,{ x: 1,y: 3 }];\r\nvar b =[[1,2],[3,4]];\r\nvar c =[1,,,,5];\r\nvar d =[\r\n [1,2],\r\n [3,4]\r\n];", rules: [ "SpaceAfterComma" ], span: { start: 0, length: 123 }, expected: "var a =[1.2, \"JavaScript\", true, { x: 1, y: 3 }];\r\nvar b =[[1, 2], [3, 4]];\r\nvar c =[1, , , , 5];\r\nvar d =[\r\n [1, 2],\r\n [3, 4]\r\n];" },
|
||||
{ input: "var a =[1.2, \"JavaScript\", true, { x: 1, y: 3 }];\r\nvar b =[[1, 2], [3, 4]];\r\nvar c =[1, , , , 5];\r\nvar d =[\r\n [1, 2],\r\n [3, 4]\r\n];", rules: [ "NoSpaceAfterComma" ], span: { start: 0, length: 136 }, expected: "var a =[1.2,\"JavaScript\",true,{ x: 1,y: 3 }];\r\nvar b =[[1,2],[3,4]];\r\nvar c =[1,,,,5];\r\nvar d =[\r\n [1,2],\r\n [3,4]\r\n];" },
|
||||
{ input: "function a(b,c) { }\r\na(0,1);\r\nvar a =[,];\r\nvar a =[0,1];\r\nvar a,b,c = 0,d = 0;\r\nfor (var a = 0,b = 10; a < 10,b >= 0; ++a,--b) { }\r\nvar a = new ActiveXObject(\"\",\"\");\r\nswitch (a) {\r\n case 1,2,3:\r\n break;\r\n}", rules: [ "SpaceAfterComma" ], span: { start: 0, length: 215 }, expected: "function a(b, c) { }\r\na(0, 1);\r\nvar a =[, ];\r\nvar a =[0, 1];\r\nvar a, b, c = 0, d = 0;\r\nfor (var a = 0, b = 10; a < 10, b >= 0; ++a, --b) { }\r\nvar a = new ActiveXObject(\"\", \"\");\r\nswitch (a) {\r\n case 1, 2, 3:\r\n break;\r\n}" },
|
||||
{ input: "function a(b, c) { }\r\na(0, 1);\r\nvar a =[, ];\r\nvar a =[0, 1];\r\nvar a, b, c = 0, d = 0;\r\nfor (var a = 0, b = 10; a < 10, b >= 0; ++a, --b) { }\r\nvar a = new ActiveXObject(\"\", \"\");\r\nswitch (a) {\r\n case 1, 2, 3:\r\n break;\r\n}", rules: [ "NoSpaceAfterComma" ], span: { start: 0, length: 228 }, expected: "function a(b,c) { }\r\na(0,1);\r\nvar a =[,];\r\nvar a =[0,1];\r\nvar a,b,c = 0,d = 0;\r\nfor (var a = 0,b = 10; a < 10,b >= 0; ++a,--b) { }\r\nvar a = new ActiveXObject(\"\",\"\");\r\nswitch (a) {\r\n case 1,2,3:\r\n break;\r\n}" },
|
||||
{ input: "function Sum(a, b, c) {\r\nvar d = 1;\r\n}", rules: [ ], span: { start: 0, length: 38 }, expected: "function Sum(a, b, c) {\r\n var d = 1;\r\n}" },
|
||||
{ input: "(function() { })();\r\nvar a = function() { };\r\nvar a = { b: function() { } };", rules: [ "SpaceAfterAnonymousFunctionKeyword" ], span: { start: 0, length: 76 }, expected: "(function () { })();\r\nvar a = function () { };\r\nvar a = { b: function () { } };" },
|
||||
{ input: "(function () { })();\r\nvar a = function () { };\r\nvar a = { b: function () { } };", rules: [ "NoSpaceAfterAnonymousFunctionKeyword" ], span: { start: 0, length: 79 }, expected: "(function() { })();\r\nvar a = function() { };\r\nvar a = { b: function() { } };" },
|
||||
{ input: "function a() {\r\n}b;", rules: [ ], span: { start: 0, length: 19 }, expected: "function a() {\r\n} b;" },
|
||||
{ input: "function a() {\r\n} b;", rules: [ ], span: { start: 0, length: 21 }, expected: "function a() {\r\n} b;" },
|
||||
{ input: "function a(){return 0;}\r\nfunction b(){toString();return 0;}", rules: [ ], span: { start: 0, length: 59 }, expected: "function a() { return 0; }\r\nfunction b() { toString(); return 0; }" },
|
||||
{ input: "for (var i = 0;i < 10;++i) { }", rules: [ "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 30 }, expected: "for (var i = 0; i < 10; ++i) { }" },
|
||||
{ input: "for (var i = 0; i < 10; ++i) { }", rules: [ "NoSpaceAfterSemicolonInFor" ], span: { start: 0, length: 32 }, expected: "for (var i = 0;i < 10;++i) { }" },
|
||||
{ input: "function f() {\r\nif (1)\r\n{\r\nvar a=0;\r\n}\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl", "NewLineBeforeOpenCurlyInFunction" ], span: { start: 0, length: 41 }, expected: "function f()\n{\r\n if (1) {\r\n var a=0;\r\n }\r\n}" },
|
||||
{ input: "function a(b) {\r\n a({\r\n});\r\n}", rules: [ ], span: { start: 0, length: 32 }, expected: "function a(b) {\r\n a({\r\n });\r\n}" },
|
||||
{ input: "// var a=[1,2];\r\n/*\r\nvar a=[1,2];\r\n*/", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 3, length: 12 }, expected: "// var a=[1,2];\r\n/*\r\nvar a=[1,2];\r\n*/" },
|
||||
{ input: "// var a=[1,2];\r\n/*\r\nvar a=[1,2];\r\n*/", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 21, length: 12 }, expected: "// var a=[1,2];\r\n/*\r\nvar a=[1,2];\r\n*/" },
|
||||
{ input: "eval(\"var a=b[1,2+3];\");", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 6, length: 15 }, expected: "eval(\"var a=b[1,2+3];\");" },
|
||||
{ input: "0 + +1;\r\n0 + +a;\r\n0 + +(1);\r\n0 + +(+1);\r\n0 + +[1];\r\n0 + +[+1];\r\n0 + +this.a;\r\n0 + +new Number(+1);\r\n\r\n0 - -1;\r\n0 - -a;\r\n0 - -(1);\r\n0 - -(-1);\r\n0 - -[1];\r\n0 - -[-1];\r\n0 - -this.a;\r\n0 - -new Number(-1);\r\n\r\n0 + ~1;\r\n0 - ~a;\r\n0 + ~(1);\r\n0 - ~(~1);\r\n0 + ~[1];\r\n0 - ~[~1];\r\n0 + ~this.a;\r\n0 - ~new Number(~1);\r\n\r\n0 - !1;\r\n0 + !a;\r\n0 - !(1);\r\n0 + !(!1);\r\n0 - ![1];\r\n0 + ![!1];\r\n0 - !this.a;\r\n0 + !new Number(!1);", rules: [ "NoSpaceBeforeBinaryOperator", "NoSpaceAfterBinaryOperator" ], span: { start: 0, length: 404 }, expected: "0+ +1;\r\n0+ +a;\r\n0+ +(1);\r\n0+ +(+1);\r\n0+ +[1];\r\n0+ +[+1];\r\n0+ +this.a;\r\n0+ +new Number(+1);\r\n\r\n0- -1;\r\n0- -a;\r\n0- -(1);\r\n0- -(-1);\r\n0- -[1];\r\n0- -[-1];\r\n0- -this.a;\r\n0- -new Number(-1);\r\n\r\n0+~1;\r\n0-~a;\r\n0+~(1);\r\n0-~(~1);\r\n0+~[1];\r\n0-~[~1];\r\n0+~this.a;\r\n0-~new Number(~1);\r\n\r\n0-!1;\r\n0+!a;\r\n0-!(1);\r\n0+!(!1);\r\n0-![1];\r\n0+![!1];\r\n0-!this.a;\r\n0+!new Number(!1);" },
|
||||
{ input: "0+ +1;\r\n0+ +a;\r\n0+ +(1);\r\n0+ +(+1);\r\n0+ +[1];\r\n0+ +[+1];\r\n0+ +this.a;\r\n0+ +new Number(+1);\r\n\r\n0- -1;\r\n0- -a;\r\n0- -(1);\r\n0- -(-1);\r\n0- -[1];\r\n0- -[-1];\r\n0- -this.a;\r\n0- -new Number(-1);\r\n\r\n0+~1;\r\n0-~a;\r\n0+~(1);\r\n0-~(~1);\r\n0+~[1];\r\n0-~[~1];\r\n0+~this.a;\r\n0-~new Number(~1);\r\n\r\n0-!1;\r\n0+!a;\r\n0-!(1);\r\n0+!(!1);\r\n0-![1];\r\n0+![!1];\r\n0-!this.a;\r\n0+!new Number(!1);", rules: [ "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 356 }, expected: "0 + +1;\r\n0 + +a;\r\n0 + +(1);\r\n0 + +(+1);\r\n0 + +[1];\r\n0 + +[+1];\r\n0 + +this.a;\r\n0 + +new Number(+1);\r\n\r\n0 - -1;\r\n0 - -a;\r\n0 - -(1);\r\n0 - -(-1);\r\n0 - -[1];\r\n0 - -[-1];\r\n0 - -this.a;\r\n0 - -new Number(-1);\r\n\r\n0 + ~1;\r\n0 - ~a;\r\n0 + ~(1);\r\n0 - ~(~1);\r\n0 + ~[1];\r\n0 - ~[~1];\r\n0 + ~this.a;\r\n0 - ~new Number(~1);\r\n\r\n0 - !1;\r\n0 + !a;\r\n0 - !(1);\r\n0 + !(!1);\r\n0 - ![1];\r\n0 + ![!1];\r\n0 - !this.a;\r\n0 + !new Number(!1);" },
|
||||
{ input: "for (var a = 0; a < 2; ++a) {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl", "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 32 }, expected: "for (var a = 0; a < 2; ++a)\n{\r\n}" },
|
||||
{ input: "for (var a = 0; a < 2; ++a)\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl", "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 32 }, expected: "for (var a = 0; a < 2; ++a) {\r\n}" },
|
||||
{ input: "function foo(a, b, c) { a = b + c;\n}", rules: [ "NewLineBeforeOpenCurlyInFunction", "NewLineAfterOpenCurlyInBlockContext", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 36 }, expected: "function foo(a, b, c)\n{\n a = b + c;\n}" },
|
||||
{ input: "function a() {\r\n // comment\r\n}", rules: [ ], span: { start: 0, length: 33 }, expected: "function a() {\r\n // comment\r\n}" },
|
||||
{ input: "if (false) {\r\n} else if (true) {\r\n} else {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 45 }, expected: "if (false)\n{\r\n} else if (true)\n{\r\n} else\n{\r\n}" },
|
||||
{ input: "if (false)\n{\r\n} else if (true)\n{\r\n} else\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 45 }, expected: "if (false) {\r\n} else if (true) {\r\n} else {\r\n}" },
|
||||
{ input: "var a = (0);\r\nvar b = (1);\r\nvar c = (1 + 2);\r\nvar d = ((1 + 2)-(3 + 4));\r\n\r\nvar e = ( 0 );\r\nvar f = ( 1 );\r\nvar g = ( 1 + 2 );\r\nvar h = ( ( 1 + 2 ) - ( 3 + 4 ) );", rules: [ "SpaceAfterOpenParen", "SpaceBeforeCloseParen", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 162 }, expected: "var a = ( 0 );\r\nvar b = ( 1 );\r\nvar c = ( 1 + 2 );\r\nvar d = ( ( 1 + 2 ) - ( 3 + 4 ) );\r\n\r\nvar e = ( 0 );\r\nvar f = ( 1 );\r\nvar g = ( 1 + 2 );\r\nvar h = ( ( 1 + 2 ) - ( 3 + 4 ) );" },
|
||||
{ input: "eval(\"var a=b[1,2+3];\");", rules: [ "SpaceAfterComma", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 24 }, expected: "eval(\"var a=b[1,2+3];\");" },
|
||||
{ input: "for (a in b)\r\n\r\n{ i++; }\r\n\r\nfor (a in b)\r\n\r\n{\r\ni++; }", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 53 }, expected: "for (a in b)\r\n\r\n{ i++; }\r\n\r\nfor (a in b) {\r\n i++;\n}" },
|
||||
{ input: "for (a in b) {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 17 }, expected: "for (a in b)\n{\r\n}" },
|
||||
{ input: "for (a in b)\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 17 }, expected: "for (a in b) {\r\n}" },
|
||||
{ input: " var a = { } ; \r\nvar b = { c : d, e : { } };\r\n ", rules: [ "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 59 }, expected: "var a = {};\r\nvar b = { c: d, e: {} };\r\n" },
|
||||
{ input: "while (true) { }", rules: [ ], span: { start: 0, length: 19 }, expected: "while (true) { }" },
|
||||
{ input: "for (a in b){ i++; }\r\n\r\nfor (a in b){ i++; }", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 44 }, expected: "for (a in b) { i++; }\r\n\r\nfor (a in b) { i++; }" },
|
||||
{ input: "function a() {\r\n}", rules: [ "NewLineBeforeOpenCurlyInFunction" ], span: { start: 0, length: 17 }, expected: "function a()\n{\r\n}" },
|
||||
{ input: "function a()\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInFunction" ], span: { start: 0, length: 17 }, expected: "function a() {\r\n}" },
|
||||
{ input: "a;\r\nb;c;\r\nd;", rules: [ ], span: { start: 0, length: 12 }, expected: "a;\r\nb; c;\r\nd;" },
|
||||
{ input: "a;\r\nb; c;\r\nd;", rules: [ ], span: { start: 0, length: 14 }, expected: "a;\r\nb; c;\r\nd;" },
|
||||
{ input: " var a = 0;\r\n function b() {\r\n var c = 0;\r\n }", rules: [ "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 61 }, expected: "var a = 0;\r\nfunction b() {\r\n var c = 0;\r\n}" },
|
||||
{ input: "a;b;", rules: [ ], span: { start: 0, length: 4 }, expected: "a; b;" },
|
||||
{ input: "a; b;", rules: [ ], span: { start: 0, length: 6 }, expected: "a; b;" },
|
||||
{ input: "var a = (0);\r\nvar b = (1);\r\nvar c = (1 + 2);\r\nvar d = ((1 + 2)-(3 + 4));\r\n\r\nvar e = ( 0 );\r\nvar f = ( 1 );\r\nvar g = ( 1 + 2 );\r\nvar h = ( ( 1 + 2 ) - ( 3 + 4 ) );", rules: [ "NoSpaceAfterOpenParen", "NoSpaceBeforeCloseParen", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 162 }, expected: "var a = (0);\r\nvar b = (1);\r\nvar c = (1 + 2);\r\nvar d = ((1 + 2) - (3 + 4));\r\n\r\nvar e = (0);\r\nvar f = (1);\r\nvar g = (1 + 2);\r\nvar h = ((1 + 2) - (3 + 4));" },
|
||||
{ input: "function a() {\r\n(b);\r\n}", rules: [ ], span: { start: 0, length: 23 }, expected: "function a() {\r\n (b);\r\n}" },
|
||||
{ input: "function test(a) {\n var i;\n for (i = 0;i < 1; i++){ //select\n a++;//select\n }\n}", rules: [ "NewLineBeforeOpenCurlyInControl", "NewLineAfterOpenCurlyInBlockContext", "NewLineBeforeOpenCurlyInFunction", "SpaceAfterSemicolonInFor" ], span: { start: 30, length: 50 }, expected: "function test(a) {\n var i;\n for (i = 0; i < 1; i++)\n { //select\n a++;//select\n }\n}" },
|
||||
{ input: "function a(){ return 1; }", rules: [ "SpaceBeforeOpenCurlyInFunction" ], span: { start: 0, length: 25 }, expected: "function a() { return 1; }" },
|
||||
{ input: "do {\r\n} while (true);", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 21 }, expected: "do\n{\r\n} while (true);" },
|
||||
{ input: "do\n{\r\n} while (true);", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 21 }, expected: "do {\r\n} while (true);" },
|
||||
{ input: "for (;;) { a = b + c; b = 2;\n}", rules: [ "NewLineBeforeOpenCurlyInControl", "NewLineAfterOpenCurlyInBlockContext", "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator", "NoSpaceAfterSemicolonInFor" ], span: { start: 0, length: 30 }, expected: "for (;;)\n{\n a = b + c; b = 2;\n}" },
|
||||
{ input: "var a =0;\r\n\r\n+ 1;\r\n+ a;\r\n+ (1);\r\n+ (+ 1);\r\n+ [1];\r\n+ [+ 1];\r\n+ this.a;\r\n+ new Number(+ 1);\r\n\r\n- 1;\r\n- a;\r\n- (1);\r\n- (- 1);\r\n- [1];\r\n- [- 1];\r\n- this.a;\r\n- new Number(- 1);\r\n\r\n~ 1;\r\n~ a;\r\n~ (1);\r\n~ (~ 1);\r\n~ [1];\r\n~ [~ 1];\r\n~ this.a;\r\n~ new Number(~ 1);\r\n\r\n! 1;\r\n! a;\r\n! (1);\r\n! (! 1);\r\n! [1];\r\n! [! 1];\r\n! this.a;\r\n! new Number(! 1);\r\n\r\n++ a;\r\n++ (a);\r\n++ this.a;\r\n++ new f().a;\r\n\r\n-- a;\r\n-- (a);\r\n-- this.a;\r\n-- new f().a;\r\n\r\na ++;\r\n(a) ++;\r\nthis.a ++;\r\nnew f().a ++;\r\n\r\na --;\r\n(a) --;\r\nthis.a --;\r\nnew f().a --;", rules: [ ], span: { start: 0, length: 513 }, expected: "var a =0;\r\n\r\n+1;\r\n+a;\r\n+(1);\r\n+(+1);\r\n+[1];\r\n+[+1];\r\n+this.a;\r\n+new Number(+1);\r\n\r\n-1;\r\n-a;\r\n-(1);\r\n-(-1);\r\n-[1];\r\n-[-1];\r\n-this.a;\r\n-new Number(-1);\r\n\r\n~1;\r\n~a;\r\n~(1);\r\n~(~1);\r\n~[1];\r\n~[~1];\r\n~this.a;\r\n~new Number(~1);\r\n\r\n!1;\r\n!a;\r\n!(1);\r\n!(!1);\r\n![1];\r\n![!1];\r\n!this.a;\r\n!new Number(!1);\r\n\r\n++a;\r\n++(a);\r\n++this.a;\r\n++new f().a;\r\n\r\n--a;\r\n--(a);\r\n--this.a;\r\n--new f().a;\r\n\r\na++;\r\n(a)++;\r\nthis.a++;\r\nnew f().a++;\r\n\r\na--;\r\n(a)--;\r\nthis.a--;\r\nnew f().a--;" },
|
||||
{ input: "switch (a) {\r\n case 0:\r\n break;\r\n default:\r\n break;\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 74 }, expected: "switch (a)\n{\r\n case 0:\r\n break;\r\n default:\r\n break;\r\n}" },
|
||||
{ input: "switch (a)\n{\r\n case 0:\r\n break;\r\n default:\r\n break;\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 74 }, expected: "switch (a) {\r\n case 0:\r\n break;\r\n default:\r\n break;\r\n}" },
|
||||
{ input: "function a()\r\n\r\n\r\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInFunction" ], span: { start: 0, length: 22 }, expected: "function a() {\r\n}" },
|
||||
{ input: "try {\r\n} catch (e) {\r\n} finally {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 36 }, expected: "try\n{\r\n} catch (e)\n{\r\n} finally\n{\r\n}" },
|
||||
{ input: "try\n{\r\n} catch (e)\n{\r\n} finally\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 36 }, expected: "try {\r\n} catch (e) {\r\n} finally {\r\n}" },
|
||||
{ input: "with (a) {\r\n b = 0;\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 25 }, expected: "with (a)\n{\r\n b = 0;\r\n}" },
|
||||
{ input: "with (a)\n{\r\n b = 0;\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 25 }, expected: "with (a) {\r\n b = 0;\r\n}" },
|
||||
{ input: "var a=0+1-2*3/4%5;\r\na+=6;\r\na-=7;\r\na*=7;\r\na/=8;\r\na%=9;\r\na=+1- -2+ +3;\r\na=1.0+2.+.0;\r\n++a+a++;\r\n--a-a--;\r\n\r\nvar b=~1&2|3^4<<1>>1>>>2;\r\nb&=5;\r\nb^=6;\r\nb|=7;\r\nb<<=8;\r\nb>>=9;\r\nb>>>=10;\r\n\r\nvar c=a>b;\r\nc=b<a?a:b;\r\nc=true&&false||true;\r\nc=a==b;\r\nc=a===b;\r\nc=a!=b;\r\nc=a!==b;\r\nc=a<=b;\r\nc=a>=b;\r\nc=!c;\r\n\r\n++a+ ++a+a++ +a++ + ++a;\r\n--a- --a-a-- -a-- - --a;\r\n\r\nfunction d::e() { }", rules: [ "SpaceBeforeBinaryOperator", "SpaceAfterBinaryOperator" ], span: { start: 0, length: 366 }, expected: "var a = 0 + 1 - 2 * 3 / 4 % 5;\r\na += 6;\r\na -= 7;\r\na *= 7;\r\na /= 8;\r\na %= 9;\r\na = +1 - -2 + +3;\r\na = 1.0 + 2. + .0;\r\n++a + a++;\r\n--a - a--;\r\n\r\nvar b = ~1 & 2 | 3 ^ 4 << 1 >> 1 >>> 2;\r\nb &= 5;\r\nb ^= 6;\r\nb |= 7;\r\nb <<= 8;\r\nb >>= 9;\r\nb >>>= 10;\r\n\r\nvar c = a > b;\r\nc = b < a ? a : b;\r\nc = true && false || true;\r\nc = a == b;\r\nc = a === b;\r\nc = a != b;\r\nc = a !== b;\r\nc = a <= b;\r\nc = a >= b;\r\nc = !c;\r\n\r\n++a + ++a + a++ + a++ + ++a;\r\n--a - --a - a-- - a-- - --a;\r\n\r\nfunction d::e() { }" },
|
||||
{ input: "var a = 0 + 1 - 2 * 3 / 4 % 5;\r\na += 6;\r\na -= 7;\r\na *= 7;\r\na /= 8;\r\na %= 9;\r\na = +1 - -2 + +3;\r\na = 1.0 + 2. + .0;\r\n++a + a++;\r\n--a - a--;\r\n\r\nvar b = ~1 & 2 | 3 ^ 4 << 1 >> 1 >>> 2;\r\nb &= 5;\r\nb ^= 6;\r\nb |= 7;\r\nb <<= 8;\r\nb >>= 9;\r\nb >>>= 10;\r\n\r\nvar c = a > b;\r\nc = b < a ? a : b;\r\nc = true && false || true;\r\nc = a == b;\r\nc = a === b;\r\nc = a != b;\r\nc = a !== b;\r\nc = a <= b;\r\nc = a >= b;\r\nc = !c;\r\n\r\n++a + ++a + a++ + a++ + ++a;\r\n--a - --a - a-- - a-- - --a;\r\n\r\nfunction d::e() { }", rules: [ "NoSpaceBeforeBinaryOperator", "NoSpaceAfterBinaryOperator" ], span: { start: 0, length: 480 }, expected: "var a=0+1-2*3/4%5;\r\na+=6;\r\na-=7;\r\na*=7;\r\na/=8;\r\na%=9;\r\na=+1- -2+ +3;\r\na=1.0+2.+.0;\r\n++a+a++;\r\n--a-a--;\r\n\r\nvar b=~1&2|3^4<<1>>1>>>2;\r\nb&=5;\r\nb^=6;\r\nb|=7;\r\nb<<=8;\r\nb>>=9;\r\nb>>>=10;\r\n\r\nvar c=a>b;\r\nc=b<a?a:b;\r\nc=true&&false||true;\r\nc=a==b;\r\nc=a===b;\r\nc=a!=b;\r\nc=a!==b;\r\nc=a<=b;\r\nc=a>=b;\r\nc=!c;\r\n\r\n++a+ ++a+a++ +a++ + ++a;\r\n--a- --a-a-- -a-- - --a;\r\n\r\nfunction d::e() { }" },
|
||||
{ input: "function foo()\n\n{ a = 1\n}", rules: [ "NewLineBeforeOpenCurlyInFunction" ], span: { start: 0, length: 25 }, expected: "function foo()\n{\n a = 1\n}" },
|
||||
{ input: "while (true) {\r\n}", rules: [ "NewLineBeforeOpenCurlyInControl" ], span: { start: 0, length: 17 }, expected: "while (true)\n{\r\n}" },
|
||||
{ input: "while (true)\n{\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl" ], span: { start: 0, length: 17 }, expected: "while (true) {\r\n}" },
|
||||
{ input: "var z = 1;\r\n for (i = 0; i < 10; i++)\r\n for (j = 0; j < 10; j++)\r\nfor (k = 0; k < 10; ++k)\r\n{\r\nz++;\r\n}", rules: [ "SpaceBeforeOpenCurlyInControl", "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 117 }, expected: "var z = 1;\r\nfor (i = 0; i < 10; i++)\r\n for (j = 0; j < 10; j++)\r\n for (k = 0; k < 10; ++k) {\r\n z++;\r\n }" },
|
||||
{ input: "a++;b++;\nfor (; ; ) {\nx++;m++;\n}", rules: [ "SpaceAfterSemicolonInFor" ], span: { start: 0, length: 32 }, expected: "a++; b++;\nfor (; ; ) {\n x++; m++;\n}" },
|
||||
{ input: "var a;\r\n $(document).ready(function() {\r\n alert('hello');\r\n});\r\n", rules: [ ], span: { start: 0, length: 117 }, expected: "var a;\r\n$(document).ready(function () {\r\n alert('hello');\r\n});\r\n" }
|
||||
@ -1,66 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
.code
|
||||
{
|
||||
font-family: Lucida Console;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
table
|
||||
{
|
||||
border: solid black 1px;
|
||||
margin-bottom: 2em;
|
||||
background: #F5F5F5;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
th
|
||||
{
|
||||
text-align: left;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
td
|
||||
{
|
||||
vertical-align: top;
|
||||
padding: 0.75em;
|
||||
margin: 0.25em;
|
||||
}
|
||||
|
||||
td.test-input
|
||||
{
|
||||
background: #DDE;
|
||||
}
|
||||
|
||||
td.test-output
|
||||
{
|
||||
background: #FEE;
|
||||
}
|
||||
|
||||
td.test-expected
|
||||
{
|
||||
background: #EFE;
|
||||
}
|
||||
|
||||
td.test-operation
|
||||
{
|
||||
font-family: inherit;
|
||||
padding: 0.1em;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
function copy(code) {
|
||||
if (window.clipboardData) {
|
||||
window.clipboardData.setData('Text', decodeURIComponent(code));
|
||||
} else {
|
||||
alert(code);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -1,88 +0,0 @@
|
||||
///<reference path='_project.ts'/>
|
||||
|
||||
describe('getFormattingEditsForRange', function() {
|
||||
//
|
||||
// Verify that formatting the typescript file "sourceFileName" results in the
|
||||
// baseline file "baselineFileName".
|
||||
//
|
||||
function getFormattingEditsForRange(sourceFileName: string) {
|
||||
var baselineFileName = "tests/cases/unittests/services/testCode/formatting/" + sourceFileName + "BaseLine.ts";
|
||||
sourceFileName = "tests/cases/unittests/services/testCode/formatting/" + sourceFileName + ".ts";
|
||||
|
||||
var typescriptLS = new Harness.TypeScriptLS();
|
||||
typescriptLS.addDefaultLibrary();
|
||||
typescriptLS.addFile(sourceFileName);
|
||||
|
||||
var ls = typescriptLS.getLanguageService();
|
||||
var script = ls.languageService.getScriptAST(sourceFileName);
|
||||
assert.notNull(script);
|
||||
|
||||
var edits = ls.languageService.getFormattingEditsForRange(sourceFileName, 0, script.limChar, new Services.FormatCodeOptions());
|
||||
typescriptLS.checkEdits(sourceFileName, baselineFileName, edits);
|
||||
}
|
||||
|
||||
describe('test cases for formatting engine', function() {
|
||||
it("formats typescript constructs properly", function() {
|
||||
getFormattingEditsForRange('typescriptConstructs');
|
||||
});
|
||||
it("formats document ready function properly", function() {
|
||||
getFormattingEditsForRange('documentReadyFunction');
|
||||
});
|
||||
it("formats on closing bracket properly", function() {
|
||||
getFormattingEditsForRange('onClosingBracket');
|
||||
});
|
||||
it("formats various javascript constructs", function() {
|
||||
getFormattingEditsForRange('various');
|
||||
});
|
||||
it("formats main javascript program", function() {
|
||||
getFormattingEditsForRange('main');
|
||||
});
|
||||
it("formats on semicolon properly", function() {
|
||||
getFormattingEditsForRange('onSemiColon');
|
||||
});
|
||||
it("formats enum with trailling tab characters properly", function() {
|
||||
getFormattingEditsForRange('tabAfterCloseCurly');
|
||||
});
|
||||
it("formats object literal", function() {
|
||||
getFormattingEditsForRange('objectLiteral');
|
||||
});
|
||||
it("formats with statements", function() {
|
||||
getFormattingEditsForRange('withStatement');
|
||||
});
|
||||
it("formats ':' and '?' in parameters", function() {
|
||||
getFormattingEditsForRange('colonAndQMark');
|
||||
});
|
||||
it("formats 'import' declaration", function() {
|
||||
getFormattingEditsForRange('importDeclaration');
|
||||
});
|
||||
it("formats exported class with implicit module", function() {
|
||||
//TODO: this is to force generation of implicit module in AST
|
||||
var svGenTarget = TypeScript.moduleGenTarget;
|
||||
try {
|
||||
TypeScript.moduleGenTarget = TypeScript.ModuleGenTarget.Asynchronous;
|
||||
getFormattingEditsForRange('implicitModule');
|
||||
}
|
||||
finally {
|
||||
TypeScript.moduleGenTarget = svGenTarget;
|
||||
}
|
||||
});
|
||||
it("formats constructor statements correctelly", function() {
|
||||
getFormattingEditsForRange('spaceAfterConstructor');
|
||||
});
|
||||
it("formats classes and interfaces correctelly", function() {
|
||||
getFormattingEditsForRange('classes');
|
||||
});
|
||||
it("formats modules correctly", function() {
|
||||
getFormattingEditsForRange('modules');
|
||||
});
|
||||
it("formats fat arrow expressions correctelly", function() {
|
||||
getFormattingEditsForRange('fatArrowFunctions');
|
||||
});
|
||||
it("formats empty object/interface literals correctelly", function() {
|
||||
getFormattingEditsForRange('emptyInterfaceLiteral');
|
||||
});
|
||||
it("formats variable declaration lists", function() {
|
||||
getFormattingEditsForRange('formatVariableDeclarationList');
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,410 +0,0 @@
|
||||
///<reference path='_project.ts'/>
|
||||
|
||||
describe('getSmartIndentAtLineNumber', function() {
|
||||
var typescriptLS = new Harness.TypeScriptLS();
|
||||
|
||||
typescriptLS.addDefaultLibrary();
|
||||
|
||||
var fileName = 'tests/cases/unittests/services/testCode/getSmartIndentAtLineNumber.ts';
|
||||
var fileName2 = 'tests/cases/unittests/services/testCode/getSmartIndentAtLineNumber2.ts';
|
||||
var fileName3 = 'tests/cases/unittests/services/testCode/getSmartIndentAtLineNumber3.ts';
|
||||
|
||||
typescriptLS.addFile(fileName);
|
||||
typescriptLS.addFile(fileName2);
|
||||
typescriptLS.addFile(fileName3);
|
||||
|
||||
var ls = typescriptLS.getLanguageService();
|
||||
|
||||
//
|
||||
// line is 1-based
|
||||
//
|
||||
function getSmartIndent(fileName: string, line: number): number {
|
||||
assert.is(line >= 1);
|
||||
var options = new Services.EditorOptions();
|
||||
var position = typescriptLS.lineColToPosition(fileName, line, 1);
|
||||
return ls.languageService.getSmartIndentAtLineNumber(fileName, position, options);
|
||||
}
|
||||
|
||||
describe("test cases for smart indent", function() {
|
||||
|
||||
it("smart indent inside module", function() {
|
||||
var result = getSmartIndent(fileName, 2);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
it("smart indent inside class", function() {
|
||||
var result = getSmartIndent(fileName, 4);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after property in class", function() {
|
||||
var result = getSmartIndent(fileName, 6);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent inside method in class ", function() {
|
||||
var result = getSmartIndent(fileName, 9);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(12, result);
|
||||
});
|
||||
|
||||
it("smart indent after after method in class", function() {
|
||||
var result = getSmartIndent(fileName, 12);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after class", function() {
|
||||
var result = getSmartIndent(fileName, 17);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
it("smart indent in interface", function() {
|
||||
var result = getSmartIndent(fileName, 19);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after property in interface", function() {
|
||||
var result = getSmartIndent(fileName, 21);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after method in interface", function() {
|
||||
var result = getSmartIndent(fileName, 23);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after interface", function() {
|
||||
var result = getSmartIndent(fileName, 25);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
it("smart indent in nested module", function() {
|
||||
var result = getSmartIndent(fileName, 27);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after function in nested module", function() {
|
||||
var result = getSmartIndent(fileName, 30);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after variable in nested module", function() {
|
||||
var result = getSmartIndent(fileName, 32);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after nested module", function() {
|
||||
var result = getSmartIndent(fileName, 34);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
it("smart indent in enum", function() {
|
||||
var result = getSmartIndent(fileName, 36);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after variable in enum", function() {
|
||||
var result = getSmartIndent(fileName, 38);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after 2nd variable in enum", function() {
|
||||
var result = getSmartIndent(fileName, 40);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after enum", function() {
|
||||
var result = getSmartIndent(fileName, 42);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
it("smart indent after module", function() {
|
||||
var result = getSmartIndent(fileName, 44);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(0, result);
|
||||
});
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
it("smart indent after an aligned function argument", function() {
|
||||
var result = getSmartIndent(fileName, 47);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(13, result);
|
||||
});
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
it("smart indent inside a 'for' statement", function() {
|
||||
var result = getSmartIndent(fileName, 53);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after a 'for' statement", function() {
|
||||
var result = getSmartIndent(fileName, 55);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
it("smart indent inside a 'for in' statement", function() {
|
||||
var result = getSmartIndent(fileName, 57);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after a 'for in' statement", function() {
|
||||
var result = getSmartIndent(fileName, 59);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
it("smart indent inside a 'with' statement", function() {
|
||||
var result = getSmartIndent(fileName, 61);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after a 'with' statement", function() {
|
||||
var result = getSmartIndent(fileName, 63);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
it("smart indent inside a 'switch' statement", function() {
|
||||
var result = getSmartIndent(fileName, 65);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after a 'switch' statement", function() {
|
||||
var result = getSmartIndent(fileName, 67);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
it("smart indent inside a 'break' statement", function() {
|
||||
var result = getSmartIndent(fileName, 69);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after a 'break' statement", function() {
|
||||
var result = getSmartIndent(fileName, 71);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(12, result);
|
||||
});
|
||||
|
||||
it("smart indent after a 'break' statement", function() {
|
||||
var result = getSmartIndent(fileName, 73);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after last 'switch' statement", function() {
|
||||
var result = getSmartIndent(fileName, 75);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
it("smart indent before 'try' in 'try/catch' statement", function() {
|
||||
var result = getSmartIndent(fileName, 79);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
it("smart indent insde 'try' in 'try/catch' statement", function() {
|
||||
var result = getSmartIndent(fileName, 81);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent before 'catch' in 'try/catch' statement", function() {
|
||||
var result = getSmartIndent(fileName, 83);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
it("smart indent inside 'catch' in 'try/catch' statement", function() {
|
||||
var result = getSmartIndent(fileName, 85);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after 'catch' in 'try/catch' statement", function() {
|
||||
var result = getSmartIndent(fileName, 87);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
it("smart indent before 'try' in 'try/finally' statement", function() {
|
||||
var result = getSmartIndent(fileName, 92);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
it("smart indent insde 'try' in 'try/finally' statement", function() {
|
||||
var result = getSmartIndent(fileName, 94);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent before 'finally' in 'try/finally' statement", function() {
|
||||
var result = getSmartIndent(fileName, 96);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
it("smart indent inside 'finally' in 'try/finally' statement", function() {
|
||||
var result = getSmartIndent(fileName, 98);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after 'finally' in 'try/finally' statement", function() {
|
||||
var result = getSmartIndent(fileName, 100);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
it("smart indent before 'try' in 'try/catch/finally' statement", function() {
|
||||
var result = getSmartIndent(fileName, 104);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
it("smart indent insde 'try' in 'try/catch/finally' statement", function() {
|
||||
var result = getSmartIndent(fileName, 106);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent before 'catch' in 'try/catch/finally' statement", function() {
|
||||
var result = getSmartIndent(fileName, 108);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
it("smart indent inside 'catch' in 'try/catch/finally' statement", function() {
|
||||
var result = getSmartIndent(fileName, 110);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent before 'finally' in 'try/catch/finally' statement", function() {
|
||||
var result = getSmartIndent(fileName, 112);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
it("smart indent inside 'finally' in 'try/catch/finally' statement", function() {
|
||||
var result = getSmartIndent(fileName, 114);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(8, result);
|
||||
});
|
||||
|
||||
it("smart indent after 'finally' in 'try/catch/finally' statement", function() {
|
||||
var result = getSmartIndent(fileName, 116);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
it("smart indent inside a block inside case", function() {
|
||||
var result = getSmartIndent(fileName, 127);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(20, result);
|
||||
});
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
it("smart indent works for a non terminated argument list at the end of a file", function() {
|
||||
var result = getSmartIndent(fileName2, 8);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
it("smart indent works for a non terminated if statement at the end of a file", function() {
|
||||
var result = getSmartIndent(fileName3, 7);
|
||||
|
||||
assert.notNull(result);
|
||||
assert.equal(4, result);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,212 +0,0 @@
|
||||
/// <reference path='..\..\..\..\src\harness\harness.ts'/>
|
||||
/// <reference path="..\..\..\..\src\services\formatting\formatting.ts"/>
|
||||
|
||||
interface DocumentTestJson {
|
||||
input: string;
|
||||
rules: string[];
|
||||
span: { start: number; length: number; };
|
||||
expected: string;
|
||||
}
|
||||
|
||||
interface FormatOperationTestJson {
|
||||
input: string;
|
||||
operations: {
|
||||
operation: string;
|
||||
point: { position: number; };
|
||||
span: { start: number; length: number; };
|
||||
}[];
|
||||
expected: string;
|
||||
}
|
||||
|
||||
function markupCodeForHtml(code: string) {
|
||||
var formatted = code.replace(/</g, '<').replace(/ /g, '·').replace(/\t/g, ' → ').replace(/\n/g,'↵<br>');
|
||||
var escaped = encodeURIComponent(code).replace(/'/g, '%27');
|
||||
|
||||
return formatted + '<br><a href="javascript:;" onclick="copy(\'' + escaped + '\');">Copy</a>';
|
||||
}
|
||||
|
||||
describe('importedJavaScriptFormatting - formatting rules', function() {
|
||||
var documentTests: DocumentTestJson[] = eval('[' + IO.readFile(Harness.userSpecifiedroot + 'tests/cases/unittests/services/documentFormattingTests.json').contents() + ']');
|
||||
|
||||
var outputFile = 'diff-1.html';
|
||||
IO.writeFile(outputFile, IO.readFile(Harness.userSpecifiedroot + 'tests/cases/unittests/services/formatDiffTemplate.html').contents(), false);
|
||||
|
||||
var checkTest = function(test: DocumentTestJson) {
|
||||
var filename = 'temp.ts';
|
||||
var typescriptLS = new Harness.TypeScriptLS();
|
||||
typescriptLS.addScript(filename, test.input);
|
||||
|
||||
var ls = typescriptLS.getLanguageService().languageService;
|
||||
|
||||
var unsupportedRules = [];
|
||||
var ruleMap = {
|
||||
'SpaceAfterSemicolonInFor': 'InsertSpaceAfterSemicolonInForStatements',
|
||||
'SpaceAfterComma': 'InsertSpaceAfterCommaDelimiter',
|
||||
'NewLineBeforeOpenCurlyInControl': 'PlaceOpenBraceOnNewLineForControlBlocks',
|
||||
'NewLineBeforeOpenCurlyInFunction': 'PlaceOpenBraceOnNewLineForFunctions'
|
||||
};
|
||||
|
||||
var options = new Services.FormatCodeOptions();
|
||||
if (test.rules.indexOf('SpaceBeforeBinaryOperator') >= 0 && test.rules.indexOf('SpaceAfterBinaryOperator') >= 0) {
|
||||
test.rules.splice(test.rules.indexOf('SpaceBeforeBinaryOperator'), 1);
|
||||
test.rules.splice(test.rules.indexOf('SpaceAfterBinaryOperator'), 1);
|
||||
options.InsertSpaceBeforeAndAfterBinaryOperators = true;
|
||||
}
|
||||
|
||||
test.rules.forEach(ruleName => {
|
||||
if (options[ruleName] !== undefined) {
|
||||
// The options struct has a matching property, just set it directly
|
||||
options[ruleName] = true;
|
||||
} else {
|
||||
if (ruleMap[ruleName] !== undefined) {
|
||||
// We have a remapping of this name, use that instead
|
||||
options[ruleMap[ruleName]] = true;
|
||||
} else {
|
||||
if (ruleName.indexOf('No') === 0) {
|
||||
// This is a 'NoFoo', set 'Foo' to false
|
||||
options[ruleMap[ruleName.substr(2)]] = false;
|
||||
} else {
|
||||
// ??
|
||||
IO.printLine('Unsupported rule name ' + ruleName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var edits = ls.getFormattingEditsForRange(filename, test.span.start, test.span.start + test.span.length, options);
|
||||
|
||||
var output = typescriptLS.applyEdits(test.input, edits);
|
||||
|
||||
// Normalize line endings
|
||||
output = output.replace(/\r\n/g, '\n');
|
||||
test.expected = test.expected.replace(/\r\n/g, '\n');
|
||||
|
||||
if (output != test.expected) {
|
||||
var outputHtml = '';
|
||||
outputHtml += '<table class="test-table">';
|
||||
outputHtml += '<tr class="test-header-row">';
|
||||
outputHtml += '<th>Input</th><th>Output</th><th>Expected</th>';
|
||||
outputHtml += '</tr>';
|
||||
outputHtml += '<tr class="test-results-row">';
|
||||
outputHtml += '<td class="test-input code">' + markupCodeForHtml(test.input) + '</td>';
|
||||
outputHtml += '<td class="test-output code">' + markupCodeForHtml(output) + '</td>';
|
||||
outputHtml += '<td class="test-expected code">' + markupCodeForHtml(test.expected) + '</td>';
|
||||
outputHtml += '</tr>';
|
||||
outputHtml += '<tr class="test-operations-row">';
|
||||
outputHtml += '<td colspan="3">Format from character ' + test.span.start + ' to ' + (test.span.start + test.span.length) + ' with rules: ' + test.rules.join(', ') + '</td>';
|
||||
outputHtml += '</tr>';
|
||||
outputHtml += '</table>'; // test-table
|
||||
|
||||
IO.writeFile(outputFile, IO.readFile(outputFile).contents() + outputHtml, false);
|
||||
|
||||
// TODO: Uncomment when things are working
|
||||
// throw new Error("Formatting failed - refer to diff-1.html");
|
||||
}
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
|
||||
for (var i = 0; i < documentTests.length; i++) {
|
||||
var test = documentTests[i];
|
||||
|
||||
var msg = 'formats the code (index ' + i + ') from ' + test.span.start + ' to ' + (test.span.start + test.span.length) + ' with rules = [' + test.rules.join(', ') + '] correctly';
|
||||
it(msg, function(t) {
|
||||
return function() {
|
||||
checkTest(t);
|
||||
}
|
||||
}(test));
|
||||
}
|
||||
});
|
||||
|
||||
describe('importedJavaScriptFormatting - formatting operations', function() {
|
||||
var outputFile = 'diff-2.html';
|
||||
IO.writeFile(outputFile, IO.readFile(Harness.userSpecifiedroot + 'tests/cases/unittests/services/formatDiffTemplate.html').contents(), false);
|
||||
|
||||
var checkTest = function(test: FormatOperationTestJson) {
|
||||
var filename = 'temp.ts';
|
||||
var typescriptLS = new Harness.TypeScriptLS();
|
||||
typescriptLS.addScript(filename, test.input);
|
||||
|
||||
var ls = typescriptLS.getLanguageService();
|
||||
|
||||
var operationsText = '';
|
||||
|
||||
var markedUpInput = test.input;
|
||||
var output = test.input;
|
||||
|
||||
for (var i = 0; i < test.operations.length; i++) {
|
||||
var options = new Services.FormatCodeOptions();
|
||||
var op = test.operations[i];
|
||||
var edits: Services.TextEdit[];
|
||||
|
||||
if (op.operation === 'CloseBrace') {
|
||||
edits = ls.languageService.getFormattingEditsAfterKeystroke(filename, op.point.position, '}', options);
|
||||
operationsText += 'Format for } at position ' + op.point.position.toString();
|
||||
markedUpInput = markedUpInput.substring(0, op.point.position) + '✪' + markedUpInput.substring(op.point.position);
|
||||
} else if (op.operation === 'Enter') {
|
||||
edits = ls.languageService.getFormattingEditsAfterKeystroke(filename, op.point.position, '\n', options);
|
||||
operationsText += 'Format for [enter] at position ' + op.point.position.toString();
|
||||
markedUpInput = markedUpInput.substring(0, op.point.position) + '✪' + markedUpInput.substring(op.point.position);
|
||||
} else if (op.operation === 'Semicolon') {
|
||||
edits = ls.languageService.getFormattingEditsAfterKeystroke(filename, op.point.position, ';', options);
|
||||
operationsText += 'Format for ; at position ' + op.point.position.toString();
|
||||
markedUpInput = markedUpInput.substring(0, op.point.position) + '✪' + markedUpInput.substring(op.point.position);
|
||||
} else if (op.operation === 'Document') {
|
||||
edits = ls.languageService.getFormattingEditsForRange(filename, 0, output.length, options);
|
||||
operationsText += 'Format Document';
|
||||
} else if (op.operation === 'Selection') {
|
||||
edits = ls.languageService.getFormattingEditsForRange(filename, op.span.start, op.span.start + op.span.length, options);
|
||||
operationsText += 'Format selection from ' + op.span.start + ', length = ' + op.span.length;
|
||||
} else if (op.operation === 'Paste') {
|
||||
edits = ls.languageService.getFormattingEditsForRange(filename, op.span.start, op.span.start + op.span.length, options);
|
||||
operationsText += 'Format pasted content from ' + op.span.start + ', length = ' + op.span.length;
|
||||
} else {
|
||||
throw new Error('Unknown operation: ' + op.operation);
|
||||
}
|
||||
|
||||
output = typescriptLS.applyEdits(test.input, edits);
|
||||
typescriptLS.updateScript(filename, output);
|
||||
}
|
||||
|
||||
// Normalize line endings
|
||||
output = output.replace(/\r\n/g, '\n');
|
||||
test.expected = test.expected.replace(/\r\n/g, '\n');
|
||||
|
||||
var outputHtml = '';
|
||||
outputHtml += '<table class="test-table">';
|
||||
outputHtml += '<tr class="test-header-row">';
|
||||
outputHtml += '<th>Input</th><th>Output</th><th>Expected</th>';
|
||||
outputHtml += '</tr>';
|
||||
outputHtml += '<tr class="test-results-row">';
|
||||
outputHtml += '<td class="test-input code">' + markupCodeForHtml(markedUpInput) + '</td>';
|
||||
outputHtml += '<td class="test-output code">' + markupCodeForHtml(output) + '</td>';
|
||||
outputHtml += '<td class="test-expected code">' + markupCodeForHtml(test.expected) + '</td>';
|
||||
outputHtml += '</tr>';
|
||||
outputHtml += '<tr class="test-operations-row">';
|
||||
outputHtml += '<td colspan="3">' + operationsText + '</td>';
|
||||
outputHtml += '</tr>';
|
||||
outputHtml += '</table>'; // test-table
|
||||
|
||||
if (test.expected == output) {
|
||||
// Pass
|
||||
} else {
|
||||
IO.writeFile(outputFile, IO.readFile(outputFile).contents() + outputHtml, false);
|
||||
// TODO: Uncomment when things are working
|
||||
// throw new Error('Format test failed - refer to ' + outputFile);
|
||||
}
|
||||
}
|
||||
|
||||
var operationsTests: FormatOperationTestJson[] = eval('[' + IO.readFile(Harness.userSpecifiedroot + 'tests/cases/unittests/services/ruleFormattingTests.json').contents() + ']');
|
||||
for (var i = 0; i < operationsTests.length; i++) {
|
||||
var test = operationsTests[i];
|
||||
|
||||
var msg = 'formats the text correctly, line = ' + i;
|
||||
it(msg, function(t) {
|
||||
return function() {
|
||||
checkTest(t);
|
||||
}
|
||||
}(test));
|
||||
}
|
||||
});
|
||||
|
||||
@ -1,284 +0,0 @@
|
||||
{ input: "function a() {\r\nvar b = 0;//}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 31 } } ], expected: "function a() {\r\nvar b = 0;//}\r\n}" },
|
||||
{ input: "function foo() {\n do {\n } while (y < 10)\n\n}", operations: [ { operation: "Enter", point: { position: 50 } } ], expected: "function foo() {\n do {\n } while (y < 10)\n\n}" },
|
||||
{ input: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n}\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 87 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n }\r\n\r\n}" },
|
||||
{ input: "function a() {\r\n return (\r\n {\r\n x: 0\r\n }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 76 } } ], expected: "function a() {\r\n return (\r\n {\r\n x: 0\r\n }\r\n}" },
|
||||
{ input: " if ( a[\";\"])\r\nb++;", operations: [ { operation: "Semicolon", point: { position: 10 } } ], expected: " if ( a[\";\"])\r\nb++;" },
|
||||
{ input: "(function () {\r\n a({\r\n b: 0\r\n });\r\n\r\n})();", operations: [ { operation: "Enter", point: { position: 48 } } ], expected: "(function () {\r\n a({\r\n b: 0\r\n });\r\n\r\n})();" },
|
||||
{ input: "var obj={a:{b:2,c:{d:{e:{\r\n}}}}}", operations: [ { operation: "Enter", point: { position: 27 } } ], expected: "var obj = {\n a: {\n b: 2, c: {\n d: {\n e: {\r\n }\n }\n }\n }\n}" },
|
||||
{ input: "if(1)if(1)if(1)if(1)x+=2;", operations: [ { operation: "Semicolon", point: { position: 25 } } ], expected: "if (1) if (1) if (1) if (1) x += 2;" },
|
||||
{ input: "\r\nvar webclass = [\r\n { 'student':\r\n { 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }\r\n }\r\n]", operations: [ { operation: "Document" } ], expected: "\r\nvar webclass = [\r\n {\n 'student':\r\n { 'id': '1', 'name': 'Linda Jones', 'legacySkill': 'Access, VB 5.0' }\r\n }\r\n]" },
|
||||
{ input: "function f(x){ return x }\nwhile (f(true))\n y++;\n", operations: [ { operation: "Enter", point: { position: 51 } } ], expected: "function f(x){ return x }\nwhile (f(true))\n y++;\n" },
|
||||
{ input: "throw e;", operations: [ { operation: "Document" } ], expected: "throw e;" },
|
||||
{ input: "x = {\n a: 1,\n b: 1\n +\n // test\n 2\n}", operations: [ { operation: "Document" } ], expected: "x = {\n a: 1,\n b: 1\n +\n // test\n 2\n}" },
|
||||
{ input: "return 1;", operations: [ { operation: "Document" } ], expected: "return 1;" },
|
||||
{ input: "var x = [\n 1,\n 2,\n 3\n]", operations: [ { operation: "Document" } ], expected: "var x = [\n 1,\n 2,\n 3\n]" },
|
||||
{ input: "switch \r\n( a ){\r\n case 1:x+=2; break\r\n case 2:{\r\n }\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 9 } } ], expected: "switch\r\n(a) {\r\n case 1:x+=2; break\r\n case 2:{\r\n }\r\n}\r\n" },
|
||||
{ input: "if (a)\r\ntest;\r\nelse\r\nif (b)\r\ntest;\r\n", operations: [ { operation: "Enter", point: { position: 36 } } ], expected: "if (a)\r\ntest;\r\nelse\r\nif (b)\r\n test;\r\n" },
|
||||
{ input: "do{\r\ndo{\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)", operations: [ { operation: "CloseBrace", point: { position: 16 } } ], expected: "do{\r\ndo{\r\n do {\r\n } while (a !== b)\r\n}while(a!==b)\r\n}while(a!==b)" },
|
||||
{ input: "label1:\r\nvar a;\r\nvar b;", operations: [ { operation: "Document" } ], expected: "label1:\r\n var a;\r\nvar b;" },
|
||||
{ input: "\r\nfunction a() {\r\nfunction test() // test\r\n{\r\nif (test) // test\r\n{\r\n}\r\n}\r\n}", operations: [ { operation: "Document" } ], expected: "\r\nfunction a() {\r\n function test() // test\r\n {\r\n if (test) // test\r\n {\r\n }\r\n }\r\n}" },
|
||||
{ input: "var obj = {\r\na:{\r\nb:2,c:{\r\nd: {\r\ne: function f() {\r\nreturn obj.a.c.d.e() +f();\r\n}\r\n}\r\n}\r\n}\r\n};", operations: [ { operation: "Semicolon", point: { position: 94 } } ], expected: "var obj = {\r\n a: {\r\n b: 2, c: {\r\n d: {\r\n e: function f() {\r\n return obj.a.c.d.e() + f();\r\n }\r\n }\r\n }\r\n }\r\n};" },
|
||||
{ input: "function f() {\r\n do{\r\nx++ }\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "function f() {\r\n do{\r\n x++\n }\r\n\r\n}" },
|
||||
{ input: "function foo (a, b, c)", operations: [ { operation: "Document" } ], expected: "function foo(a, b, c)" },
|
||||
{ input: "{ var b;\n}", operations: [ { operation: "Document" } ], expected: "{\n var b;\n}" },
|
||||
{ input: "var z = {\na: 1};", operations: [ { operation: "Document" } ], expected: "var z = {\n a: 1\n};" },
|
||||
{ input: "for (var i = 0; i < 10; i++)\n { var a\n}", operations: [ { operation: "Document" } ], expected: "for (var i = 0; i < 10; i++) {\n var a\n}" },
|
||||
{ input: "if (1)\n {\nvar a }", operations: [ { operation: "Document" } ], expected: "if (1) {\n var a\n}" },
|
||||
{ input: "while (1)\n { var a\n}", operations: [ { operation: "Document" } ], expected: "while (1) {\n var a\n}" },
|
||||
{ input: "do\n { var a\n} while (1)", operations: [ { operation: "Document" } ], expected: "do {\n var a\n} while (1)" },
|
||||
{ input: "for (var a in b)\n { var a\n}", operations: [ { operation: "Document" } ], expected: "for (var a in b) {\n var a\n}" },
|
||||
{ input: "with (x)\n { var a\n}", operations: [ { operation: "Document" } ], expected: "with (x) {\n var a\n}" },
|
||||
{ input: "try\n { var a\n} \ncatch (e)\n { var a\n} \nfinally\n {\n}", operations: [ { operation: "Document" } ], expected: "try {\n var a\n}\ncatch (e) {\n var a\n}\nfinally {\n}" },
|
||||
{ input: "switch (x)\n { case 1: { var a }\n}", operations: [ { operation: "Document" } ], expected: "switch (x) {\n case 1: { var a }\n}" },
|
||||
{ input: "function f()\n { var x\n}", operations: [ { operation: "Document" } ], expected: "function f() {\n var x\n}" },
|
||||
{ input: "if(1)if(1)if(1)if(1){x+=2\r\n}", operations: [ { operation: "CloseBrace", point: { position: 28 } } ], expected: "if (1) if (1) if (1) if (1) {\n x += 2\r\n}" },
|
||||
{ input: "switch (a){\r\n case 1: x += 2;\r\n case 2 : \r\n for (var i=0;i<10;i++)\r\ni --;\r\n}\r\n", operations: [ { operation: "Semicolon", point: { position: 84 } } ], expected: "switch (a){\r\n case 1: x += 2;\r\n case 2 : \r\n for (var i = 0; i < 10; i++)\r\n i--;\r\n}\r\n" },
|
||||
{ input: "do{for(var i=0;i<10;i++)i-=2}while(1!==1);", operations: [ { operation: "Semicolon", point: { position: 42 } } ], expected: "do { for (var i = 0; i < 10; i++) i -= 2 } while (1 !== 1);" },
|
||||
{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;j++)\r\n{j-=i}}", operations: [ { operation: "Enter", point: { position: 45 } } ], expected: "for (var i = 0; i < 10; i++) {\n for (var j = 0; j < 10; j++)\r\n { j -= i }\n}" },
|
||||
{ input: "function f() {\r\nstring='string\\r\n line2' + 'other part'}", operations: [ { operation: "CloseBrace", point: { position: 63 } } ], expected: "function f() {\r\n string = 'string\\r\n line2' + 'other part'\n}" },
|
||||
{ input: "x =\r\n function ()\r\n{\r\n var a\r\n}", operations: [ { operation: "Document" } ], expected: "x =\r\n function () {\r\n var a\r\n }" },
|
||||
{ input: "if (a instanceof b) { }", operations: [ { operation: "Document" } ], expected: "if (a instanceof b) { }" },
|
||||
{ input: "do a++; while (0)", operations: [ { operation: "Document" } ], expected: "do a++; while (0)" },
|
||||
{ input: "foo\r\n(1, 2, 3)", operations: [ { operation: "Document" } ], expected: "foo\r\n(1, 2, 3)" },
|
||||
{ input: "if(1) //comment\r\n{\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "if (1) //comment\r\n{\r\n}\r\n" },
|
||||
{ input: "var x =\n [\n1\n]", operations: [ { operation: "Document" } ], expected: "var x =\n [\n1\n ]" },
|
||||
{ input: "\r\n{\r\n function f() {\r\n var s = 1\r\n }\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 59 } } ], expected: "\r\n{\r\n function f() {\r\n var s = 1\r\n }\r\n\r\n}" },
|
||||
{ input: "\r\ndefine(null,\r\n function test() {\r\nvar a;\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\ndefine(null,\r\n function test() {\r\n var a;\r\n }\r\n" },
|
||||
{ input: "x = [\r\n 1,\r\n\r\n]", operations: [ { operation: "Enter", point: { position: 15 } } ], expected: "x = [\r\n 1,\r\n\r\n]" },
|
||||
{ input: "var x =\n {\na: 1\n}", operations: [ { operation: "Document" } ], expected: "var x =\n {\n a: 1\n }" },
|
||||
{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "CloseBrace", point: { position: 50 } } ], expected: "for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { j -= i } }" },
|
||||
{ input: "function f()\n{\n for (a in b)\n a++;\n}", operations: [ { operation: "Semicolon", point: { position: 40 } } ], expected: "function f()\n{\n for (a in b)\n a++;\n}" },
|
||||
{ input: "if(x!=1^y===2) \r\nx+=2\r\n", operations: [ { operation: "Enter", point: { position: 25 } } ], expected: "if(x!=1^y===2) \r\n x += 2\r\n" },
|
||||
{ input: "if (1)\r\n if (1)\r\n x++\r\n else\r\n if (1)\r\n x--\r\nelse\r\n x+=2\r\n", operations: [ { operation: "Enter", point: { position: 81 } } ], expected: "if (1)\r\n if (1)\r\n x++\r\n else\r\n if (1)\r\n x--\r\n else\r\n x += 2\r\n" },
|
||||
{ input: "switch (a){\r\ncase 1 : x+=2 ; break;\r\n case 2:{\r\n }\r\n}\r\n", operations: [ { operation: "Semicolon", point: { position: 44 } } ], expected: "switch (a){\r\n case 1: x += 2; break;\r\n case 2:{\r\n }\r\n}\r\n" },
|
||||
{ input: "{ { {\r\n{\r\ntest\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Selection", span: { start: 7, length: 19 } } ], expected: "{ { {\r\n {\r\n test\r\n }\r\n}\r\n}\r\n}" },
|
||||
{ input: "do {\r\n do {\r\n do {\r\n }while(a!==b)\r\n\r\n} while (a !== b)\r\n} while (a !== b)", operations: [ { operation: "Enter", point: { position: 55 } } ], expected: "do {\r\n do {\r\n do {\r\n }while(a!==b)\r\n\r\n } while (a !== b)\r\n} while (a !== b)" },
|
||||
{ input: "\r\nswitch (t) {\r\n case 1:\r\n{\r\ntest\r\n}\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\nswitch (t) {\r\n case 1:\r\n {\r\n test\r\n }\r\n}\r\n" },
|
||||
{ input: "if (true) {\r\n \r\n}", operations: [ { operation: "Document" } ], expected: "if (true) {\r\n\r\n}" },
|
||||
{ input: "for(var j=0;j<10;j++)\r\nj-=i;", operations: [ { operation: "Semicolon", point: { position: 28 } } ], expected: "for (var j = 0; j < 10; j++)\r\n j -= i;" },
|
||||
{ input: "function a() {\r\n function b() {\r\n //\r\n\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 48 } } ], expected: "function a() {\r\n function b() {\r\n //\r\n\r\n }\r\n}" },
|
||||
{ input: "if(1)if(1)if(1)if(1)x+=2\r\n", operations: [ { operation: "Enter", point: { position: 26 } } ], expected: "if (1) if (1) if (1) if (1) x += 2\r\n" },
|
||||
{ input: "do{do{do{}while(a!==b)}while(a!==b)}while(a!==b)\r\n", operations: [ { operation: "Enter", point: { position: 50 } } ], expected: "do { do { do { } while (a !== b) } while (a !== b) } while (a !== b)\r\n" },
|
||||
{ input: "foo(\r\n)", operations: [ { operation: "Document" } ], expected: "foo(\r\n)" },
|
||||
{ input: "function f() {\r\n'use strict';\r\n}", operations: [ { operation: "Semicolon", point: { position: 29 } } ], expected: "function f() {\r\n 'use strict';\r\n}" },
|
||||
{ input: "var x = function() {\n//comment\nreturn 1;\n}", operations: [ { operation: "Document" } ], expected: "var x = function () {\n //comment\n return 1;\n}" },
|
||||
{ input: " function foo4() {\r\n function foo5() {\r\n function foo6() {\r\n test1\r\n }\r\n test2\r\n }\r\n }", operations: [ { operation: "Selection", span: { start: 62, length: 120 } } ], expected: " function foo4() {\r\n function foo5() {\r\n function foo6() {\r\n test1\r\n }\r\n test2\r\n }\r\n }" },
|
||||
{ input: "do{\r\ndo{\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)", operations: [ { operation: "CloseBrace", point: { position: 46 } } ], expected: "do {\r\n do {\r\n do {\r\n } while (a !== b)\r\n } while (a !== b)\r\n} while (a !== b)" },
|
||||
{ input: "if (true)\n// test\n test;", operations: [ { operation: "Document" } ], expected: "if (true)\n // test\n test;" },
|
||||
{ input: "function test() {\r\n return (\r\n function test() {\r\n test;\r\n }\r\n );\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n return (\r\n function test() {\r\n test;\r\n }\r\n );\r\n}" },
|
||||
{ input: "for(var i=0;i<10;i++){\r\nfor(var j=0;j<10;j++){\r\nj-=i\r\n}}", operations: [ { operation: "CloseBrace", point: { position: 56 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n }\n}" },
|
||||
{ input: " var a = 0 ;", operations: [ { operation: "Semicolon", point: { position: 14 } } ], expected: "var a = 0;" },
|
||||
{ input: "var obj={a:{b:2,c:{d:\r\n{e:{}}}}}", operations: [ { operation: "Enter", point: { position: 23 } } ], expected: "var obj = {\n a: {\n b: 2, c: {\n d:\r\n { e: {} }\n }\n }\n}" },
|
||||
{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n}finally {\r\nx+=2\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 74 } } ], expected: "function foo() {\r\n try {\r\n x += 2\r\n }\r\n catch (e) {\r\n x += 2\r\n } finally {\r\n x += 2\r\n }\r\n}" },
|
||||
{ input: "var obj = {\r\na: {\r\nb: 2, c: {\r\nd: {\r\ne: function f() {\r\nreturn obj.a.c.d.e() + f();\r\n}\r\n}\r\n}\r\n}}", operations: [ { operation: "CloseBrace", point: { position: 96 } } ], expected: "var obj = {\r\n a: {\r\n b: 2, c: {\r\n d: {\r\n e: function f() {\r\n return obj.a.c.d.e() + f();\r\n }\r\n }\r\n }\r\n }\n}" },
|
||||
{ input: "if (x!=1^y===2){ x+=2}", operations: [ { operation: "CloseBrace", point: { position: 24 } } ], expected: "if (x != 1 ^ y === 2) { x += 2 }" },
|
||||
{ input: "function test() {\r\n var a;\r\n label:\r\n for (; ;)\r\n\r\n", operations: [ { operation: "Enter", point: { position: 58 } } ], expected: "function test() {\r\n var a;\r\n label:\r\n for (; ;)\r\n\r\n" },
|
||||
{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;j++){\r\nj-=i}}", operations: [ { operation: "Enter", point: { position: 46 } } ], expected: "for (var i = 0; i < 10; i++) {\n for (var j = 0; j < 10; j++) {\r\n j -= i\n }\n}" },
|
||||
{ input: "do {\r\n for (var i = 0; i < 10; i++)\r\n i -= 2\r\n }\r\nwhile (1 !== 1)", operations: [ { operation: "Enter", point: { position: 67 } } ], expected: "do {\r\n for (var i = 0; i < 10; i++)\r\n i -= 2\r\n}\r\nwhile (1 !== 1)" },
|
||||
{ input: "{\r\n try {\r\n } catch (e) {\r\n }\r\n}", operations: [ { operation: "Document" } ], expected: "{\r\n try {\r\n } catch (e) {\r\n }\r\n}" },
|
||||
{ input: "{ { {\r\n{\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Selection", span: { start: 7, length: 13 } } ], expected: "{ { {\r\n {\r\n }\r\n}\r\n}\r\n}" },
|
||||
{ input: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\nj -= i}}\r\n", operations: [ { operation: "Enter", point: { position: 78 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\n }\n}\r\n" },
|
||||
{ input: "var a = {\r\n}", operations: [ { operation: "Document" } ], expected: "var a = {\r\n}" },
|
||||
{ input: "\r\n switch ( a ) {\r\n case 1: x+=2;\r\n case 2:{\r\n }\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 2 } } ], expected: "\r\nswitch (a) {\r\n case 1: x+=2;\r\n case 2:{\r\n }\r\n}\r\n" },
|
||||
{ input: "function a() {\r\nvar b = 0;//;\r\n}", operations: [ { operation: "Semicolon", point: { position: 31 } } ], expected: "function a() {\r\nvar b = 0;//;\r\n}" },
|
||||
{ input: "for (a in b) { }", operations: [ { operation: "Document" } ], expected: "for (a in b) { }" },
|
||||
{ input: "\r\n{\r\nfunction test(/* test */ a,\r\n /* test */ b\r\n /* test */) {\r\n// test\r\n}\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\n{\r\n function test(/* test */ a,\r\n /* test */ b\r\n /* test */) {\r\n // test\r\n }\r\n}\r\n" },
|
||||
{ input: " //\r\n", operations: [ { operation: "Enter", point: { position: 8 } } ], expected: "//\r\n" },
|
||||
{ input: " if ( a[\"}\"])\r\nb++;", operations: [ { operation: "CloseBrace", point: { position: 10 } } ], expected: " if ( a[\"}\"])\r\nb++;" },
|
||||
{ input: "$ ( document ) . ready ( function ( ) { \n alert ( \"i am ready\" ) ;\n } );", operations: [ { operation: "Semicolon", point: { position: 138 } } ], expected: "$(document).ready(function () {\n alert(\"i am ready\");\n});" },
|
||||
{ input: "function f() {\r\nvar s=\"string\";\r\n}", operations: [ { operation: "Semicolon", point: { position: 31 } } ], expected: "function f() {\r\n var s = \"string\";\r\n}" },
|
||||
{ input: "do{for(var i=0;i<10;i++)i-=2\r\n}while(1!==1)", operations: [ { operation: "Enter", point: { position: 30 } } ], expected: "do {\n for (var i = 0; i < 10; i++) i -= 2\r\n} while (1 !== 1)" },
|
||||
{ input: "do{\r\ndo{\r\n\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)", operations: [ { operation: "Enter", point: { position: 12 } } ], expected: "do{\r\ndo{\r\n\r\n do {\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)" },
|
||||
{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "CloseBrace", point: { position: 49 } } ], expected: "for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { j -= i }}" },
|
||||
{ input: "var obj = {\r\na: {\r\nb: 2, c: {\r\nd: {\r\ne: function f() {\r\nreturn obj.a.c.d.e() + f();\r\n}\r\n}\r\n } \r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 99 } } ], expected: "var obj = {\r\na: {\r\n b: 2, c: {\r\n d: {\r\n e: function f() {\r\n return obj.a.c.d.e() + f();\r\n }\r\n }\r\n }\r\n}\r\n}" },
|
||||
{ input: "var a = 0 ;var b=0;var c = 0 ;", operations: [ { operation: "Paste", span: { start: 13, length: 7 } } ], expected: "var a = 0; var b = 0; var c = 0;" },
|
||||
{ input: "function a()\r\n{\r\n}", operations: [ { operation: "Enter", point: { position: 14 } } ], expected: "function a()\r\n{\r\n}" },
|
||||
{ input: " function test() { function foo() { function foo3() { function foo4() { function foo5() { function foo6()\r\n{\r\ntest\r\n}\r\n}\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Selection", span: { start: 110, length: 25 } } ], expected: " function test() { function foo() { function foo3() { function foo4() { function foo5() { function foo6()\r\n {\r\n test\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }" },
|
||||
{ input: " \r\nfunction a() { \r\n return; \r\n} \r\n ", operations: [ { operation: "Document" } ], expected: "\r\nfunction a() {\r\n return;\r\n}\r\n" },
|
||||
{ input: "foo(\r\n1, 2, 3)", operations: [ { operation: "Document" } ], expected: "foo(\r\n1, 2, 3)" },
|
||||
{ input: "function Init() {\r\n var a = [[1, 2],\r\n [3, 4],\r\n\r\n ];\r\n}", operations: [ { operation: "Enter", point: { position: 63 } } ], expected: "function Init() {\r\n var a = [[1, 2],\r\n [3, 4],\r\n\r\n ];\r\n}" },
|
||||
{ input: "\r\n //function start\r\n function abc() { }\r\n //function end\r\n", operations: [ { operation: "Document" } ], expected: "\r\n//function start\r\nfunction abc() { }\r\n//function end\r\n" },
|
||||
{ input: "for(var i=0;i<10;i++){\r\n for (var j = 0; j < 10; j++) {\r\nj-=i\r\n\r\n}\r\n}", operations: [ { operation: "Enter", point: { position: 66 } } ], expected: "for(var i=0;i<10;i++){\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n\r\n}\r\n}" },
|
||||
{ input: "// JScript source code\r\nfunction adder(a, b) {\r\n ///<summary>Adds two numbers </summary>\r\n return a + b;\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 94 } } ], expected: "// JScript source code\r\nfunction adder(a, b) {\r\n ///<summary>Adds two numbers </summary>\r\n return a + b;\r\n}\r\n" },
|
||||
{ input: "x = {\r\n a: function() {\r\n},\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "x = {\r\n a: function() {\r\n },\r\n\r\n}" },
|
||||
{ input: "if(1)\r\n if(1)\r\n x++\r\n else\r\n if(1)\r\n x+=2\r\n else\r\nx+=2\r\n", operations: [ { operation: "Enter", point: { position: 94 } } ], expected: "if(1)\r\n if(1)\r\n x++\r\n else\r\n if(1)\r\n x+=2\r\n else\r\n x += 2\r\n" },
|
||||
{ input: "for (a in b) {\nx++;}\n", operations: [ { operation: "Enter", point: { position: 21 } } ], expected: "for (a in b) {\n x++;\n}\n" },
|
||||
{ input: "if(1)if(1)if(1)if(1){x+=2}", operations: [ { operation: "CloseBrace", point: { position: 26 } } ], expected: "if (1) if (1) if (1) if (1) { x += 2 }" },
|
||||
{ input: "if (x!=1^y===2){ x+=2\r\n}", operations: [ { operation: "CloseBrace", point: { position: 26 } } ], expected: "if (x != 1 ^ y === 2) {\n x += 2\r\n}" },
|
||||
{ input: "var d = new Date ()", operations: [ { operation: "Document" } ], expected: "var d = new Date()" },
|
||||
{ input: "do {\r\n} while (1 == 10);", operations: [ { operation: "Document" } ], expected: "do {\r\n} while (1 == 10);" },
|
||||
{ input: "string='string+=2';", operations: [ { operation: "Semicolon", point: { position: 19 } } ], expected: "string = 'string+=2';" },
|
||||
{ input: "function foo() {\r\n try {\r\n }\r\ncatch(e){\r\n } finally {\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 48 } } ], expected: "function foo() {\r\n try {\r\n }\r\n catch (e) {\r\n } finally {\r\n }\r\n}" },
|
||||
{ input: "try // comment\r\n{\r\n}\r\ncatch (e) // comment\r\n{\r\n}\r\nfinally // comment\r\n{\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "try // comment\r\n{\r\n}\r\ncatch (e) // comment\r\n{\r\n}\r\nfinally // comment\r\n{\r\n}\r\n" },
|
||||
{ input: "function f() {\r\n /**/ var x;\r\n}", operations: [ { operation: "Semicolon", point: { position: 39 } } ], expected: "function f() {\r\n /**/ var x;\r\n}" },
|
||||
{ input: "if (a)\r\ntest;\r\nelse if (b)\r\ntest;", operations: [ { operation: "Document" } ], expected: "if (a)\r\n test;\r\nelse if (b)\r\n test;" },
|
||||
{ input: "foo(1, 2, 3\r\n)", operations: [ { operation: "Document" } ], expected: "foo(1, 2, 3\r\n)" },
|
||||
{ input: "\r\nswitch (a){\r\n case 1: x++;\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\nswitch (a) {\r\n case 1: x++;\r\n}\r\n" },
|
||||
{ input: "x = {\r\n a: function () {\r\n\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 39 } } ], expected: "x = {\r\n a: function () {\r\n\r\n }\r\n}" },
|
||||
{ input: "switch (a) {\n case 1: b++;\n break;\n\n default: a++;\n break;\n}", operations: [ { operation: "Enter", point: { position: 45 } } ], expected: "switch (a) {\n case 1: b++;\n break;\n\n default: a++;\n break;\n}" },
|
||||
{ input: "string='string+=2;'", operations: [ { operation: "Semicolon", point: { position: 18 } } ], expected: "string='string+=2;'" },
|
||||
{ input: "function test() {\r\n function foo() {\r\n var a;\r\n// some\r\ncomment\r\n", operations: [ { operation: "Enter", point: { position: 66 } } ], expected: "function test() {\r\n function foo() {\r\n var a;\r\n // some\r\n comment\r\n" },
|
||||
{ input: "switch ( a ) {\r\n case 1: x+=2;\r\n case 2:{for(var i=0;i<10;i++){ \r\nx+=2;}\r\n }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 89 } } ], expected: "switch (a) {\r\n case 1: x += 2;\r\n case 2: {\n for (var i = 0; i < 10; i++) {\r\n x += 2;\n }\r\n }\r\n}" },
|
||||
{ input: "do{\r\nfor(var i=0;i<10;i++)\r\ni-=2;\r\n}while(1!==1)", operations: [ { operation: "Semicolon", point: { position: 33 } } ], expected: "do{\r\n for (var i = 0; i < 10; i++)\r\n i -= 2;\r\n}while(1!==1)" },
|
||||
{ input: "\r\nfunction foo() {\r\n try{ } catch (e) { } finally { }\r\n\r\n\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 63 } } ], expected: "\r\nfunction foo() {\r\n try { } catch (e) { } finally { }\r\n\r\n\r\n}\r\n" },
|
||||
{ input: "do{for(var i=0;i<10;i++)\r\ni-=2}while(1!==1)", operations: [ { operation: "Enter", point: { position: 26 } } ], expected: "do {\n for (var i = 0; i < 10; i++)\r\n i -= 2\n} while (1 !== 1)" },
|
||||
{ input: "\r\n fun(\r\n {\r\n a: 1\r\n });\r\n", operations: [ { operation: "Document" } ], expected: "\r\nfun(\r\n {\r\n a: 1\r\n });\r\n" },
|
||||
{ input: "function f () //comment\r\n{\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "function f() //comment\r\n{\r\n}\r\n" },
|
||||
{ input: "function a(b) {\r\n var c = 0;\r\n if (b != null) {\r\n for (d in b) {\r\n }\r\n }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 94 } } ], expected: "function a(b) {\r\n var c = 0;\r\n if (b != null) {\r\n for (d in b) {\r\n }\r\n }\r\n}" },
|
||||
{ input: "switch (a) {\r\n case 1:\r\n\r\n break;\r\n}", operations: [ { operation: "Enter", point: { position: 34 } } ], expected: "switch (a) {\r\n case 1:\r\n\r\n break;\r\n}" },
|
||||
{ input: " \r\n do{\r\n for(var i=0;i<10;i++)\r\n i -= 2\r\n}\r\nwhile (1 !== 1)", operations: [ { operation: "Enter", point: { position: 5 } } ], expected: "\r\ndo {\r\n for(var i=0;i<10;i++)\r\n i -= 2\r\n}\r\nwhile (1 !== 1)" },
|
||||
{ input: "function test() {\r\n label1:\r\nvar a\r\n\r\n var b;\r\n}", operations: [ { operation: "Enter", point: { position: 39 } } ], expected: "function test() {\r\n label1:\r\n var a\r\n\r\n var b;\r\n}" },
|
||||
{ input: "var x = {\n//comment\na: 1\n}", operations: [ { operation: "Document" } ], expected: "var x = {\n //comment\n a: 1\n}" },
|
||||
{ input: "for(var i=0;i<10;i++){\r\n\r\nfor(var j=0;j<10;j++){\r\nj-=i\r\n}\r\n}", operations: [ { operation: "Enter", point: { position: 26 } } ], expected: "for(var i=0;i<10;i++){\r\n\r\n for (var j = 0; j < 10; j++) {\r\nj-=i\r\n}\r\n}" },
|
||||
{ input: "if (true) {\r\n//\r\n} else if (false) {\r\n//\r\n} else\r\n if (true)\r\n//", operations: [ { operation: "Document" } ], expected: "if (true) {\r\n //\r\n} else if (false) {\r\n //\r\n} else\r\n if (true)\r\n //" },
|
||||
{ input: "x = [\n 1,\n 1\n +\n // test\n 2\n]", operations: [ { operation: "Document" } ], expected: "x = [\n 1,\n 1\n +\n // test\n 2\n]" },
|
||||
{ input: "var x =\n function() {\nreturn 1;\n}", operations: [ { operation: "Document" } ], expected: "var x =\n function () {\n return 1;\n }" },
|
||||
{ input: "function f() {\n var x }", operations: [ { operation: "Document" } ], expected: "function f() {\n var x\n}" },
|
||||
{ input: "switch (a) {\r\n case 1: b++;\r\n break ;\r\n\r\n default: a++;\r\n break;\r\n}", operations: [ { operation: "Enter", point: { position: 46 } } ], expected: "switch (a) {\r\n case 1: b++;\r\n break;\r\n\r\n default: a++;\r\n break;\r\n}" },
|
||||
{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n} finally {\r\nx+=2\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 32 } } ], expected: "function foo() {\r\n try {\r\n x += 2\r\n }\r\ncatch( e){\r\nx+=2\r\n} finally {\r\nx+=2\r\n}\r\n}" },
|
||||
{ input: "function f(a, b\n , c){\n}", operations: [ { operation: "CloseBrace", point: { position: 39 } } ], expected: "function f(a, b\n , c) {\n}" },
|
||||
{ input: "function add(a, b) { return a + b}", operations: [ { operation: "Document" } ], expected: "function add(a, b) { return a + b }" },
|
||||
{ input: "var a = 0 ;\r\n", operations: [ { operation: "Enter", point: { position: 15 } } ], expected: "var a = 0;\r\n" },
|
||||
{ input: "var a = function (b) {\r\nb = 0;\r\n}", operations: [ { operation: "CloseBrace", point: { position: 33 } } ], expected: "var a = function (b) {\r\n b = 0;\r\n}" },
|
||||
{ input: "\r\nif (\r\n test) {\r\n a;\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\nif (\r\n test) {\r\n a;\r\n}\r\n" },
|
||||
{ input: " var a = 0 ;\r\n var b = { } ;\r\n var c = false ;", operations: [ { operation: "Selection", span: { start: 18, length: 34 } } ], expected: " var a = 0 ;\r\n var b = {};\r\n var c = false ;" },
|
||||
{ input: "function a() {\r\n return (\r\n function () {\r\n return 0;\r\n }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 93 } } ], expected: "function a() {\r\n return (\r\n function () {\r\n return 0;\r\n }\r\n}" },
|
||||
{ input: "function test() {\r\n label1:\r\n a();\r\n b()\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 59 } } ], expected: "function test() {\r\n label1:\r\n a();\r\n b()\r\n\r\n}" },
|
||||
{ input: "(function () {\r\n a({\r\n b: 0\r\n });\r\n})();", operations: [ { operation: "Document" } ], expected: "(function () {\r\n a({\r\n b: 0\r\n });\r\n})();" },
|
||||
{ input: "function a() {\r\n /**/ }", operations: [ { operation: "Document" } ], expected: "function a() {\r\n /**/\n}" },
|
||||
{ input: "for (var i = 0; i < 10; i++) {\r\n for (var j=0;j<10;j++) {\r\nj=i;\r\n }\r\n}", operations: [ { operation: "Semicolon", point: { position: 64 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j=0;j<10;j++) {\r\n j = i;\r\n }\r\n}" },
|
||||
{ input: "function f() {\r\n var x; /*\r\n */ var y = 2;\r\n}", operations: [ { operation: "Document" } ], expected: "function f() {\r\n var x; /*\r\n */ var y = 2;\r\n}" },
|
||||
{ input: "foo (1, 2, 3)", operations: [ { operation: "Document" } ], expected: "foo(1, 2, 3)" },
|
||||
{ input: "if (typeof a == null);", operations: [ { operation: "Document" } ], expected: "if (typeof a == null);" },
|
||||
{ input: "function f() {\r\n var x = \"\\r\n \"; var y = 2;\r\n}", operations: [ { operation: "Document" } ], expected: "function f() {\r\n var x = \"\\r\n \"; var y = 2;\r\n}" },
|
||||
{ input: "void x;", operations: [ { operation: "Document" } ], expected: "void x;" },
|
||||
{ input: "function f() {\r\n string='string'\r\n }\r\n", operations: [ { operation: "Enter", point: { position: 44 } } ], expected: "function f() {\r\n string='string'\r\n}\r\n" },
|
||||
{ input: "do{\r\nfor(var i=0;i<10;i++)\r\ni-=2\r\n}while(1!==1);", operations: [ { operation: "Semicolon", point: { position: 48 } } ], expected: "do {\r\n for (var i = 0; i < 10; i++)\r\n i -= 2\r\n} while (1 !== 1);" },
|
||||
{ input: "function test() {\r\n return (\r\n {\r\n a: 1\r\n }\r\n );\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n return (\r\n {\r\n a: 1\r\n }\r\n );\r\n}" },
|
||||
{ input: "for(var i=0;i<10;i++)\r\n{for(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "Enter", point: { position: 23 } } ], expected: "for (var i = 0; i < 10; i++)\r\n{ for (var j = 0; j < 10; j++) { j -= i } }" },
|
||||
{ input: "for(var i=0;i<10;i++){\r\nfor(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "Enter", point: { position: 24 } } ], expected: "for (var i = 0; i < 10; i++) {\r\n for (var j = 0; j < 10; j++) { j -= i }\n}" },
|
||||
{ input: "do{\r\nfor(var i=0;i<10;i++)\r\ni-=2\r\n}while(1!==1)\r\n", operations: [ { operation: "Enter", point: { position: 49 } } ], expected: "do{\r\nfor(var i=0;i<10;i++)\r\ni-=2\r\n} while (1 !== 1)\r\n" },
|
||||
{ input: "if(1===1\r\n&& 2===2)x+=2", operations: [ { operation: "Enter", point: { position: 10 } } ], expected: "if (1 === 1\r\n&& 2 === 2) x += 2" },
|
||||
{ input: "\r\n{\r\n\r\n/* test\r\n test2\r\n test3 */\r\nvar a,\r\n // test\r\n // test\r\n b;\r\n\r\nx = {\r\na: 1 +\r\n // test\r\n /* test\r\n test2 */\r\n 2\r\n}\r\n\r\na(1,\r\n 2). // test\r\n test(); /* test */\r\n\r\n/* test\r\n test2\r\n test3 */\r\nfunction foo(a, b,\r\n /* test\r\n test2\r\n test3 */\r\n c) {\r\n}\r\n\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\n{\r\n\r\n /* test\r\n test2\r\n test3 */\r\n var a,\r\n // test\r\n // test\r\n b;\r\n\r\n x = {\r\n a: 1 +\r\n // test\r\n /* test\r\n test2 */\r\n 2\r\n }\r\n\r\n a(1,\r\n 2). // test\r\n test(); /* test */\r\n\r\n /* test\r\n test2\r\n test3 */\r\n function foo(a, b,\r\n /* test\r\n test2\r\n test3 */\r\n c) {\r\n }\r\n\r\n}\r\n" },
|
||||
{ input: "\r\n for (var i = 0; i < 10\r\n ; i--) {\r\n test\r\n ;\r\n }\r\n", operations: [ { operation: "Document" } ], expected: "\r\nfor (var i = 0; i < 10\r\n ; i--) {\r\n test\r\n ;\r\n}\r\n" },
|
||||
{ input: "if (1)\r\n x++;\r\nelse if (1)\r\n x--;", operations: [ { operation: "Document" } ], expected: "if (1)\r\n x++;\r\nelse if (1)\r\n x--;" },
|
||||
{ input: "x = {\n get foo () {\n },\n set foo (val) {\n }\n};", operations: [ { operation: "Document" } ], expected: "x = {\n get foo() {\n },\n set foo(val) {\n }\n};" },
|
||||
{ input: "function foo\r\n(a, b, c) {\r\n}", operations: [ { operation: "Document" } ], expected: "function foo\r\n(a, b, c) {\r\n}" },
|
||||
{ input: "switch ( a ) {\r\n case 1: x+=2;\r\n case 2:{for(var i=0;i<10;i++){ \r\nx+=2;\r\n }}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 80 } } ], expected: "switch ( a ) {\r\n case 1: x+=2;\r\n case 2: {\n for (var i = 0; i < 10; i++) {\r\n x += 2;\r\n }\n }\r\n}" },
|
||||
{ input: "function f() {\r\n'use strict'}", operations: [ { operation: "CloseBrace", point: { position: 29 } } ], expected: "function f() {\r\n 'use strict'\n}" },
|
||||
{ input: "foo(1\r\n, 2, 3)", operations: [ { operation: "Document" } ], expected: "foo(1\r\n, 2, 3)" },
|
||||
{ input: "do{\r\ndo\r\n{\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)", operations: [ { operation: "Enter", point: { position: 9 } } ], expected: "do{\r\n do\r\n {\r\ndo{\r\n}while(a!==b)\r\n}while(a!==b)\r\n}while(a!==b)" },
|
||||
{ input: "function Sum(a,b,c) {\r\n for(i=0,j=1,k=0,fib=1;i<5;i++,fib=j+k,k=j,j=fib) {\r\n var sparseArray = [1,,,,5]\r\n }\r\n}", operations: [ { operation: "Selection", span: { start: 49, length: 3 } } ], expected: "function Sum(a,b,c) {\r\n for (i = 0, j = 1, k = 0, fib = 1; i < 5; i++, fib = j + k, k = j, j = fib) {\r\n var sparseArray = [1,,,,5]\r\n }\r\n}" },
|
||||
{ input: "function a() {\r\n function b() {\r\n\r\n }\r\n}", operations: [ { operation: "Document" } ], expected: "function a() {\r\n function b() {\r\n\r\n }\r\n}" },
|
||||
{ input: "", operations: [ { operation: "Document" } ], expected: "" },
|
||||
{ input: "function a() {\r\nvar b=\"c\"\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 27 } } ], expected: "function a() {\r\n var b = \"c\"\r\n\r\n}" },
|
||||
{ input: " if ( a[\"\r\n\"])\r\nb++;", operations: [ { operation: "Enter", point: { position: 11 } } ], expected: "if ( a[\"\r\n\"])\r\nb++;" },
|
||||
{ input: "/* \r\n \r\n*/ ", operations: [ { operation: "Document" } ], expected: "/* \r\n \r\n*/" },
|
||||
{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n}finally {\r\nx+=2\r\n}\r\n};", operations: [ { operation: "Semicolon", point: { position: 75 } } ], expected: "function foo() {\r\n try {\r\n x += 2\r\n }\r\n catch (e) {\r\n x += 2\r\n } finally {\r\n x += 2\r\n }\r\n};" },
|
||||
{ input: "if (1) if (1) a++;", operations: [ { operation: "Document" } ], expected: "if (1) if (1) a++;" },
|
||||
{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n}finally {\r\nx+=2\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 53 } } ], expected: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\n catch (e) {\r\n x += 2\r\n }finally {\r\nx+=2\r\n}\r\n}" },
|
||||
{ input: "function f() {\r\n'use strict'\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 30 } } ], expected: "function f() {\r\n 'use strict'\r\n\r\n}" },
|
||||
{ input: " \r\n ", operations: [ { operation: "Document" } ], expected: " \r\n " },
|
||||
{ input: "{ var b; }", operations: [ { operation: "Document" } ], expected: "{ var b; }" },
|
||||
{ input: "var z = {a: 1};", operations: [ { operation: "Document" } ], expected: "var z = { a: 1 };" },
|
||||
{ input: "var z =\n {a: 1};", operations: [ { operation: "Document" } ], expected: "var z =\n { a: 1 };" },
|
||||
{ input: "for (var i = 0; i < 10; i++) { var a }", operations: [ { operation: "Document" } ], expected: "for (var i = 0; i < 10; i++) { var a }" },
|
||||
{ input: "for (var i = 0; i < 10; i++)\n { var a }", operations: [ { operation: "Document" } ], expected: "for (var i = 0; i < 10; i++)\n{ var a }" },
|
||||
{ input: "if (1) { var a }", operations: [ { operation: "Document" } ], expected: "if (1) { var a }" },
|
||||
{ input: "if (1)\n { var a }", operations: [ { operation: "Document" } ], expected: "if (1)\n{ var a }" },
|
||||
{ input: "while (1) { var a }", operations: [ { operation: "Document" } ], expected: "while (1) { var a }" },
|
||||
{ input: "while (1)\n { var a }", operations: [ { operation: "Document" } ], expected: "while (1)\n{ var a }" },
|
||||
{ input: "do { var a } while (1)", operations: [ { operation: "Document" } ], expected: "do { var a } while (1)" },
|
||||
{ input: "do\n { var a }\n while (1)", operations: [ { operation: "Document" } ], expected: "do\n{ var a }\nwhile (1)" },
|
||||
{ input: "for (var a in b) { var a }", operations: [ { operation: "Document" } ], expected: "for (var a in b) { var a }" },
|
||||
{ input: "for (var a in b)\n { var a }", operations: [ { operation: "Document" } ], expected: "for (var a in b)\n{ var a }" },
|
||||
{ input: "with (x) { var a }", operations: [ { operation: "Document" } ], expected: "with (x) { var a }" },
|
||||
{ input: "with (x)\n { var a }", operations: [ { operation: "Document" } ], expected: "with (x)\n{ var a }" },
|
||||
{ input: "try { var a } \ncatch (e) { var a } \nfinally { }", operations: [ { operation: "Document" } ], expected: "try { var a }\ncatch (e) { var a }\nfinally { }" },
|
||||
{ input: "try\n { var a } \ncatch (e)\n { var a } \nfinally\n { }", operations: [ { operation: "Document" } ], expected: "try\n{ var a }\ncatch (e)\n{ var a }\nfinally\n{ }" },
|
||||
{ input: "switch (x) { case 1: { var a } }", operations: [ { operation: "Document" } ], expected: "switch (x) { case 1: { var a } }" },
|
||||
{ input: "switch (x)\n { case 1: { var a } }", operations: [ { operation: "Document" } ], expected: "switch (x)\n{ case 1: { var a } }" },
|
||||
{ input: "function f() { var x }", operations: [ { operation: "Document" } ], expected: "function f() { var x }" },
|
||||
{ input: "function f()\n\n { var x }", operations: [ { operation: "Document" } ], expected: "function f()\n\n{ var x }" },
|
||||
{ input: "function test() {\r\nlabel1:\r\nvar a;\r\nvar b;\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n label1:\r\n var a;\r\n var b;\r\n}" },
|
||||
{ input: "{\n x =\nfunction () {\n };\n}", operations: [ { operation: "Document" } ], expected: "{\n x =\nfunction () {\n};\n}" },
|
||||
{ input: "switch (a){\r\n case 1: x+=2;\r\ncase 2 : { \r\nx+=2}\r\n}", operations: [ { operation: "Enter", point: { position: 49 } } ], expected: "switch (a){\r\n case 1: x+=2;\r\n case 2: {\r\n x += 2\n }\r\n}" },
|
||||
{ input: " // ;", operations: [ { operation: "Semicolon", point: { position: 7 } } ], expected: " // ;" },
|
||||
{ input: "// JScript source code\r\nfunction adder(a, b) {\r\n ///<summary>Adds two numbers </summary>\r\n return a + b;\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 115 } } ], expected: "// JScript source code\r\nfunction adder(a, b) {\r\n ///<summary>Adds two numbers </summary>\r\n return a + b;\r\n}\r\n" },
|
||||
{ input: "function foo4() {\r\n test;\r\n for (; ;) {\r\n test\r\n }\r\n}", operations: [ { operation: "Selection", span: { start: 46, length: 33 } } ], expected: "function foo4() {\r\n test;\r\n for (; ;) {\r\n test\r\n }\r\n}" },
|
||||
{ input: "if (a in b) { }", operations: [ { operation: "Document" } ], expected: "if (a in b) { }" },
|
||||
{ input: "\r\nfunction f() {\r\nlabel0:\r\nfor (var i = 0; i < 10; i++) {\r\nlabel1: {\r\nfor (var i = 0; i < 10; i++)\r\nx = 2;\r\nlabel2:\r\nfor (var i = 0; i < 10; i++) {\r\nbreak label2\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Document" } ], expected: "\r\nfunction f() {\r\n label0:\r\n for (var i = 0; i < 10; i++) {\r\n label1: {\r\n for (var i = 0; i < 10; i++)\r\n x = 2;\r\n label2:\r\n for (var i = 0; i < 10; i++) {\r\n break label2\r\n }\r\n }\r\n }\r\n}" },
|
||||
{ input: "function f() {\r\nstring='string'}", operations: [ { operation: "CloseBrace", point: { position: 32 } } ], expected: "function f() {\r\n string = 'string'\n}" },
|
||||
{ input: "\r\nfunction a() {\r\nfunction test() /* test */\r\n{\r\nif (test) /* test */\r\n{\r\n}\r\n}\r\n}", operations: [ { operation: "Document" } ], expected: "\r\nfunction a() {\r\n function test() /* test */ {\r\n if (test) /* test */ {\r\n }\r\n }\r\n}" },
|
||||
{ input: "that = {\r\n method: function () {\r\n return this.datum;\r\n } , \r\n\r\n datum: 0\r\n};", operations: [ { operation: "Enter", point: { position: 98 } } ], expected: "that = {\r\n method: function () {\r\n return this.datum;\r\n },\r\n\r\n datum: 0\r\n};" },
|
||||
{ input: "for (; ;)\n// test\n test;", operations: [ { operation: "Document" } ], expected: "for (; ;)\n // test\n test;" },
|
||||
{ input: "(function () {\r\n a({\r\n b: 0\r\n });\r\n\r\n})();", operations: [ { operation: "Enter", point: { position: 50 } } ], expected: "(function () {\r\n a({\r\n b: 0\r\n });\r\n\r\n})();" },
|
||||
{ input: "var f = function () {\n mycanvas.onmousedown = function () {\n };\n\n}", operations: [ { operation: "Enter", point: { position: 70 } } ], expected: "var f = function () {\n mycanvas.onmousedown = function () {\n };\n\n}" },
|
||||
{ input: "var obj={a:{b:2,c:{d:{e:{}}}}};", operations: [ { operation: "Semicolon", point: { position: 31 } } ], expected: "var obj = { a: { b: 2, c: { d: { e: {} } } } };" },
|
||||
{ input: "if (1)\r\n x++;\r\nelse x--;", operations: [ { operation: "Document" } ], expected: "if (1)\r\n x++;\r\nelse x--;" },
|
||||
{ input: "do{\r\nfor(var i=0;i<10;i++)i-=2}while(1!==1)", operations: [ { operation: "Enter", point: { position: 5 } } ], expected: "do {\r\n for (var i = 0; i < 10; i++) i -= 2\n} while (1 !== 1)" },
|
||||
{ input: "switch (a){\r\n case 1,2,3:\r\n break;\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "switch (a) {\r\n case 1, 2, 3:\r\n break;\r\n}\r\n" },
|
||||
{ input: " foo(function (file) {\r\n return 0\r\n })\r\n .then(function (doc) {\r\n return 1\r\n });", operations: [ { operation: "Document" } ], expected: "foo(function (file) {\r\n return 0\r\n})\r\n .then(function (doc) {\r\n return 1\r\n });" },
|
||||
{ input: "var a = 1;\nvar f = function () {\n var b = 2;\n}\n", operations: [ { operation: "Enter", point: { position: 50 } } ], expected: "var a = 1;\nvar f = function () {\n var b = 2;\n}\n" },
|
||||
{ input: "do{for(var i=0;i<10;i++)i-=2}\r\nwhile(1!==1)", operations: [ { operation: "Enter", point: { position: 31 } } ], expected: "do { for (var i = 0; i < 10; i++) i -= 2 }\r\nwhile (1 !== 1)" },
|
||||
{ input: " function a( b,c ) \r\n {\r\n var d=0 ;\r\n }", operations: [ { operation: "Document" } ], expected: "function a(b, c) {\r\n var d = 0;\r\n}" },
|
||||
{ input: "function f() {\r\n /*\r\n */ var x\r\n\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 59 } } ], expected: "function f() {\r\n /*\r\n */ var x\r\n\r\n\r\n}" },
|
||||
{ input: "if (x!=1^y===2) x+=2\r\n", operations: [ { operation: "Enter", point: { position: 24 } } ], expected: "if (x != 1 ^ y === 2) x += 2\r\n" },
|
||||
{ input: "function f() {\n }", operations: [ { operation: "Enter", point: { position: 15 } } ], expected: "function f() {\n}" },
|
||||
{ input: "function test() {\r\n try { }\r\n catch (e) { }\r\n finally\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n try { }\r\n catch (e) { }\r\n finally\r\n }" },
|
||||
{ input: "a = [\n // test\n foo(\n // test\n 1),\n 2\n];", operations: [ { operation: "Document" } ], expected: "a = [\n // test\n foo(\n // test\n 1),\n 2\n];" },
|
||||
{ input: "if (x!=1^y===2) x+=2;", operations: [ { operation: "Semicolon", point: { position: 23 } } ], expected: "if (x != 1 ^ y === 2) x += 2;" },
|
||||
{ input: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n}finally {\r\nx+=2\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 71 } } ], expected: "function foo() {\r\ntry {\r\nx+=2\r\n}\r\ncatch( e){\r\nx+=2\r\n} finally {\r\n x += 2\r\n}\r\n}" },
|
||||
{ input: "switch (a) {\n case 1: b++;\n break;\n\n default: a++;\n break;\n}", operations: [ { operation: "Enter", point: { position: 46 } } ], expected: "switch (a) {\n case 1: b++;\n break;\n\n default: a++;\n break;\n}" },
|
||||
{ input: "function test() { }\r\n", operations: [ { operation: "Enter", point: { position: 27 } } ], expected: "function test() { }\r\n" },
|
||||
{ input: "delete x;", operations: [ { operation: "Document" } ], expected: "delete x;" },
|
||||
{ input: "\r\n{\r\n\r\nvar a,\r\n b;\r\n\r\nx = {\r\na: 1 +\r\n 2\r\n}\r\n\r\na(1,\r\n 2).\r\n test();\r\n\r\nfunction foo(a, b,\r\n c) {\r\n}\r\n\r\nfor (i = 0;\r\n i < 1;\r\n i++) {\r\n}\r\n\r\nfor (a\r\n in b) {\r\n}\r\n\r\nwhile (i +\r\n 2) {\r\n}\r\n\r\nswitch (i +\r\n 2) {\r\n\r\n case 1 +\r\n 3:\r\n break;\r\n}\r\n\r\ntry {\r\n}\r\ncatch (\r\n e) {\r\n}\r\n\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\n{\r\n\r\n var a,\r\n b;\r\n\r\n x = {\r\n a: 1 +\r\n 2\r\n }\r\n\r\n a(1,\r\n 2).\r\n test();\r\n\r\n function foo(a, b,\r\n c) {\r\n }\r\n\r\n for (i = 0;\r\n i < 1;\r\n i++) {\r\n }\r\n\r\n for (a\r\n in b) {\r\n }\r\n\r\n while (i +\r\n 2) {\r\n }\r\n\r\n switch (i +\r\n 2) {\r\n\r\n case 1 +\r\n 3:\r\n break;\r\n }\r\n\r\n try {\r\n }\r\n catch (\r\n e) {\r\n }\r\n\r\n}\r\n" },
|
||||
{ input: "function f() {\r\n do{\r\nx++ }\r\n}", operations: [ { operation: "CloseBrace", point: { position: 30 } } ], expected: "function f() {\r\n do {\r\n x++\n }\r\n}" },
|
||||
{ input: "do\r\n{for(var i=0;i<10;i++)i-=2}while(1!==1)", operations: [ { operation: "Enter", point: { position: 4 } } ], expected: "do\r\n{ for (var i = 0; i < 10; i++) i -= 2 } while (1 !== 1)" },
|
||||
{ input: "switch (a){\r\n case 1 :\r\n x+=2\r\n case 2:{\r\n }\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 28 } } ], expected: "switch (a){\r\n case 1:\r\n x += 2\r\n case 2:{\r\n }\r\n}\r\n" },
|
||||
{ input: "var x = [\n //comment\n 1,\n 2,\n 3\n]", operations: [ { operation: "Document" } ], expected: "var x = [\n //comment\n 1,\n 2,\n 3\n]" },
|
||||
{ input: "switch (a){\r\n case 1: x += 2;\r\n\r\ncase 1 : x+=2;\r\n}\r\n", operations: [ { operation: "Enter", point: { position: 36 } } ], expected: "switch (a){\r\n case 1: x += 2;\r\n\r\n case 1: x += 2;\r\n}\r\n" },
|
||||
{ input: " foo(function (file) {\r\n return 0\r\n }).then(function (doc) {\r\n return 1\r\n });", operations: [ { operation: "Document" } ], expected: "foo(function (file) {\r\n return 0\r\n}).then(function (doc) {\r\n return 1\r\n});" },
|
||||
{ input: "function f() {\r\nvar s=1 /**/;\r\n}", operations: [ { operation: "Semicolon", point: { position: 30 } } ], expected: "function f() {\r\n var s = 1 /**/;\r\n}" },
|
||||
{ input: "switch (a){\r\n case 1: x+=2;\r\n case 2:{\r\n }\r\n \r\n}", operations: [ { operation: "Enter", point: { position: 61 } } ], expected: "switch (a){\r\n case 1: x+=2;\r\n case 2:{\r\n }\r\n\r\n}" },
|
||||
{ input: "if(1)\r\nif(1)\r\nx++\r\nelse\r\nif(1)\r\nx+=2\r\nelse\r\nx+=2\r\n\r\n\r\n\r\n;", operations: [ { operation: "Semicolon", point: { position: 57 } } ], expected: "if (1)\r\n if (1)\r\n x++\r\n else\r\n if (1)\r\n x += 2\r\n else\r\n x += 2\r\n\r\n\r\n\r\n;" },
|
||||
{ input: "function a() {\r\nvar b = 0;//\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "function a() {\r\n var b = 0;//\r\n\r\n}" },
|
||||
{ input: "if (a)\r\ntest;\r\nelse\r\nif (b)\r\ntest;", operations: [ { operation: "Document" } ], expected: "if (a)\r\n test;\r\nelse\r\n if (b)\r\n test;" },
|
||||
{ input: "for(var j=0;j<10;j++)j-=i;", operations: [ { operation: "Semicolon", point: { position: 26 } } ], expected: "for (var j = 0; j < 10; j++) j -= i;" },
|
||||
{ input: "if(1)\r\nif(1)\r\nx++\r\nelse\r\nif(1)\r\nx+=2\r\nelse\r\nx+=2;", operations: [ { operation: "Semicolon", point: { position: 49 } } ], expected: "if (1)\r\n if (1)\r\n x++\r\n else\r\n if (1)\r\n x += 2\r\n else\r\n x += 2;" },
|
||||
{ input: "function test() {\r\n var a\r\n }", operations: [ { operation: "Document" } ], expected: "function test() {\r\n var a\r\n}" },
|
||||
{ input: "if (1) {\r\n} else { }", operations: [ { operation: "Document" } ], expected: "if (1) {\r\n} else { }" },
|
||||
{ input: "function f() {\r\n /*\r\n\r\n */\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "function f() {\r\n /*\r\n\r\n */\r\n}" },
|
||||
{ input: "if (x!=1^y===2) \r\n x+=2", operations: [ { operation: "Enter", point: { position: 18 } } ], expected: "if (x != 1 ^ y === 2)\r\n x += 2" },
|
||||
{ input: "for (a in b) {\n for (c in d) {\n for (e in f) {\n for (q in w) {}}}}\n", operations: [ { operation: "Enter", point: { position: 88 } } ], expected: "for (a in b) {\n for (c in d) {\n for (e in f) {\n for (q in w) { }\n }\n }\n}\n" },
|
||||
{ input: "a=a+\nb+\n c+\n d +\ne +\nm+f;", operations: [ { operation: "Semicolon", point: { position: 100 } } ], expected: "a = a +\nb +\n c +\n d +\ne +\nm + f;" },
|
||||
{ input: "x = {\r\n get a() {\r\n\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "x = {\r\n get a() {\r\n\r\n }\r\n}" },
|
||||
{ input: "if(1)\r\n;", operations: [ { operation: "Enter", point: { position: 7 } } ], expected: "if (1)\r\n ;" },
|
||||
{ input: "function test() {\r\n return (\r\n [\r\n 1\r\n ]\r\n );\r\n}", operations: [ { operation: "Document" } ], expected: "function test() {\r\n return (\r\n [\r\n 1\r\n ]\r\n );\r\n}" },
|
||||
{ input: "string='string+=2\\r\n'", operations: [ { operation: "Enter", point: { position: 20 } } ], expected: "string = 'string+=2\\r\n'" },
|
||||
{ input: "if(1)\r\nif(1)\r\nx++\r\nelse\r\n{if(1)\r\nx+=2\r\nelse\r\nx+=2}", operations: [ { operation: "CloseBrace", point: { position: 50 } } ], expected: "if(1)\r\n if (1)\r\n x++\r\n else {\n if (1)\r\n x += 2\r\n else\r\n x += 2\n }" },
|
||||
{ input: " function test() { function foo() { function foo3() { function foo4() { function foo5() { function foo6()\r\n{\r\n}\r\n}\r\n}\r\n}\r\n}\r\n}", operations: [ { operation: "Selection", span: { start: 110, length: 19 } } ], expected: " function test() { function foo() { function foo3() { function foo4() { function foo5() { function foo6()\r\n {\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }" },
|
||||
{ input: "switch (a){\r\n case 1: x+=2;\r\n case 2 : { x+=2;}\r\n}\r\n", operations: [ { operation: "Semicolon", point: { position: 53 } } ], expected: "switch (a){\r\n case 1: x+=2;\r\n case 2: { x += 2;}\r\n}\r\n" },
|
||||
{ input: "// ", operations: [ { operation: "Document" } ], expected: "// " },
|
||||
{ input: "for(var i=0;\r\ni<10;i++){for(var j=0;j<10;j++){j-=i}}", operations: [ { operation: "Enter", point: { position: 14 } } ], expected: "for (var i = 0;\r\ni < 10; i++) { for (var j = 0; j < 10; j++) { j -= i } }" },
|
||||
{ input: "if (a) if (b) if (c) if (d)\r\ntest;", operations: [ { operation: "Document" } ], expected: "if (a) if (b) if (c) if (d)\r\n test;" },
|
||||
{ input: "do{for(var i=0;i<10;i++)i-=2}while(1!==1)", operations: [ { operation: "Semicolon", point: { position: 15 } } ], expected: "do { for (var i = 0;i<10;i++)i-=2}while(1!==1)" },
|
||||
{ input: "$ ( '#TextBox1' ) . unbind ( ) ;", operations: [ { operation: "Document" } ], expected: "$('#TextBox1').unbind();" },
|
||||
{ input: "do{do{do{}while(a!==b)}while(a!==b)}while(a!==b);", operations: [ { operation: "Semicolon", point: { position: 49 } } ], expected: "do { do { do { } while (a !== b) } while (a !== b) } while (a !== b);" },
|
||||
{ input: "do{for(var i=0;i<10;i++)i-=2;}while(1!==1)", operations: [ { operation: "Semicolon", point: { position: 29 } } ], expected: "do { for (var i = 0; i < 10; i++) i -= 2;}while(1!==1)" },
|
||||
{ input: "for(var i=0;i<10;i++){\r\nfor(var j=0;j<10;j++){\r\nj-=i\r\n}\r\n}", operations: [ { operation: "CloseBrace", point: { position: 55 } } ], expected: "for(var i=0;i<10;i++){\r\n for (var j = 0; j < 10; j++) {\r\n j -= i\r\n }\r\n}" },
|
||||
{ input: "function a() {\r\nfunction b() {\r\nfunction c() {\r\n}}}", operations: [ { operation: "CloseBrace", point: { position: 51 } } ], expected: "function a() {\r\n function b() {\r\n function c() {\r\n }\n }\n}" },
|
||||
{ input: " do do do do\r\n test;\r\n while (0)\r\n while (0)\r\n while (0)\r\n while (0)", operations: [ { operation: "Document" } ], expected: "do do do do\r\n test;\r\nwhile (0)\r\nwhile (0)\r\nwhile (0)\r\nwhile (0)" },
|
||||
{ input: "/**/ ", operations: [ { operation: "Document" } ], expected: "/**/" },
|
||||
{ input: "function a()\n{ var a\n}", operations: [ { operation: "Enter", point: { position: 21 } } ], expected: "function a()\n{\n var a\n}" },
|
||||
{ input: "for(var i=0;i<10;i++){for(var j=0;j<10;\r\nj++){j-=i}}", operations: [ { operation: "Enter", point: { position: 41 } } ], expected: "for (var i = 0; i < 10; i++) {\n for (var j = 0; j < 10;\r\n j++) { j -= i }\n}" },
|
||||
{ input: "function a() {\r\n if (true) {\r\n }\r\n\r\n}", operations: [ { operation: "Enter", point: { position: 40 } } ], expected: "function a() {\r\n if (true) {\r\n }\r\n\r\n}" },
|
||||
{ input: "string='string+=2'\r\n", operations: [ { operation: "Enter", point: { position: 20 } } ], expected: "string = 'string+=2'\r\n" },
|
||||
{ input: "for (a in b) {\r\nx++;}\r\n", operations: [ { operation: "Enter", point: { position: 23 } } ], expected: "for (a in b) {\r\n x++;\n}\r\n" },
|
||||
{ input: "var obj={a:{b:2,c:{\r\nd:{e:{}}}}}", operations: [ { operation: "Enter", point: { position: 21 } } ], expected: "var obj = {\n a: {\n b: 2, c: {\r\n d: { e: {} }\n }\n }\n}" },
|
||||
{ input: "\r\n// test\r\n\r\n{\r\n// test\r\n}\r\n\r\nfunction foo() {\r\n// test\r\n\r\nswitch (a) {\r\n// test\r\ncase 1:\r\n// test\r\ndefault:\r\n// test\r\n}\r\n\r\nif (false)\r\n// test\r\nifblock;\r\n\r\nif (false) {\r\n//test\r\n}\r\n\r\nif (false) test;\r\nelse\r\n// test\r\ntest;\r\n\r\nif (false) test;\r\nelse {\r\n// test\r\ntest;\r\n}\r\n\r\nfor (; ;)\r\n// test\r\ntest;\r\n\r\nfor (; ;) {\r\n// test\r\nforblock;\r\n}\r\n\r\nfor (a in b)\r\n// test\r\ntest;\r\n\r\nfor (a in b) {\r\n// test\r\ntest\r\n}\r\n\r\nwhile (false)\r\n// test\r\ntest;\r\n\r\nwhile (false) {\r\n// test\r\ntest;\r\n}\r\n\r\nwith (a) {\r\n// test\r\n}\r\n\r\ndo\r\n// test\r\ntestl\r\nwhile (false)\r\n\r\ndo {\r\n// test\r\ntest;\r\n} while (false)\r\n\r\ntry {\r\n// test\r\n} catch (e) {\r\n// test\r\n} finally {\r\n// test\r\n}\r\n\r\n(function () {\r\nvar a = function () {\r\nreturn 1;\r\n},\r\n// This is a comment inline with a multiline statement\r\nb = 2,\r\nc = 3;\r\n})();\r\n\r\n\r\nvar a = {\r\n// test\r\nx: 1,\r\ny: 2 +\r\n// test\r\n3 +\r\n4,\r\n}\r\n\r\n\r\nvar a,\r\n// test\r\nb;\r\n\r\nvar a = [\r\n// test\r\n1,\r\n2,\r\n3\r\n];\r\n\r\na = 1 +\r\n// test\r\n2;\r\n\r\n}\r\n", operations: [ { operation: "Document" } ], expected: "\r\n// test\r\n\r\n{\r\n // test\r\n}\r\n\r\nfunction foo() {\r\n // test\r\n\r\n switch (a) {\r\n // test\r\n case 1:\r\n // test\r\n default:\r\n // test\r\n }\r\n\r\n if (false)\r\n // test\r\n ifblock;\r\n\r\n if (false) {\r\n //test\r\n }\r\n\r\n if (false) test;\r\n else\r\n // test\r\n test;\r\n\r\n if (false) test;\r\n else {\r\n // test\r\n test;\r\n }\r\n\r\n for (; ;)\r\n // test\r\n test;\r\n\r\n for (; ;) {\r\n // test\r\n forblock;\r\n }\r\n\r\n for (a in b)\r\n // test\r\n test;\r\n\r\n for (a in b) {\r\n // test\r\n test\r\n }\r\n\r\n while (false)\r\n // test\r\n test;\r\n\r\n while (false) {\r\n // test\r\n test;\r\n }\r\n\r\n with (a) {\r\n // test\r\n }\r\n\r\n do\r\n // test\r\n testl\r\n while (false)\r\n\r\n do {\r\n // test\r\n test;\r\n } while (false)\r\n\r\n try {\r\n // test\r\n } catch (e) {\r\n // test\r\n } finally {\r\n // test\r\n }\r\n\r\n (function () {\r\n var a = function () {\r\n return 1;\r\n },\r\n // This is a comment inline with a multiline statement\r\n b = 2,\r\n c = 3;\r\n })();\r\n\r\n\r\n var a = {\r\n // test\r\n x: 1,\r\n y: 2 +\r\n // test\r\n 3 +\r\n 4,\r\n }\r\n\r\n\r\n var a,\r\n // test\r\n b;\r\n\r\n var a = [\r\n // test\r\n 1,\r\n 2,\r\n 3\r\n ];\r\n\r\n a = 1 +\r\n // test\r\n 2;\r\n\r\n}\r\n" },
|
||||
{ input: " \r\n /* \r\n\r\n a \r\n a\r\n a \r\n a \r\na \r\n \r\n\r\n */ \r\n ", operations: [ { operation: "Document" } ], expected: "\r\n/* \r\n\r\n a \r\n a\r\n a \r\na \r\na \r\n\r\n\r\n*/\r\n" },
|
||||
{ input: "string='{string +=2}'", operations: [ { operation: "CloseBrace", point: { position: 20 } } ], expected: "string='{string +=2}'" },
|
||||
{ input: "var obj={a:{b:2,c:{d:{e:{}}}}}\r\n", operations: [ { operation: "Enter", point: { position: 32 } } ], expected: "var obj = { a: { b: 2, c: { d: { e: {} } } } }\r\n" },
|
||||
{ input: "string='string\\r\n line2'+'other part'\r\n", operations: [ { operation: "Enter", point: { position: 47 } } ], expected: "string='string\\r\n line2' + 'other part'\r\n" },
|
||||
{ input: " switch( a)\r\n{case 1 :x+=2 ;break\r\n case 2:{\r\n }\r\n}", operations: [ { operation: "Enter", point: { position: 13 } } ], expected: "switch (a)\r\n{\n case 1: x += 2; break\r\n case 2:{\r\n }\r\n}" }
|
||||
@ -1,79 +0,0 @@
|
||||
class a {
|
||||
constructor ( n : number ) ;
|
||||
constructor ( s : string ) ;
|
||||
constructor ( ns : any ) {
|
||||
|
||||
}
|
||||
|
||||
public pgF ( ) { } ;
|
||||
|
||||
public pv ;
|
||||
public get d ( ) {
|
||||
return 30 ;
|
||||
}
|
||||
public set d ( ) {
|
||||
}
|
||||
|
||||
public static get p2 ( ) {
|
||||
return { x : 30 , y : 40 } ;
|
||||
}
|
||||
|
||||
private static d2 ( ) {
|
||||
}
|
||||
private static get p3 ( ) {
|
||||
return "string" ;
|
||||
}
|
||||
private pv3 ;
|
||||
|
||||
private foo ( n : number ) : string ;
|
||||
private foo ( s : string ) : string ;
|
||||
private foo ( ns : any ) {
|
||||
return ns.toString ( ) ;
|
||||
}
|
||||
}
|
||||
|
||||
class b extends a {
|
||||
}
|
||||
|
||||
class m1b {
|
||||
|
||||
}
|
||||
|
||||
interface m1ib {
|
||||
|
||||
}
|
||||
class c extends m1b {
|
||||
}
|
||||
|
||||
class ib2 implements m1ib {
|
||||
}
|
||||
|
||||
declare class aAmbient {
|
||||
constructor ( n : number ) ;
|
||||
constructor ( s : string ) ;
|
||||
public pgF ( ) : void ;
|
||||
public pv ;
|
||||
public d : number ;
|
||||
static p2 : { x : number ; y : number ; } ;
|
||||
static d2 ( ) ;
|
||||
static p3 ;
|
||||
private pv3 ;
|
||||
private foo ( s ) ;
|
||||
}
|
||||
|
||||
class d {
|
||||
private foo ( n : number ) : string ;
|
||||
private foo ( ns : any ) {
|
||||
return ns.toString ( ) ;
|
||||
}
|
||||
private foo ( s : string ) : string ;
|
||||
}
|
||||
|
||||
class e {
|
||||
private foo ( ns : any ) {
|
||||
return ns.toString ( ) ;
|
||||
}
|
||||
private foo ( s : string ) : string ;
|
||||
private foo ( n : number ) : string ;
|
||||
}
|
||||
|
||||
@ -1,79 +0,0 @@
|
||||
class a {
|
||||
constructor(n: number);
|
||||
constructor(s: string);
|
||||
constructor(ns: any) {
|
||||
|
||||
}
|
||||
|
||||
public pgF() { };
|
||||
|
||||
public pv;
|
||||
public get d() {
|
||||
return 30;
|
||||
}
|
||||
public set d() {
|
||||
}
|
||||
|
||||
public static get p2() {
|
||||
return { x: 30, y: 40 };
|
||||
}
|
||||
|
||||
private static d2() {
|
||||
}
|
||||
private static get p3() {
|
||||
return "string";
|
||||
}
|
||||
private pv3;
|
||||
|
||||
private foo(n: number): string;
|
||||
private foo(s: string): string;
|
||||
private foo(ns: any) {
|
||||
return ns.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class b extends a {
|
||||
}
|
||||
|
||||
class m1b {
|
||||
|
||||
}
|
||||
|
||||
interface m1ib {
|
||||
|
||||
}
|
||||
class c extends m1b {
|
||||
}
|
||||
|
||||
class ib2 implements m1ib {
|
||||
}
|
||||
|
||||
declare class aAmbient {
|
||||
constructor(n: number);
|
||||
constructor(s: string);
|
||||
public pgF(): void;
|
||||
public pv;
|
||||
public d: number;
|
||||
static p2: { x: number; y: number; };
|
||||
static d2();
|
||||
static p3;
|
||||
private pv3;
|
||||
private foo(s);
|
||||
}
|
||||
|
||||
class d {
|
||||
private foo(n: number): string;
|
||||
private foo(ns: any) {
|
||||
return ns.toString();
|
||||
}
|
||||
private foo(s: string): string;
|
||||
}
|
||||
|
||||
class e {
|
||||
private foo(ns: any) {
|
||||
return ns.toString();
|
||||
}
|
||||
private foo(s: string): string;
|
||||
private foo(n: number): string;
|
||||
}
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
class foo {
|
||||
constructor (n?: number, m? = 5, o?: string = "") { }
|
||||
x:number = 1?2:3;
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
class foo {
|
||||
constructor(n?: number, m? = 5, o?: string = "") { }
|
||||
x: number = 1 ? 2 : 3;
|
||||
}
|
||||
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