Merge branch 'master' into fallthrough

This commit is contained in:
Andy Hanson
2017-04-12 10:58:03 -07:00
5117 changed files with 35527 additions and 34784 deletions
+26 -3
View File
@@ -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
+23
View File
@@ -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
+33 -33
View File
@@ -175,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" }))
@@ -275,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,
@@ -304,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,
@@ -335,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,
@@ -383,8 +383,8 @@ 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())
@@ -394,15 +394,15 @@ gulp.task(builtLocalCompiler, false, [servicesFile], () => {
.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");
@@ -428,8 +428,8 @@ gulp.task(servicesFile, false, ["lib", "generate-diagnostics"], () => {
// 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())
@@ -441,8 +441,8 @@ 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())
@@ -454,8 +454,8 @@ gulp.task(typingsInstallerJs, false, [servicesFile], () => {
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())
@@ -468,7 +468,7 @@ gulp.task(serverFile, false, [servicesFile, typingsInstallerJs, cancellationToke
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())
@@ -479,7 +479,7 @@ gulp.task(tsserverLibraryFile, false, [servicesFile], (done) => {
js.pipe(prependCopyright())
.pipe(sourcemaps.write("."))
.pipe(gulp.dest("src/server")),
dts.pipe(prependCopyright(/*outputCopyright*/true))
dts.pipe(prependCopyright(/*outputCopyright*/ true))
.pipe(insert.transform((content) => {
return content + "\r\nexport = ts;\r\nexport as namespace ts;";
}))
@@ -497,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);
@@ -509,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 + "\"";
@@ -525,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);
@@ -541,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");
@@ -550,8 +550,8 @@ 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())
@@ -724,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))
@@ -757,7 +757,7 @@ gulp.task("browserify", "Runs browserify on run.js to produce a file suitable fo
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)
@@ -775,7 +775,7 @@ 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 }))
@@ -889,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);
@@ -909,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);
@@ -927,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);
@@ -940,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);
+1 -1
View File
@@ -946,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() {
+78 -46
View File
@@ -2,62 +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): string {
const current = currently ? ` (currently '${currently}')` : "";
return `Tag boolean argument as '${name}'${current}`;
}
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
// Cheat to get type checker
const program = ts.createProgram([sourceFile.fileName], Lint.createCompilerOptions());
const checker = program.getTypeChecker();
return this.applyWithFunction(program.getSourceFile(sourceFile.fileName), ctx => walk(ctx, checker));
return this.applyWithFunction(sourceFile, ctx => walk(ctx));
}
}
function walk(ctx: Lint.WalkContext<void>, checker: ts.TypeChecker): void {
ts.forEachChild(ctx.sourceFile, recur);
function recur(node: ts.Node): void {
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);
}
});
function checkCall(node: ts.CallExpression): void {
if (!node.arguments || !node.arguments.some(arg => arg.kind === ts.SyntaxKind.TrueKeyword || arg.kind === ts.SyntaxKind.FalseKeyword)) {
return;
}
const targetCallSignature = checker.getResolvedSignature(node);
if (!targetCallSignature) {
return;
}
const targetParameters = targetCallSignature.getParameters();
for (let index = 0; index < targetParameters.length; index++) {
const param = targetParameters[index];
const arg = node.arguments[index];
if (!(arg && param)) {
continue;
}
const argType = 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 | undefined;
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 + ":") {
ctx.addFailureAtNode(arg, Rule.FAILURE_STRING_FACTORY(param.getName(), triviaContent));
}
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;
}
let 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;
}
}
}
+47 -34
View File
@@ -259,7 +259,7 @@ 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=";
@@ -418,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 {
@@ -447,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);
}
}
}
@@ -703,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);
}
@@ -1545,7 +1546,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 {
@@ -1721,7 +1722,7 @@ namespace ts {
blockScopeContainer.locals = createMap<Symbol>();
addToContainerChain(blockScopeContainer);
}
declareSymbol(blockScopeContainer.locals, undefined, node, symbolFlags, symbolExcludes);
declareSymbol(blockScopeContainer.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
}
}
@@ -1855,7 +1856,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));
}
}
@@ -1911,7 +1912,9 @@ namespace ts {
// 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.
bindJSDocTypedefTagIfAny(node);
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
@@ -2019,30 +2022,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.Property:
bindStaticPropertyAssignment(<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:
@@ -2334,7 +2335,7 @@ namespace ts {
function bindThisPropertyAssignment(node: BinaryExpression) {
Debug.assert(isInJavaScriptFile(node));
const container = getThisContainer(node, /*includeArrowFunctions*/false);
const container = getThisContainer(node, /*includeArrowFunctions*/ false);
switch (container.kind) {
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
@@ -2424,7 +2425,7 @@ namespace ts {
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);
}
}
@@ -3331,6 +3332,18 @@ 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) {
+468 -342
View File
File diff suppressed because it is too large Load Diff
+23 -17
View File
@@ -153,6 +153,12 @@ namespace ts {
category: Diagnostics.Basic_Options,
description: Diagnostics.Allow_javascript_files_to_be_compiled
},
{
name: "checkJs",
type: "boolean",
category: Diagnostics.Basic_Options,
description: Diagnostics.Report_errors_in_js_files
},
{
name: "jsx",
type: createMapFromTemplate({
@@ -854,9 +860,9 @@ namespace ts {
}
/**
* Read tsconfig.json file
* @param fileName The path to the config file
*/
* Read tsconfig.json file
* @param fileName The path to the config file
*/
export function readConfigFile(fileName: string, readFile: (path: string) => string): { config?: any; error?: Diagnostic } {
let text = "";
try {
@@ -869,10 +875,10 @@ namespace ts {
}
/**
* Parse the text of the tsconfig.json file
* @param fileName The path to the config file
* @param jsonText The text of the config file
*/
* Parse the text of the tsconfig.json file
* @param fileName The path to the config file
* @param jsonText The text of the config file
*/
export function parseConfigFileTextToJson(fileName: string, jsonText: string, stripComments = true): { config?: any; error?: Diagnostic } {
try {
const jsonTextToParse = stripComments ? removeComments(jsonText) : jsonText;
@@ -889,7 +895,7 @@ namespace ts {
* @param fileNames array of filenames to be generated into tsconfig.json
*/
/* @internal */
export function generateTSConfig(options: CompilerOptions, fileNames: string[]): string {
export function generateTSConfig(options: CompilerOptions, fileNames: string[], newLine: string): string {
const compilerOptions = extend(options, defaultInitCompilerOptions);
const configurations: { compilerOptions: MapLike<CompilerOptionsValue>; files?: string[] } = {
compilerOptions: serializeCompilerOptions(compilerOptions)
@@ -1047,7 +1053,7 @@ namespace ts {
}
result.push(`}`);
return result.join(sys.newLine);
return result.join(newLine);
}
}
@@ -1077,12 +1083,12 @@ namespace ts {
}
/**
* Parse the contents of a config file (tsconfig.json).
* @param json The contents of the config file to parse
* @param host Instance of ParseConfigHost used to enumerate files in folder.
* @param basePath A root directory to resolve relative path entries in the config
* file to. e.g. outDir
*/
* Parse the contents of a config file (tsconfig.json).
* @param json The contents of the config file to parse
* @param host Instance of ParseConfigHost used to enumerate files in folder.
* @param basePath A root directory to resolve relative path entries in the config
* file to. e.g. outDir
*/
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}, configFileName?: string, resolutionStack: Path[] = [], extraFileExtensions: JsFileExtensionInfo[] = []): ParsedCommandLine {
const errors: Diagnostic[] = [];
basePath = normalizeSlashes(basePath);
@@ -1164,7 +1170,7 @@ namespace ts {
const relativeDifference = convertToRelativePath(extendedDirname, basePath, getCanonicalFileName);
const updatePath: (path: string) => string = path => isRootedDiskPath(path) ? path : combinePaths(relativeDifference, path);
// Merge configs (copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios)
const result = parseJsonConfigFileContent(extendedResult.config, host, extendedDirname, /*existingOptions*/undefined, getBaseFileName(extendedConfigPath), resolutionStack.concat([resolvedPath]));
const result = parseJsonConfigFileContent(extendedResult.config, host, extendedDirname, /*existingOptions*/ undefined, getBaseFileName(extendedConfigPath), resolutionStack.concat([resolvedPath]));
errors.push(...result.errors);
const [include, exclude, files] = map(["include", "exclude", "files"], key => {
if (!json[key] && extendedResult.config[key]) {
@@ -1574,7 +1580,7 @@ namespace ts {
delete wildcardDirectories[key];
}
}
};
}
}
return wildcardDirectories;
+1 -1
View File
@@ -411,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
+7 -3
View File
@@ -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
@@ -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;
}
}
+1 -1
View File
@@ -590,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);
}
+26
View File
@@ -1827,6 +1827,10 @@
"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
@@ -3480,6 +3484,24 @@
"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
@@ -3487,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
}
}
+75 -33
View File
@@ -204,7 +204,6 @@ namespace ts {
} = handlers;
const newLine = getNewLineCharacter(printerOptions);
const languageVersion = getEmitScriptTarget(printerOptions);
const comments = createCommentWriter(printerOptions, onEmitSourceMapOfPosition);
const {
emitNodeWithComments,
@@ -276,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);
@@ -287,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;
@@ -737,15 +740,6 @@ namespace ts {
return node && substituteNode && substituteNode(hint, node) || node;
}
function emitBodyIndirect(node: Node, elements: NodeArray<Node>, emitCallback: (node: Node) => void): void {
if (emitBodyWithDetachedComments) {
emitBodyWithDetachedComments(node, elements, emitCallback);
}
else {
emitCallback(node);
}
}
function emitHelpersIndirect(node: Node) {
if (onEmitHelpers) {
onEmitHelpers(node, writeLines);
@@ -1089,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) {
@@ -1123,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)) {
@@ -1663,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);
@@ -2072,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();
}
@@ -2095,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
@@ -2112,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);
@@ -2595,7 +2637,7 @@ namespace ts {
}
}
return getLiteralText(node, currentSourceFile, languageVersion);
return getLiteralText(node, currentSourceFile);
}
/**
+4 -7
View File
@@ -88,6 +88,7 @@ namespace ts {
export function createNumericLiteral(value: string): NumericLiteral {
const node = <NumericLiteral>createSynthesizedNode(SyntaxKind.NumericLiteral);
node.text = value;
node.numericLiteralFlags = 0;
return node;
}
@@ -3365,17 +3366,14 @@ namespace ts {
*/
export function parenthesizeForAccess(expression: Expression): LeftHandSideExpression {
// isLeftHandSideExpression is almost the correct criterion for when it is not necessary
// to parenthesize the expression before a dot. The known exceptions are:
// to parenthesize the expression before a dot. The known exception is:
//
// NewExpression:
// new C.x -> not the same as (new C).x
// NumericLiteral
// 1.x -> not the same as (1).x
//
const emittedExpression = skipPartiallyEmittedExpressions(expression);
if (isLeftHandSideExpression(emittedExpression)
&& (emittedExpression.kind !== SyntaxKind.NewExpression || (<NewExpression>emittedExpression).arguments)
&& emittedExpression.kind !== SyntaxKind.NumericLiteral) {
&& (emittedExpression.kind !== SyntaxKind.NewExpression || (<NewExpression>emittedExpression).arguments)) {
return <LeftHandSideExpression>expression;
}
@@ -3491,8 +3489,7 @@ namespace ts {
}
export function parenthesizeConciseBody(body: ConciseBody): ConciseBody {
const emittedBody = skipPartiallyEmittedExpressions(body);
if (emittedBody.kind === SyntaxKind.ObjectLiteralExpression) {
if (!isBlock(body) && getLeftmostExpression(body).kind === SyntaxKind.ObjectLiteralExpression) {
return setTextRange(createParen(<Expression>body), body);
}
+10 -10
View File
@@ -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 };
}
@@ -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 });
}
}
+31 -18
View File
@@ -1267,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));
}
@@ -1844,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> {
@@ -2030,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);
}
@@ -2134,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);
}
@@ -3043,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();
@@ -3813,7 +3809,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);
@@ -4662,6 +4658,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();
@@ -5818,11 +5819,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
@@ -5884,6 +5886,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
};
}
}
}
@@ -5891,6 +5903,7 @@ namespace ts {
sourceFile.typeReferenceDirectives = typeReferenceDirectives;
sourceFile.amdDependencies = amdDependencies;
sourceFile.moduleName = amdModuleName;
sourceFile.checkJsDirective = checkJsDirective;
}
function setExternalModuleIndicator(sourceFile: SourceFile) {
@@ -6517,7 +6530,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) {
+37 -7
View File
@@ -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) {
@@ -911,17 +912,42 @@ namespace ts {
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[] = [];
@@ -1192,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];
@@ -1265,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 {
@@ -1722,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"));
+12 -2
View File
@@ -23,6 +23,8 @@ namespace ts {
isIdentifier(): boolean;
isReservedWord(): boolean;
isUnterminated(): boolean;
/* @internal */
getNumericLiteralFlags(): NumericLiteralFlags;
reScanGreaterToken(): SyntaxKind;
reScanSlashToken(): SyntaxKind;
reScanTemplateToken(): SyntaxKind;
@@ -736,11 +738,11 @@ namespace ts {
}
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 */
@@ -802,6 +804,7 @@ namespace ts {
let precedingLineBreak: boolean;
let hasExtendedUnicodeEscape: boolean;
let tokenIsUnterminated: boolean;
let numericLiteralFlags: NumericLiteralFlags;
setText(text, start, length);
@@ -817,6 +820,7 @@ namespace ts {
isIdentifier: () => token === SyntaxKind.Identifier || token > SyntaxKind.LastReservedWord,
isReservedWord: () => token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord,
isUnterminated: () => tokenIsUnterminated,
getNumericLiteralFlags: () => numericLiteralFlags,
reScanGreaterToken,
reScanSlashToken,
reScanTemplateToken,
@@ -853,6 +857,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++;
@@ -1224,6 +1229,7 @@ namespace ts {
hasExtendedUnicodeEscape = false;
precedingLineBreak = false;
tokenIsUnterminated = false;
numericLiteralFlags = 0;
while (true) {
tokenPos = pos;
if (pos >= end) {
@@ -1422,6 +1428,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)) {
@@ -1432,6 +1439,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)) {
@@ -1442,11 +1450,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
+7 -7
View File
@@ -54,10 +54,10 @@ 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;
export function getNodeMajorVersion() {
if (typeof process === "undefined") {
@@ -74,7 +74,7 @@ namespace ts {
return parseInt(version.substring(1, dot));
}
declare var ChakraHost: {
declare const ChakraHost: {
args: string[];
currentDirectory: string;
executingFile: string;
@@ -232,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) {
@@ -368,7 +368,7 @@ namespace ts {
if (eventName === "rename") {
// When deleting a file, the passed baseFileName is null
callback(!relativeFileName ? relativeFileName : normalizePath(combinePaths(directoryName, relativeFileName)));
};
}
}
);
},
+3 -2
View File
@@ -490,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[] = [];
@@ -517,7 +518,7 @@ namespace ts {
}
return createCall(
getHelperName("__rest"),
undefined,
/*typeArguments*/ undefined,
[
value,
setTextRange(
+33 -3
View File
@@ -315,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;
@@ -328,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;
}
@@ -466,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);
@@ -3103,7 +3109,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(
@@ -3414,6 +3420,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.
*
+1 -1
View File
@@ -1478,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);
}
+16 -11
View File
@@ -359,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);
}
}
}
@@ -1157,7 +1162,7 @@ namespace ts {
statement = createStatement(
createExportExpression(
createIdentifier("__esModule"),
createLiteral(true)
createLiteral(/*value*/ true)
)
);
}
@@ -1170,7 +1175,7 @@ namespace ts {
createIdentifier("exports"),
createLiteral("__esModule"),
createObjectLiteral([
createPropertyAssignment("value", createLiteral(true))
createPropertyAssignment("value", createLiteral(/*value*/ true))
])
]
)
+18 -12
View File
@@ -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]
});
}
}
}
@@ -1287,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) {
+3 -3
View File
@@ -2324,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);
}
+2 -2
View File
@@ -336,7 +336,7 @@ namespace ts {
// is an absolute file name.
directory == "" ? "." : directory,
watchedDirectoryChanged, /*recursive*/ true);
};
}
}
return configParseResult;
}
@@ -739,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, generateTSConfig(options, fileNames));
sys.writeFile(file, generateTSConfig(options, fileNames, sys.newLine));
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Successfully_created_a_tsconfig_json_file), /* host */ undefined);
}
+33 -16
View File
@@ -819,7 +819,7 @@ namespace ts {
body?: FunctionBody;
}
/** For when we encounter a semicolon in a class declaration. ES6 allows these as class elements.*/
/** For when we encounter a semicolon in a class declaration. ES6 allows these as class elements. */
export interface SemicolonClassElement extends ClassElement {
kind: SyntaxKind.SemicolonClassElement;
parent?: ClassDeclaration | ClassExpression;
@@ -1313,8 +1313,6 @@ namespace ts {
text: string;
isUnterminated?: boolean;
hasExtendedUnicodeEscape?: boolean;
/* @internal */
isOctalLiteral?: boolean;
}
// The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral,
@@ -1332,8 +1330,21 @@ namespace ts {
kind: SyntaxKind.NoSubstitutionTemplateLiteral;
}
/* @internal */
export const enum NumericLiteralFlags {
None = 0,
Scientific = 1 << 1, // e.g. `10e2`
Octal = 1 << 2, // e.g. `0777`
HexSpecifier = 1 << 3, // e.g. `0x00000000`
BinarySpecifier = 1 << 4, // e.g. `0b0110010000000000`
OctalSpecifier = 1 << 5, // e.g. `0o777`
BinaryOrOctalSpecifier = BinarySpecifier | OctalSpecifier,
}
export interface NumericLiteral extends LiteralExpression {
kind: SyntaxKind.NumericLiteral;
/* @internal */
numericLiteralFlags?: NumericLiteralFlags;
}
export interface TemplateHead extends LiteralLikeNode {
@@ -1386,11 +1397,11 @@ namespace ts {
}
/**
* This interface is a base interface for ObjectLiteralExpression and JSXAttributes to extend from. JSXAttributes is similar to
* ObjectLiteralExpression in that it contains array of properties; however, JSXAttributes' properties can only be
* JSXAttribute or JSXSpreadAttribute. ObjectLiteralExpression, on the other hand, can only have properties of type
* ObjectLiteralElement (e.g. PropertyAssignment, ShorthandPropertyAssignment etc.)
**/
* This interface is a base interface for ObjectLiteralExpression and JSXAttributes to extend from. JSXAttributes is similar to
* ObjectLiteralExpression in that it contains array of properties; however, JSXAttributes' properties can only be
* JSXAttribute or JSXSpreadAttribute. ObjectLiteralExpression, on the other hand, can only have properties of type
* ObjectLiteralElement (e.g. PropertyAssignment, ShorthandPropertyAssignment etc.)
*/
export interface ObjectLiteralExpressionBase<T extends ObjectLiteralElement> extends PrimaryExpression, Declaration {
properties: NodeArray<T>;
}
@@ -1402,7 +1413,7 @@ namespace ts {
multiLine?: boolean;
}
export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression;
export type EntityNameExpression = Identifier | PropertyAccessEntityNameExpression | ParenthesizedExpression;
export type EntityNameOrEntityNameExpression = EntityName | EntityNameExpression;
export interface PropertyAccessExpression extends MemberExpression, Declaration {
@@ -1952,6 +1963,10 @@ namespace ts {
fileName: string;
}
export interface CheckJsDirective extends TextRange {
enabled: boolean;
}
export type CommentKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia;
export interface CommentRange extends TextRange {
@@ -2294,6 +2309,7 @@ namespace ts {
/* @internal */ moduleAugmentations: LiteralExpression[];
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
/* @internal */ ambientModuleNames: string[];
/* @internal */ checkJsDirective: CheckJsDirective | undefined;
}
export interface Bundle extends Node {
@@ -2314,9 +2330,9 @@ namespace ts {
readDirectory(rootDir: string, extensions: string[], excludes: string[], includes: string[]): string[];
/**
* Gets a value indicating whether the specified path exists and is a file.
* @param path The path to test.
*/
* Gets a value indicating whether the specified path exists and is a file.
* @param path The path to test.
*/
fileExists(path: string): boolean;
readFile(path: string): string;
@@ -2664,8 +2680,7 @@ namespace ts {
errorModuleName?: string; // If the symbol is not visible from module, module's name
}
/** Indicates how to serialize the name for a TypeReferenceNode when emitting decorator
* metadata */
/** Indicates how to serialize the name for a TypeReferenceNode when emitting decorator metadata */
/* @internal */
export enum TypeReferenceSerializationKind {
Unknown, // The TypeReferenceNode could not be resolved. The type name
@@ -2865,6 +2880,7 @@ namespace ts {
/* @internal */
export interface TransientSymbol extends Symbol, SymbolLinks {
checkFlags: CheckFlags;
isRestParameter?: boolean;
}
export type SymbolTable = Map<Symbol>;
@@ -2894,7 +2910,7 @@ namespace ts {
ContextChecked = 0x00000400, // Contextual types have been assigned
AsyncMethodWithSuper = 0x00000800, // An async method that reads a value from a member of 'super'.
AsyncMethodWithSuperBinding = 0x00001000, // An async method that assigns a value to a member of 'super'.
CaptureArguments = 0x00002000, // Lexical 'arguments' used in body (for async functions)
CaptureArguments = 0x00002000, // Lexical 'arguments' used in body
EnumValuesComputed = 0x00004000, // Values for enum members have been computed, and any errors have been reported for them.
LexicalModuleMergesWithClass = 0x00008000, // Instantiated lexical module declaration is merged with a previous class declaration.
LoopWithCapturedBlockScopedBinding = 0x00010000, // Loop that contains block scoped variable captured in closure
@@ -2918,6 +2934,7 @@ namespace ts {
maybeTypePredicate?: boolean; // Cached check whether call expression might reference a type predicate
enumMemberValue?: number; // Constant value of enum member
isVisible?: boolean; // Is this node visible
containsArgumentsReference?: boolean; // Whether a function-like declaration contains an 'arguments' reference
hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context
jsxFlags?: JsxFlags; // flags for knowing what kind of element/attributes we're dealing with
resolvedJsxElementAttributesType?: Type; // resolved element attributes type of a JSX openinglike element
@@ -3355,6 +3372,7 @@ namespace ts {
alwaysStrict?: boolean; // Always combine with strict property
baseUrl?: string;
charset?: string;
checkJs?: boolean;
/* @internal */ configFilePath?: string;
declaration?: boolean;
declarationDir?: string;
@@ -4181,7 +4199,6 @@ namespace ts {
}
export interface PrinterOptions {
target?: ScriptTarget;
removeComments?: boolean;
newLine?: NewLineKind;
/*@internal*/ sourceMap?: boolean;
+37 -88
View File
@@ -322,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,
@@ -359,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;
}
@@ -438,9 +379,9 @@ 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. */
export function isUntypedOrShorthandAmbientModuleSymbol(moduleSymbol: Symbol): boolean {
return !moduleSymbol.declarations || isShorthandAmbientModule(moduleSymbol.valueDeclaration);
/** Given a symbol for a module, checks that it is a shorthand ambient module. */
export function isShorthandAmbientModuleSymbol(moduleSymbol: Symbol): boolean {
return isShorthandAmbientModule(moduleSymbol.valueDeclaration);
}
function isShorthandAmbientModule(node: Node): boolean {
@@ -1097,13 +1038,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;
@@ -1407,17 +1348,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) {
@@ -1453,13 +1401,10 @@ namespace ts {
/// 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;
@@ -1594,7 +1539,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);
@@ -2026,6 +1971,10 @@ namespace ts {
return false;
}
export function isNumericLiteral(node: Node): node is NumericLiteral {
return node.kind === SyntaxKind.NumericLiteral;
}
export function isStringOrNumericLiteral(node: Node): node is StringLiteral | NumericLiteral {
const kind = node.kind;
return kind === SyntaxKind.StringLiteral
@@ -4553,9 +4502,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 },
+1 -1
View File
@@ -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, () => {
+49 -11
View File
@@ -858,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");
@@ -872,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[]) {
@@ -1083,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"));
@@ -1091,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[]) {
@@ -1184,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;
@@ -1669,7 +1694,7 @@ namespace FourSlash {
if (ch === "\r") {
this.currentCaretPosition--;
}
};
}
}
private applyEdits(fileName: string, edits: ts.TextChange[], isFormattingEdit = false): number {
@@ -2180,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.
@@ -2584,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);
@@ -3161,7 +3191,7 @@ ${code}
}
// Add the remaining text
flush(undefined);
flush(/*lastSafeCharIndex*/ undefined);
if (openRanges.length > 0) {
const openRange = openRanges[0];
@@ -3509,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);
}
@@ -3637,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);
}
/**
@@ -3668,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) {
@@ -3753,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() {
@@ -3772,6 +3806,10 @@ namespace FourSlashInterface {
this.state.printCompletionListMembers();
}
public printAvailableCodeFixes() {
this.state.printAvailableCodeFixes();
}
public printBreakpointLocation(pos: number) {
this.state.printBreakpointLocation(pos);
}
+2 -2
View File
@@ -191,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];
@@ -1797,7 +1797,7 @@ namespace Harness {
if (currentFileContent === undefined) {
currentFileContent = "";
}
else {
else if (currentFileContent !== "") {
// End-of-line
currentFileContent = currentFileContent + "\n";
}
+5 -5
View File
@@ -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));
}
@@ -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 () {
+1 -1
View File
@@ -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
+3 -2
View File
@@ -1,4 +1,4 @@
{
{
"extends": "../tsconfig-base",
"compilerOptions": {
"removeComments": false,
@@ -81,6 +81,7 @@
"../services/codefixes/helpers.ts",
"../services/codefixes/importFixes.ts",
"../services/codefixes/unusedIdentifierFixes.ts",
"../services/codefixes/disableJsDiagnostics.ts",
"harness.ts",
"sourceMapRecorder.ts",
@@ -95,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",
@@ -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);
});
});
}
}
+1 -1
View File
@@ -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);`);
});
+2 -13
View File
@@ -6,22 +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) {
// normalize line endings
return initResult.replace(new RegExp(sys.newLine, "g"), "\n");
}
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);
});
});
}
+11 -11
View File
@@ -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);
});
});
+5 -7
View File
@@ -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);
+5
View File
@@ -52,6 +52,9 @@ namespace ts {
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", () => {
@@ -77,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,
@@ -94,6 +98,7 @@ namespace ts {
)
])
);
// tslint:enable boolean-trivia
printsCorrectly("class", {}, printer => printer.printNode(EmitHint.Unspecified, syntheticNode, sourceFile));
});
});
@@ -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"/>
@@ -34,7 +34,7 @@ describe("PreProcessFile:", function () {
describe("Test preProcessFiles,", function () {
it("Correctly return referenced files from triple slash", function () {
test("///<reference path = \"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\"/>" + "\n" + "///<reference path=\"refFile3.ts\" />" + "\n" + "///<reference path= \"..\\refFile4d.ts\" />",
/*readImportFile*/true,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: [{ fileName: "refFile1.ts", pos: 0, end: 37 }, { fileName: "refFile2.ts", pos: 38, end: 73 },
@@ -48,7 +48,7 @@ describe("PreProcessFile:", function () {
it("Do not return reference path because of invalid triple-slash syntax", function () {
test("///<reference path\"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\">" + "\n" + "///<referencepath=\"refFile3.ts\" />" + "\n" + "///<reference pat= \"refFile4d.ts\" />",
/*readImportFile*/true,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: <ts.FileReference[]>[],
@@ -61,7 +61,7 @@ describe("PreProcessFile:", function () {
it("Correctly return imported files", function () {
test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");",
/*readImportFile*/true,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: <ts.FileReference[]>[],
@@ -88,7 +88,7 @@ describe("PreProcessFile:", function () {
it("Do not return import path because of invalid import syntax", function () {
test("import i1 require(\"r1.ts\"); import = require(\"r2.ts\") import i3= require(\"r3.ts\"); import i5",
/*readImportFile*/true,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: <ts.FileReference[]>[],
@@ -101,7 +101,7 @@ describe("PreProcessFile:", function () {
it("Correctly return referenced files and import files", function () {
test("///<reference path=\"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\"/>" + "\n" + "import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\");",
/*readImportFile*/true,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: [{ fileName: "refFile1.ts", pos: 0, end: 35 }, { fileName: "refFile2.ts", pos: 36, end: 71 }],
@@ -114,7 +114,7 @@ describe("PreProcessFile:", function () {
it("Correctly return referenced files and import files even with some invalid syntax", function () {
test("///<reference path=\"refFile1.ts\" />" + "\n" + "///<reference path \"refFile2.ts\"/>" + "\n" + "import i1 = require(\"r1.ts\"); import = require(\"r2.ts\"); import i2 = require(\"r3.ts\");",
/*readImportFile*/true,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: [{ fileName: "refFile1.ts", pos: 0, end: 35 }],
@@ -133,7 +133,7 @@ describe("PreProcessFile:", function () {
"import {a as A} from \"m5\";" + "\n" +
"import {a as A, b, c as C} from \"m6\";" + "\n" +
"import def , {a, b, c as C} from \"m7\";" + "\n",
/*readImportFile*/true,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: [],
@@ -157,7 +157,7 @@ describe("PreProcessFile:", function () {
"export {a} from \"m2\";" + "\n" +
"export {a as A} from \"m3\";" + "\n" +
"export {a as A, b, c as C} from \"m4\";" + "\n",
/*readImportFile*/true,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: [],
@@ -194,7 +194,7 @@ describe("PreProcessFile:", function () {
it("Correctly handles export import declarations", function () {
test("export import a = require(\"m1\");",
/*readImportFile*/true,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: [],
@@ -213,7 +213,7 @@ describe("PreProcessFile:", function () {
foo(require('m3'));
var z = { f: require('m4') }
`,
/*readImportFile*/true,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ true,
{
referencedFiles: [],
@@ -233,7 +233,7 @@ describe("PreProcessFile:", function () {
define(["mod1", "mod2"], (m1, m2) => {
});
`,
/*readImportFile*/true,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ true,
{
referencedFiles: [],
@@ -251,7 +251,7 @@ describe("PreProcessFile:", function () {
define("mod", ["mod1", "mod2"], (m1, m2) => {
});
`,
/*readImportFile*/true,
/*readImportFile*/ true,
/*detectJavaScriptImports*/ true,
{
referencedFiles: [],
+3 -3
View File
@@ -326,7 +326,7 @@ namespace ts.server {
send(msg: protocol.Message) {
this.lastSent = msg;
}
};
}
it("can override methods such as send", () => {
const session = new TestSession();
@@ -367,7 +367,7 @@ namespace ts.server {
assert(this.projectService);
expect(this.projectService).to.be.instanceOf(ProjectService);
}
};
}
new ServiceSession();
});
});
@@ -462,7 +462,7 @@ namespace ts.server {
});
this.callbacks[this.seq] = callback;
}
};
}
it("can be constructed and respond to commands", (done) => {
const cli = new InProcClient();
+209 -48
View File
@@ -17,6 +17,16 @@ namespace ts.projectSystem {
})
};
const customSafeList = {
path: <Path>"/typeMapList.json",
content: JSON.stringify({
"quack": {
"match": "/duckquack-(\\d+)\\.min\\.js",
"types": ["duck-types"]
},
})
};
export interface PostExecAction {
readonly success: boolean;
readonly callback: TI.RequestCompletedAction;
@@ -174,13 +184,13 @@ namespace ts.projectSystem {
request.type = "request";
return this.executeCommand(<T>request);
}
};
}
export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler, cancellationToken?: server.ServerCancellationToken) {
export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler, cancellationToken?: server.ServerCancellationToken, throttleWaitMilliseconds?: number) {
if (typingsInstaller === undefined) {
typingsInstaller = new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host);
}
return new TestSession(host, cancellationToken || server.nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler);
return new TestSession(host, cancellationToken || server.nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler, throttleWaitMilliseconds);
}
export interface CreateProjectServiceParameters {
@@ -310,7 +320,7 @@ namespace ts.projectSystem {
register(cb: (...args: any[]) => void, args: any[]) {
const timeoutId = this.nextId;
this.nextId++;
this.map[timeoutId] = cb.bind(undefined, ...args);
this.map[timeoutId] = cb.bind(/*this*/ undefined, ...args);
return timeoutId;
}
unregister(id: any) {
@@ -381,7 +391,7 @@ namespace ts.projectSystem {
fileExists(s: string) {
const path = this.toPath(s);
return this.fs.contains(path) && isFile(this.fs.get(path));
};
}
getFileSize(s: string) {
const path = this.toPath(s);
@@ -476,11 +486,11 @@ namespace ts.projectSystem {
// TOOD: record and invoke callbacks to simulate timer events
setTimeout(callback: TimeOutCallback, _time: number, ...args: any[]) {
return this.timeoutCallbacks.register(callback, args);
};
}
clearTimeout(timeoutId: any): void {
this.timeoutCallbacks.unregister(timeoutId);
};
}
checkTimeoutQueueLength(expected: number) {
const callbacksCount = this.timeoutCallbacks.count();
@@ -501,7 +511,7 @@ namespace ts.projectSystem {
clearImmediate(timeoutId: any): void {
this.immediateCallbacks.unregister(timeoutId);
};
}
createDirectory(directoryName: string): void {
this.createFileOrFolder({ path: directoryName });
@@ -547,6 +557,49 @@ namespace ts.projectSystem {
readonly getEnvironmentVariable = notImplemented;
}
/**
* Test server cancellation token used to mock host token cancellation requests.
* The cancelAfterRequest constructor param specifies how many isCancellationRequested() calls
* should be made before canceling the token. The id of the request to cancel should be set with
* setRequestToCancel();
*/
export class TestServerCancellationToken implements server.ServerCancellationToken {
private currentId = -1;
private requestToCancel = -1;
private isCancellationRequestedCount = 0;
constructor(private cancelAfterRequest = 0) {
}
setRequest(requestId: number) {
this.currentId = requestId;
}
setRequestToCancel(requestId: number) {
this.resetToken();
this.requestToCancel = requestId;
}
resetRequest(requestId: number) {
assert.equal(requestId, this.currentId, "unexpected request id in cancellation");
this.currentId = undefined;
}
isCancellationRequested() {
this.isCancellationRequestedCount++;
// If the request id is the request to cancel and isCancellationRequestedCount
// has been met then cancel the request. Ex: cancel the request if it is a
// nav bar request & isCancellationRequested() has already been called three times.
return this.requestToCancel === this.currentId && this.isCancellationRequestedCount >= this.cancelAfterRequest;
}
resetToken() {
this.currentId = -1;
this.isCancellationRequestedCount = 0;
this.requestToCancel = -1;
}
}
export function makeSessionRequest<T>(command: string, args: T) {
const newRequest: protocol.Request = {
seq: 0,
@@ -764,7 +817,7 @@ namespace ts.projectSystem {
path: "/c/app.ts",
content: "let x = 1"
};
const makeProject = (f: FileOrFolder) => ({ projectFileName: f.path + ".csproj", rootFiles: [toExternalFile(f.path)], options: {} });
const makeProject = (f: FileOrFolder) => ({ projectFileName: f.path + ".csproj", rootFiles: [toExternalFile(f.path)], options: {} });
const p1 = makeProject(f1);
const p2 = makeProject(f2);
const p3 = makeProject(f3);
@@ -1402,6 +1455,66 @@ namespace ts.projectSystem {
checkProjectActualFiles(projectService.inferredProjects[1], [file3.path]);
});
it("ignores files excluded by a custom safe type list", () => {
const file1 = {
path: "/a/b/f1.ts",
content: "export let x = 5"
};
const office = {
path: "/lib/duckquack-3.min.js",
content: "whoa do @@ not parse me ok thanks!!!"
};
const host = createServerHost([customSafeList, file1, office]);
const projectService = createProjectService(host);
projectService.loadSafeList(customSafeList.path);
try {
projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path, office.path]) });
const proj = projectService.externalProjects[0];
assert.deepEqual(proj.getFileNames(/*excludeFilesFromExternalLibraries*/ true), [file1.path]);
assert.deepEqual(proj.getTypeAcquisition().include, ["duck-types"]);
} finally {
projectService.resetSafeList();
}
});
it("ignores files excluded by the default type list", () => {
const file1 = {
path: "/a/b/f1.ts",
content: "export let x = 5"
};
const minFile = {
path: "/c/moment.min.js",
content: "unspecified"
};
const kendoFile1 = {
path: "/q/lib/kendo/kendo.all.min.js",
content: "unspecified"
};
const kendoFile2 = {
path: "/q/lib/kendo/kendo.ui.min.js",
content: "unspecified"
};
const officeFile1 = {
path: "/scripts/Office/1/excel-15.debug.js",
content: "unspecified"
};
const officeFile2 = {
path: "/scripts/Office/1/powerpoint.js",
content: "unspecified"
};
const files = [file1, minFile, kendoFile1, kendoFile2, officeFile1, officeFile2];
const host = createServerHost(files);
const projectService = createProjectService(host);
try {
projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles(files.map(f => f.path)) });
const proj = projectService.externalProjects[0];
assert.deepEqual(proj.getFileNames(/*excludeFilesFromExternalLibraries*/ true), [file1.path]);
assert.deepEqual(proj.getTypeAcquisition().include, ["kendo-ui", "office"]);
} finally {
projectService.resetSafeList();
}
});
it("open file become a part of configured project if it is referenced from root file", () => {
const file1 = {
path: "/a/b/f1.ts",
@@ -1652,7 +1765,7 @@ namespace ts.projectSystem {
checkProjectActualFiles(projectService.inferredProjects[1], [file2.path]);
});
it ("loading files with correct priority", () => {
it("loading files with correct priority", () => {
const f1 = {
path: "/a/main.ts",
content: "let x = 1"
@@ -1677,14 +1790,14 @@ namespace ts.projectSystem {
});
projectService.openClientFile(f1.path);
projectService.checkNumberOfProjects({ configuredProjects: 1 });
checkProjectActualFiles(projectService.configuredProjects[0], [ f1.path ]);
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path]);
projectService.closeClientFile(f1.path);
projectService.openClientFile(f2.path);
projectService.checkNumberOfProjects({ configuredProjects: 1, inferredProjects: 1 });
checkProjectActualFiles(projectService.configuredProjects[0], [ f1.path ]);
checkProjectActualFiles(projectService.inferredProjects[0], [ f2.path ]);
checkProjectActualFiles(projectService.configuredProjects[0], [f1.path]);
checkProjectActualFiles(projectService.inferredProjects[0], [f2.path]);
});
it("tsconfig script block support", () => {
@@ -1720,9 +1833,9 @@ namespace ts.projectSystem {
// Open HTML file
projectService.applyChangesInOpenFiles(
/*openFiles*/[{ fileName: file2.path, hasMixedContent: true, scriptKind: ScriptKind.JS, content: `var hello = "hello";` }],
/*changedFiles*/undefined,
/*closedFiles*/undefined);
/*openFiles*/ [{ fileName: file2.path, hasMixedContent: true, scriptKind: ScriptKind.JS, content: `var hello = "hello";` }],
/*changedFiles*/ undefined,
/*closedFiles*/ undefined);
// Now HTML file is included in the project
checkNumberOfProjects(projectService, { configuredProjects: 1 });
@@ -1735,9 +1848,9 @@ namespace ts.projectSystem {
// Close HTML file
projectService.applyChangesInOpenFiles(
/*openFiles*/undefined,
/*changedFiles*/undefined,
/*closedFiles*/[file2.path]);
/*openFiles*/ undefined,
/*changedFiles*/ undefined,
/*closedFiles*/ [file2.path]);
// HTML file is still included in project
checkNumberOfProjects(projectService, { configuredProjects: 1 });
@@ -1802,7 +1915,7 @@ namespace ts.projectSystem {
// #3. Ensure no errors when compiler options aren't specified
const config3 = {
path: "/a/b/tsconfig.json",
content: JSON.stringify({ })
content: JSON.stringify({})
};
host = createServerHost([file1, file2, config3, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") });
@@ -2195,12 +2308,12 @@ namespace ts.projectSystem {
projectService.openClientFile(f1.path, "let x = 1;\nlet y = 2;");
projectService.checkNumberOfProjects({ externalProjects: 1 });
projectService.externalProjects[0].getLanguageService(/*ensureSynchronized*/false).getNavigationBarItems(f1.path);
projectService.externalProjects[0].getLanguageService(/*ensureSynchronized*/ false).getNavigationBarItems(f1.path);
projectService.closeClientFile(f1.path);
projectService.openClientFile(f1.path);
projectService.checkNumberOfProjects({ externalProjects: 1 });
const navbar = projectService.externalProjects[0].getLanguageService(/*ensureSynchronized*/false).getNavigationBarItems(f1.path);
const navbar = projectService.externalProjects[0].getLanguageService(/*ensureSynchronized*/ false).getNavigationBarItems(f1.path);
assert.equal(navbar[0].spans[0].length, f1.content.length);
});
});
@@ -3338,13 +3451,13 @@ namespace ts.projectSystem {
assert.equal((<protocol.CompileOnSaveAffectedFileListSingleProject[]>response)[0].projectUsesOutFile, expectedUsesOutFile, "usesOutFile");
}
it ("projectUsesOutFile should not be returned if not set", () => {
it("projectUsesOutFile should not be returned if not set", () => {
test({}, /*expectedUsesOutFile*/ false);
});
it ("projectUsesOutFile should be true if outFile is set", () => {
it("projectUsesOutFile should be true if outFile is set", () => {
test({ outFile: "/a/out.js" }, /*expectedUsesOutFile*/ true);
});
it ("projectUsesOutFile should be true if out is set", () => {
it("projectUsesOutFile should be true if out is set", () => {
test({ out: "/a/out.js" }, /*expectedUsesOutFile*/ true);
});
});
@@ -3384,6 +3497,7 @@ namespace ts.projectSystem {
},
resetRequest: noop
};
const session = createSession(host, /*typingsInstaller*/ undefined, /*projectServiceEventHandler*/ undefined, cancellationToken);
expectedRequestId = session.getNextSeq();
@@ -3422,24 +3536,9 @@ namespace ts.projectSystem {
})
};
let requestToCancel = -1;
const cancellationToken: server.ServerCancellationToken = (function(){
let currentId: number;
return <server.ServerCancellationToken>{
setRequest(requestId) {
currentId = requestId;
},
resetRequest(requestId) {
assert.equal(requestId, currentId, "unexpected request id in cancellation");
currentId = undefined;
},
isCancellationRequested() {
return requestToCancel === currentId;
}
};
})();
const cancellationToken = new TestServerCancellationToken();
const host = createServerHost([f1, config]);
const session = createSession(host, /*typingsInstaller*/ undefined, () => {}, cancellationToken);
const session = createSession(host, /*typingsInstaller*/ undefined, () => { }, cancellationToken);
{
session.executeCommandSeq(<protocol.OpenRequest>{
command: "open",
@@ -3472,13 +3571,13 @@ namespace ts.projectSystem {
host.clearOutput();
// cancel previously issued Geterr
requestToCancel = getErrId;
cancellationToken.setRequestToCancel(getErrId);
host.runQueuedTimeoutCallbacks();
assert.equal(host.getOutput().length, 1, "expect 1 message");
verifyRequestCompleted(getErrId, 0);
requestToCancel = -1;
cancellationToken.resetToken();
}
{
const getErrId = session.getNextSeq();
@@ -3495,12 +3594,12 @@ namespace ts.projectSystem {
assert.equal(e1.event, "syntaxDiag");
host.clearOutput();
requestToCancel = getErrId;
cancellationToken.setRequestToCancel(getErrId);
host.runQueuedImmediateCallbacks();
assert.equal(host.getOutput().length, 1, "expect 1 message");
verifyRequestCompleted(getErrId, 0);
requestToCancel = -1;
cancellationToken.resetToken();
}
{
const getErrId = session.getNextSeq();
@@ -3523,7 +3622,7 @@ namespace ts.projectSystem {
assert.equal(e2.event, "semanticDiag");
verifyRequestCompleted(getErrId, 1);
requestToCancel = -1;
cancellationToken.resetToken();
}
{
const getErr1 = session.getNextSeq();
@@ -3558,6 +3657,68 @@ namespace ts.projectSystem {
return JSON.parse(server.extractMessage(host.getOutput()[n]));
}
});
it("Lower priority tasks are cancellable", () => {
const f1 = {
path: "/a/app.ts",
content: `{ let x = 1; } var foo = "foo"; var bar = "bar"; var fooBar = "fooBar";`
};
const config = {
path: "/a/tsconfig.json",
content: JSON.stringify({
compilerOptions: {}
})
};
const cancellationToken = new TestServerCancellationToken(/*cancelAfterRequest*/ 3);
const host = createServerHost([f1, config]);
const session = createSession(host, /*typingsInstaller*/ undefined, () => { }, cancellationToken, /*throttleWaitMilliseconds*/ 0);
{
session.executeCommandSeq(<protocol.OpenRequest>{
command: "open",
arguments: { file: f1.path }
});
// send navbar request (normal priority)
session.executeCommandSeq(<protocol.NavBarRequest>{
command: "navbar",
arguments: { file: f1.path }
});
// ensure the nav bar request can be canceled
verifyExecuteCommandSeqIsCancellable(<protocol.NavBarRequest>{
command: "navbar",
arguments: { file: f1.path }
});
// send outlining spans request (normal priority)
session.executeCommandSeq(<protocol.OutliningSpansRequest>{
command: "outliningSpans",
arguments: { file: f1.path }
});
// ensure the outlining spans request can be canceled
verifyExecuteCommandSeqIsCancellable(<protocol.OutliningSpansRequest>{
command: "outliningSpans",
arguments: { file: f1.path }
});
}
function verifyExecuteCommandSeqIsCancellable<T extends server.protocol.Request>(request: Partial<T>) {
// Set the next request to be cancellable
// The cancellation token will cancel the request the third time
// isCancellationRequested() is called.
cancellationToken.setRequestToCancel(session.getNextSeq());
let operationCanceledExceptionThrown = false;
try {
session.executeCommandSeq(request);
}
catch (e) {
assert(e instanceof OperationCanceledException);
operationCanceledExceptionThrown = true;
}
assert(operationCanceledExceptionThrown, "Operation Canceled Exception not thrown for request: " + JSON.stringify(request));
}
});
});
describe("occurence highlight on string", () => {
@@ -3659,4 +3820,4 @@ namespace ts.projectSystem {
assert.isUndefined(project.getCompilerOptions().maxNodeModuleJsDepth);
});
});
}
}
+51 -4
View File
@@ -381,12 +381,12 @@ namespace ts.projectSystem {
const p = projectService.externalProjects[0];
projectService.checkNumberOfProjects({ externalProjects: 1 });
checkProjectActualFiles(p, [file1.path, file2.path]);
checkProjectActualFiles(p, [file2.path]);
installer.checkPendingCommands(/*expectedCount*/ 0);
checkNumberOfProjects(projectService, { externalProjects: 1 });
checkProjectActualFiles(p, [file1.path, file2.path]);
checkProjectActualFiles(p, [file2.path]);
});
it("external project - with type acquisition, with only js, d.ts files", () => {
@@ -692,7 +692,54 @@ namespace ts.projectSystem {
checkProjectActualFiles(p, [app.path, jqueryDTS.path]);
});
it("configured projects discover from bower.josn", () => {
it("configured projects discover from bower_components", () => {
const app = {
path: "/app.js",
content: ""
};
const jsconfig = {
path: "/jsconfig.json",
content: JSON.stringify({})
};
const jquery = {
path: "/bower_components/jquery/index.js",
content: ""
};
const jqueryPackage = {
path: "/bower_components/jquery/package.json",
content: JSON.stringify({ name: "jquery" })
};
const jqueryDTS = {
path: "/tmp/node_modules/@types/jquery/index.d.ts",
content: ""
};
const host = createServerHost([app, jsconfig, jquery, jqueryPackage]);
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation: "/tmp", typesRegistry: createTypesRegistry("jquery") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
const installedTypings = ["@types/jquery"];
const typingFiles = [jqueryDTS];
executeCommand(this, host, installedTypings, typingFiles, cb);
}
})();
const projectService = createProjectService(host, { useSingleInferredProject: true, typingsInstaller: installer });
projectService.openClientFile(app.path);
checkNumberOfProjects(projectService, { configuredProjects: 1 });
const p = projectService.configuredProjects[0];
checkProjectActualFiles(p, [app.path]);
checkWatchedFiles(host, [jsconfig.path, "/bower_components", "/node_modules"]);
installer.installAll(/*expectedCount*/ 1);
checkNumberOfProjects(projectService, { configuredProjects: 1 });
checkProjectActualFiles(p, [app.path, jqueryDTS.path]);
});
it("configured projects discover from bower.json", () => {
const app = {
path: "/app.js",
content: ""
@@ -975,7 +1022,7 @@ namespace ts.projectSystem {
}
});
it("should use cached locaitons", () => {
it("should use cached locations", () => {
const f = {
path: "/a/b/app.js",
content: ""
+1 -1
View File
@@ -98,7 +98,7 @@ namespace Utils {
useCaseSensitiveFileNames: boolean;
constructor(currentDirectory: string, useCaseSensitiveFileNames: boolean) {
super(undefined, "");
super(/*fileSystem*/ undefined, "");
this.fileSystem = this;
this.root = new VirtualDirectory(this, "");
this.currentDirectory = currentDirectory;
+37 -20
View File
@@ -4,25 +4,42 @@ interface DOMTokenList {
[Symbol.iterator](): IterableIterator<string>;
}
interface FormData {
/**
* Returns an array of key, value pairs for every entry in the list
*/
entries(): IterableIterator<[string, string | File]>;
/**
* Returns a list of keys in the list
*/
keys(): IterableIterator<string>;
/**
* Returns a list of values in the list
*/
values(): IterableIterator<string | File>;
[Symbol.iterator](): IterableIterator<string | File>;
}
interface NodeList {
/**
* Returns an array of key, value pairs for every entry in the list
*/
* Returns an array of key, value pairs for every entry in the list
*/
entries(): IterableIterator<[number, Node]>;
/**
* Performs the specified action for each node in an list.
* @param callbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the list.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
* Performs the specified action for each node in an list.
* @param callbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the list.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
forEach(callbackfn: (value: Node, index: number, listObj: NodeList) => void, thisArg?: any): void;
/**
* Returns an list of keys in the list
*/
* Returns an list of keys in the list
*/
keys(): IterableIterator<number>;
/**
* Returns an list of values in the list
*/
* Returns an list of values in the list
*/
values(): IterableIterator<Node>;
@@ -32,23 +49,23 @@ interface NodeList {
interface NodeListOf<TNode extends Node> {
/**
* Returns an array of key, value pairs for every entry in the list
*/
* Returns an array of key, value pairs for every entry in the list
*/
entries(): IterableIterator<[number, TNode]>;
/**
* Performs the specified action for each node in an list.
* @param callbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the list.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
* Performs the specified action for each node in an list.
* @param callbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the list.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
forEach(callbackfn: (value: TNode, index: number, listObj: NodeListOf<TNode>) => void, thisArg?: any): void;
/**
* Returns an list of keys in the list
*/
* Returns an list of keys in the list
*/
keys(): IterableIterator<number>;
/**
* Returns an list of values in the list
*/
* Returns an list of values in the list
*/
values(): IterableIterator<TNode>;
[Symbol.iterator](): IterableIterator<TNode>;
+280 -280
View File
@@ -2,75 +2,75 @@ declare type PropertyKey = string | number | symbol;
interface Array<T> {
/**
* Returns the value of the first element in the array where predicate is true, and undefined
* otherwise.
* @param predicate find calls predicate once for each element of the array, in ascending
* order, until it finds one where predicate returns true. If such an element is found, find
* immediately returns that element value. Otherwise, find returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
* Returns the value of the first element in the array where predicate is true, and undefined
* otherwise.
* @param predicate find calls predicate once for each element of the array, in ascending
* order, until it finds one where predicate returns true. If such an element is found, find
* immediately returns that element value. Otherwise, find returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
find(predicate: (this: undefined, value: T, index: number, obj: Array<T>) => boolean): T | undefined;
find(predicate: (this: undefined, value: T, index: number, obj: Array<T>) => boolean, thisArg: undefined): T | undefined;
find<Z>(predicate: (this: Z, value: T, index: number, obj: Array<T>) => boolean, thisArg: Z): T | undefined;
/**
* Returns the index of the first element in the array where predicate is true, and -1
* otherwise.
* @param predicate find calls predicate once for each element of the array, in ascending
* order, until it finds one where predicate returns true. If such an element is found,
* findIndex immediately returns that element index. Otherwise, findIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
* Returns the index of the first element in the array where predicate is true, and -1
* otherwise.
* @param predicate find calls predicate once for each element of the array, in ascending
* order, until it finds one where predicate returns true. If such an element is found,
* findIndex immediately returns that element index. Otherwise, findIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findIndex(predicate: (this: undefined, value: T, index: number, obj: Array<T>) => boolean): number;
findIndex(predicate: (this: undefined, value: T, index: number, obj: Array<T>) => boolean, thisArg: undefined): number;
findIndex<Z>(predicate: (this: Z, value: T, index: number, obj: Array<T>) => boolean, thisArg: Z): number;
/**
* Returns the this object after filling the section identified by start and end with value
* @param value value to fill array section with
* @param start index to start filling the array at. If start is negative, it is treated as
* length+start where length is the length of the array.
* @param end index to stop filling the array at. If end is negative, it is treated as
* length+end.
*/
* Returns the this object after filling the section identified by start and end with value
* @param value value to fill array section with
* @param start index to start filling the array at. If start is negative, it is treated as
* length+start where length is the length of the array.
* @param end index to stop filling the array at. If end is negative, it is treated as
* length+end.
*/
fill(value: T, start?: number, end?: number): this;
/**
* Returns the this object after copying a section of the array identified by start and end
* to the same array starting at position target
* @param target If target is negative, it is treated as length+target where length is the
* length of the array.
* @param start If start is negative, it is treated as length+start. If end is negative, it
* is treated as length+end.
* @param end If not specified, length of the this object is used as its default value.
*/
* Returns the this object after copying a section of the array identified by start and end
* to the same array starting at position target
* @param target If target is negative, it is treated as length+target where length is the
* length of the array.
* @param start If start is negative, it is treated as length+start. If end is negative, it
* is treated as length+end.
* @param end If not specified, length of the this object is used as its default value.
*/
copyWithin(target: number, start: number, end?: number): this;
}
interface ArrayConstructor {
/**
* Creates an array from an array-like object.
* @param arrayLike An array-like object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
* Creates an array from an array-like object.
* @param arrayLike An array-like object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
from<T, U>(arrayLike: ArrayLike<T>, mapfn: (this: undefined, v: T, k: number) => U): Array<U>;
from<T, U>(arrayLike: ArrayLike<T>, mapfn: (this: undefined, v: T, k: number) => U, thisArg: undefined): Array<U>;
from<Z, T, U>(arrayLike: ArrayLike<T>, mapfn: (this: Z, v: T, k: number) => U, thisArg: Z): Array<U>;
/**
* Creates an array from an array-like object.
* @param arrayLike An array-like object to convert to an array.
*/
* Creates an array from an array-like object.
* @param arrayLike An array-like object to convert to an array.
*/
from<T>(arrayLike: ArrayLike<T>): Array<T>;
/**
* Returns a new array from a set of elements.
* @param items A set of elements to include in the new array object.
*/
* Returns a new array from a set of elements.
* @param items A set of elements to include in the new array object.
*/
of<T>(...items: T[]): Array<T>;
}
@@ -80,332 +80,332 @@ interface DateConstructor {
interface Function {
/**
* Returns the name of the function. Function names are read-only and can not be changed.
*/
* Returns the name of the function. Function names are read-only and can not be changed.
*/
readonly name: string;
}
interface Math {
/**
* Returns the number of leading zero bits in the 32-bit binary representation of a number.
* @param x A numeric expression.
*/
* Returns the number of leading zero bits in the 32-bit binary representation of a number.
* @param x A numeric expression.
*/
clz32(x: number): number;
/**
* Returns the result of 32-bit multiplication of two numbers.
* @param x First number
* @param y Second number
*/
* Returns the result of 32-bit multiplication of two numbers.
* @param x First number
* @param y Second number
*/
imul(x: number, y: number): number;
/**
* Returns the sign of the x, indicating whether x is positive, negative or zero.
* @param x The numeric expression to test
*/
* Returns the sign of the x, indicating whether x is positive, negative or zero.
* @param x The numeric expression to test
*/
sign(x: number): number;
/**
* Returns the base 10 logarithm of a number.
* @param x A numeric expression.
*/
* Returns the base 10 logarithm of a number.
* @param x A numeric expression.
*/
log10(x: number): number;
/**
* Returns the base 2 logarithm of a number.
* @param x A numeric expression.
*/
* Returns the base 2 logarithm of a number.
* @param x A numeric expression.
*/
log2(x: number): number;
/**
* Returns the natural logarithm of 1 + x.
* @param x A numeric expression.
*/
* Returns the natural logarithm of 1 + x.
* @param x A numeric expression.
*/
log1p(x: number): number;
/**
* Returns the result of (e^x - 1) of x (e raised to the power of x, where e is the base of
* the natural logarithms).
* @param x A numeric expression.
*/
* Returns the result of (e^x - 1) of x (e raised to the power of x, where e is the base of
* the natural logarithms).
* @param x A numeric expression.
*/
expm1(x: number): number;
/**
* Returns the hyperbolic cosine of a number.
* @param x A numeric expression that contains an angle measured in radians.
*/
* Returns the hyperbolic cosine of a number.
* @param x A numeric expression that contains an angle measured in radians.
*/
cosh(x: number): number;
/**
* Returns the hyperbolic sine of a number.
* @param x A numeric expression that contains an angle measured in radians.
*/
* Returns the hyperbolic sine of a number.
* @param x A numeric expression that contains an angle measured in radians.
*/
sinh(x: number): number;
/**
* Returns the hyperbolic tangent of a number.
* @param x A numeric expression that contains an angle measured in radians.
*/
* Returns the hyperbolic tangent of a number.
* @param x A numeric expression that contains an angle measured in radians.
*/
tanh(x: number): number;
/**
* Returns the inverse hyperbolic cosine of a number.
* @param x A numeric expression that contains an angle measured in radians.
*/
* Returns the inverse hyperbolic cosine of a number.
* @param x A numeric expression that contains an angle measured in radians.
*/
acosh(x: number): number;
/**
* Returns the inverse hyperbolic sine of a number.
* @param x A numeric expression that contains an angle measured in radians.
*/
* Returns the inverse hyperbolic sine of a number.
* @param x A numeric expression that contains an angle measured in radians.
*/
asinh(x: number): number;
/**
* Returns the inverse hyperbolic tangent of a number.
* @param x A numeric expression that contains an angle measured in radians.
*/
* Returns the inverse hyperbolic tangent of a number.
* @param x A numeric expression that contains an angle measured in radians.
*/
atanh(x: number): number;
/**
* Returns the square root of the sum of squares of its arguments.
* @param values Values to compute the square root for.
* If no arguments are passed, the result is +0.
* If there is only one argument, the result is the absolute value.
* If any argument is +Infinity or -Infinity, the result is +Infinity.
* If any argument is NaN, the result is NaN.
* If all arguments are either +0 or 0, the result is +0.
*/
* Returns the square root of the sum of squares of its arguments.
* @param values Values to compute the square root for.
* If no arguments are passed, the result is +0.
* If there is only one argument, the result is the absolute value.
* If any argument is +Infinity or -Infinity, the result is +Infinity.
* If any argument is NaN, the result is NaN.
* If all arguments are either +0 or 0, the result is +0.
*/
hypot(...values: number[] ): number;
/**
* Returns the integral part of the a numeric expression, x, removing any fractional digits.
* If x is already an integer, the result is x.
* @param x A numeric expression.
*/
* Returns the integral part of the a numeric expression, x, removing any fractional digits.
* If x is already an integer, the result is x.
* @param x A numeric expression.
*/
trunc(x: number): number;
/**
* Returns the nearest single precision float representation of a number.
* @param x A numeric expression.
*/
* Returns the nearest single precision float representation of a number.
* @param x A numeric expression.
*/
fround(x: number): number;
/**
* Returns an implementation-dependent approximation to the cube root of number.
* @param x A numeric expression.
*/
* Returns an implementation-dependent approximation to the cube root of number.
* @param x A numeric expression.
*/
cbrt(x: number): number;
}
interface NumberConstructor {
/**
* The value of Number.EPSILON is the difference between 1 and the smallest value greater than 1
* that is representable as a Number value, which is approximately:
* 2.2204460492503130808472633361816 x 1016.
*/
* The value of Number.EPSILON is the difference between 1 and the smallest value greater than 1
* that is representable as a Number value, which is approximately:
* 2.2204460492503130808472633361816 x 1016.
*/
readonly EPSILON: number;
/**
* Returns true if passed value is finite.
* Unlike the global isFinite, Number.isFinite doesn't forcibly convert the parameter to a
* number. Only finite values of the type number, result in true.
* @param number A numeric value.
*/
* Returns true if passed value is finite.
* Unlike the global isFinite, Number.isFinite doesn't forcibly convert the parameter to a
* number. Only finite values of the type number, result in true.
* @param number A numeric value.
*/
isFinite(number: number): boolean;
/**
* Returns true if the value passed is an integer, false otherwise.
* @param number A numeric value.
*/
* Returns true if the value passed is an integer, false otherwise.
* @param number A numeric value.
*/
isInteger(number: number): boolean;
/**
* Returns a Boolean value that indicates whether a value is the reserved value NaN (not a
* number). Unlike the global isNaN(), Number.isNaN() doesn't forcefully convert the parameter
* to a number. Only values of the type number, that are also NaN, result in true.
* @param number A numeric value.
*/
* Returns a Boolean value that indicates whether a value is the reserved value NaN (not a
* number). Unlike the global isNaN(), Number.isNaN() doesn't forcefully convert the parameter
* to a number. Only values of the type number, that are also NaN, result in true.
* @param number A numeric value.
*/
isNaN(number: number): boolean;
/**
* Returns true if the value passed is a safe integer.
* @param number A numeric value.
*/
* Returns true if the value passed is a safe integer.
* @param number A numeric value.
*/
isSafeInteger(number: number): boolean;
/**
* The value of the largest integer n such that n and n + 1 are both exactly representable as
* a Number value.
* The value of Number.MAX_SAFE_INTEGER is 9007199254740991 2^53 1.
*/
* The value of the largest integer n such that n and n + 1 are both exactly representable as
* a Number value.
* The value of Number.MAX_SAFE_INTEGER is 9007199254740991 2^53 1.
*/
readonly MAX_SAFE_INTEGER: number;
/**
* The value of the smallest integer n such that n and n 1 are both exactly representable as
* a Number value.
* The value of Number.MIN_SAFE_INTEGER is 9007199254740991 ((2^53 1)).
*/
* The value of the smallest integer n such that n and n 1 are both exactly representable as
* a Number value.
* The value of Number.MIN_SAFE_INTEGER is 9007199254740991 ((2^53 1)).
*/
readonly MIN_SAFE_INTEGER: number;
/**
* Converts a string to a floating-point number.
* @param string A string that contains a floating-point number.
*/
* Converts a string to a floating-point number.
* @param string A string that contains a floating-point number.
*/
parseFloat(string: string): number;
/**
* Converts A string to an integer.
* @param s A string to convert into a number.
* @param radix A value between 2 and 36 that specifies the base of the number in numString.
* If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal.
* All other strings are considered decimal.
*/
* Converts A string to an integer.
* @param s A string to convert into a number.
* @param radix A value between 2 and 36 that specifies the base of the number in numString.
* If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal.
* All other strings are considered decimal.
*/
parseInt(string: string, radix?: number): number;
}
interface Object {
/**
* Determines whether an object has a property with the specified name.
* @param v A property name.
*/
* Determines whether an object has a property with the specified name.
* @param v A property name.
*/
hasOwnProperty(v: PropertyKey): boolean;
/**
* Determines whether a specified property is enumerable.
* @param v A property name.
*/
* Determines whether a specified property is enumerable.
* @param v A property name.
*/
propertyIsEnumerable(v: PropertyKey): boolean;
}
interface ObjectConstructor {
/**
* Copy the values of all of the enumerable own properties from one or more source objects to a
* target object. Returns the target object.
* @param target The target object to copy to.
* @param source The source object from which to copy properties.
*/
* Copy the values of all of the enumerable own properties from one or more source objects to a
* target object. Returns the target object.
* @param target The target object to copy to.
* @param source The source object from which to copy properties.
*/
assign<T, U>(target: T, source: U): T & U;
/**
* Copy the values of all of the enumerable own properties from one or more source objects to a
* target object. Returns the target object.
* @param target The target object to copy to.
* @param source1 The first source object from which to copy properties.
* @param source2 The second source object from which to copy properties.
*/
* Copy the values of all of the enumerable own properties from one or more source objects to a
* target object. Returns the target object.
* @param target The target object to copy to.
* @param source1 The first source object from which to copy properties.
* @param source2 The second source object from which to copy properties.
*/
assign<T, U, V>(target: T, source1: U, source2: V): T & U & V;
/**
* Copy the values of all of the enumerable own properties from one or more source objects to a
* target object. Returns the target object.
* @param target The target object to copy to.
* @param source1 The first source object from which to copy properties.
* @param source2 The second source object from which to copy properties.
* @param source3 The third source object from which to copy properties.
*/
* Copy the values of all of the enumerable own properties from one or more source objects to a
* target object. Returns the target object.
* @param target The target object to copy to.
* @param source1 The first source object from which to copy properties.
* @param source2 The second source object from which to copy properties.
* @param source3 The third source object from which to copy properties.
*/
assign<T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W;
/**
* Copy the values of all of the enumerable own properties from one or more source objects to a
* target object. Returns the target object.
* @param target The target object to copy to.
* @param sources One or more source objects from which to copy properties
*/
* Copy the values of all of the enumerable own properties from one or more source objects to a
* target object. Returns the target object.
* @param target The target object to copy to.
* @param sources One or more source objects from which to copy properties
*/
assign(target: any, ...sources: any[]): any;
/**
* Returns an array of all symbol properties found directly on object o.
* @param o Object to retrieve the symbols from.
*/
* Returns an array of all symbol properties found directly on object o.
* @param o Object to retrieve the symbols from.
*/
getOwnPropertySymbols(o: any): symbol[];
/**
* Returns true if the values are the same value, false otherwise.
* @param value1 The first value.
* @param value2 The second value.
*/
* Returns true if the values are the same value, false otherwise.
* @param value1 The first value.
* @param value2 The second value.
*/
is(value1: any, value2: any): boolean;
/**
* Sets the prototype of a specified object o to object proto or null. Returns the object o.
* @param o The object to change its prototype.
* @param proto The value of the new prototype or null.
*/
* Sets the prototype of a specified object o to object proto or null. Returns the object o.
* @param o The object to change its prototype.
* @param proto The value of the new prototype or null.
*/
setPrototypeOf(o: any, proto: object | null): any;
/**
* Gets the own property descriptor of the specified object.
* An own property descriptor is one that is defined directly on the object and is not
* inherited from the object's prototype.
* @param o Object that contains the property.
* @param p Name of the property.
*/
* Gets the own property descriptor of the specified object.
* An own property descriptor is one that is defined directly on the object and is not
* inherited from the object's prototype.
* @param o Object that contains the property.
* @param p Name of the property.
*/
getOwnPropertyDescriptor(o: any, propertyKey: PropertyKey): PropertyDescriptor;
/**
* Adds a property to an object, or modifies attributes of an existing property.
* @param o Object on which to add or modify the property. This can be a native JavaScript
* object (that is, a user-defined object or a built in object) or a DOM object.
* @param p The property name.
* @param attributes Descriptor for the property. It can be for a data property or an accessor
* property.
*/
* Adds a property to an object, or modifies attributes of an existing property.
* @param o Object on which to add or modify the property. This can be a native JavaScript
* object (that is, a user-defined object or a built in object) or a DOM object.
* @param p The property name.
* @param attributes Descriptor for the property. It can be for a data property or an accessor
* property.
*/
defineProperty(o: any, propertyKey: PropertyKey, attributes: PropertyDescriptor): any;
}
interface ReadonlyArray<T> {
/**
* Returns the value of the first element in the array where predicate is true, and undefined
* otherwise.
* @param predicate find calls predicate once for each element of the array, in ascending
* order, until it finds one where predicate returns true. If such an element is found, find
* immediately returns that element value. Otherwise, find returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
find(predicate: (this: undefined, value: T, index: number, obj: ReadonlyArray<T>) => boolean): T | undefined;
find(predicate: (this: undefined, value: T, index: number, obj: ReadonlyArray<T>) => boolean, thisArg: undefined): T | undefined;
find<Z>(predicate: (this: Z, value: T, index: number, obj: ReadonlyArray<T>) => boolean, thisArg: Z): T | undefined;
/**
* Returns the value of the first element in the array where predicate is true, and undefined
* otherwise.
* @param predicate find calls predicate once for each element of the array, in ascending
* order, until it finds one where predicate returns true. If such an element is found, find
* immediately returns that element value. Otherwise, find returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
find(predicate: (this: undefined, value: T, index: number, obj: ReadonlyArray<T>) => boolean): T | undefined;
find(predicate: (this: undefined, value: T, index: number, obj: ReadonlyArray<T>) => boolean, thisArg: undefined): T | undefined;
find<Z>(predicate: (this: Z, value: T, index: number, obj: ReadonlyArray<T>) => boolean, thisArg: Z): T | undefined;
/**
* Returns the index of the first element in the array where predicate is true, and -1
* otherwise.
* @param predicate find calls predicate once for each element of the array, in ascending
* order, until it finds one where predicate returns true. If such an element is found,
* findIndex immediately returns that element index. Otherwise, findIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findIndex(predicate: (this: undefined, value: T, index: number, obj: Array<T>) => boolean): number;
findIndex(predicate: (this: undefined, value: T, index: number, obj: Array<T>) => boolean, thisArg: undefined): number;
findIndex<Z>(predicate: (this: Z, value: T, index: number, obj: Array<T>) => boolean, thisArg: Z): number;
/**
* Returns the index of the first element in the array where predicate is true, and -1
* otherwise.
* @param predicate find calls predicate once for each element of the array, in ascending
* order, until it finds one where predicate returns true. If such an element is found,
* findIndex immediately returns that element index. Otherwise, findIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findIndex(predicate: (this: undefined, value: T, index: number, obj: Array<T>) => boolean): number;
findIndex(predicate: (this: undefined, value: T, index: number, obj: Array<T>) => boolean, thisArg: undefined): number;
findIndex<Z>(predicate: (this: Z, value: T, index: number, obj: Array<T>) => boolean, thisArg: Z): number;
}
interface RegExp {
/**
* Returns a string indicating the flags of the regular expression in question. This field is read-only.
* The characters in this string are sequenced and concatenated in the following order:
*
* - "g" for global
* - "i" for ignoreCase
* - "m" for multiline
* - "u" for unicode
* - "y" for sticky
*
* If no flags are set, the value is the empty string.
*/
* Returns a string indicating the flags of the regular expression in question. This field is read-only.
* The characters in this string are sequenced and concatenated in the following order:
*
* - "g" for global
* - "i" for ignoreCase
* - "m" for multiline
* - "u" for unicode
* - "y" for sticky
*
* If no flags are set, the value is the empty string.
*/
readonly flags: string;
/**
* Returns a Boolean value indicating the state of the sticky flag (y) used with a regular
* expression. Default is false. Read-only.
*/
* Returns a Boolean value indicating the state of the sticky flag (y) used with a regular
* expression. Default is false. Read-only.
*/
readonly sticky: boolean;
/**
* Returns a Boolean value indicating the state of the Unicode flag (u) used with a regular
* expression. Default is false. Read-only.
*/
* Returns a Boolean value indicating the state of the Unicode flag (u) used with a regular
* expression. Default is false. Read-only.
*/
readonly unicode: boolean;
}
@@ -416,64 +416,64 @@ interface RegExpConstructor {
interface String {
/**
* Returns a nonnegative integer Number less than 1114112 (0x110000) that is the code point
* value of the UTF-16 encoded code point starting at the string element at position pos in
* the String resulting from converting this object to a String.
* If there is no element at that position, the result is undefined.
* If a valid UTF-16 surrogate pair does not begin at pos, the result is the code unit at pos.
*/
* Returns a nonnegative integer Number less than 1114112 (0x110000) that is the code point
* value of the UTF-16 encoded code point starting at the string element at position pos in
* the String resulting from converting this object to a String.
* If there is no element at that position, the result is undefined.
* If a valid UTF-16 surrogate pair does not begin at pos, the result is the code unit at pos.
*/
codePointAt(pos: number): number | undefined;
/**
* Returns true if searchString appears as a substring of the result of converting this
* object to a String, at one or more positions that are
* greater than or equal to position; otherwise, returns false.
* @param searchString search string
* @param position If position is undefined, 0 is assumed, so as to search all of the String.
*/
* Returns true if searchString appears as a substring of the result of converting this
* object to a String, at one or more positions that are
* greater than or equal to position; otherwise, returns false.
* @param searchString search string
* @param position If position is undefined, 0 is assumed, so as to search all of the String.
*/
includes(searchString: string, position?: number): boolean;
/**
* Returns true if the sequence of elements of searchString converted to a String is the
* same as the corresponding elements of this object (converted to a String) starting at
* endPosition length(this). Otherwise returns false.
*/
* Returns true if the sequence of elements of searchString converted to a String is the
* same as the corresponding elements of this object (converted to a String) starting at
* endPosition length(this). Otherwise returns false.
*/
endsWith(searchString: string, endPosition?: number): boolean;
/**
* Returns the String value result of normalizing the string into the normalization form
* named by form as specified in Unicode Standard Annex #15, Unicode Normalization Forms.
* @param form Applicable values: "NFC", "NFD", "NFKC", or "NFKD", If not specified default
* is "NFC"
*/
* Returns the String value result of normalizing the string into the normalization form
* named by form as specified in Unicode Standard Annex #15, Unicode Normalization Forms.
* @param form Applicable values: "NFC", "NFD", "NFKC", or "NFKD", If not specified default
* is "NFC"
*/
normalize(form: "NFC" | "NFD" | "NFKC" | "NFKD"): string;
/**
* Returns the String value result of normalizing the string into the normalization form
* named by form as specified in Unicode Standard Annex #15, Unicode Normalization Forms.
* @param form Applicable values: "NFC", "NFD", "NFKC", or "NFKD", If not specified default
* is "NFC"
*/
* Returns the String value result of normalizing the string into the normalization form
* named by form as specified in Unicode Standard Annex #15, Unicode Normalization Forms.
* @param form Applicable values: "NFC", "NFD", "NFKC", or "NFKD", If not specified default
* is "NFC"
*/
normalize(form?: string): string;
/**
* Returns a String value that is made from count copies appended together. If count is 0,
* T is the empty String is returned.
* @param count number of copies to append
*/
* Returns a String value that is made from count copies appended together. If count is 0,
* T is the empty String is returned.
* @param count number of copies to append
*/
repeat(count: number): string;
/**
* Returns true if the sequence of elements of searchString converted to a String is the
* same as the corresponding elements of this object (converted to a String) starting at
* position. Otherwise returns false.
*/
* Returns true if the sequence of elements of searchString converted to a String is the
* same as the corresponding elements of this object (converted to a String) starting at
* position. Otherwise returns false.
*/
startsWith(searchString: string, position?: number): boolean;
/**
* Returns an <a> HTML anchor element and sets the name attribute to the text value
* @param name
*/
* Returns an <a> HTML anchor element and sets the name attribute to the text value
* @param name
*/
anchor(name: string): string;
/** Returns a <big> HTML element */
@@ -518,17 +518,17 @@ interface String {
interface StringConstructor {
/**
* Return the String value whose elements are, in order, the elements in the List elements.
* If length is 0, the empty string is returned.
*/
* Return the String value whose elements are, in order, the elements in the List elements.
* If length is 0, the empty string is returned.
*/
fromCodePoint(...codePoints: number[]): string;
/**
* String.raw is intended for use as a tag function of a Tagged Template String. When called
* as such the first argument will be a well formed template call site object and the rest
* parameter will contain the substitution values.
* @param template A well-formed template string call site representation.
* @param substitutions A set of substitution values.
*/
* String.raw is intended for use as a tag function of a Tagged Template String. When called
* as such the first argument will be a well formed template call site object and the rest
* parameter will contain the substitution values.
* @param template A well-formed template string call site representation.
* @param substitutions A set of substitution values.
*/
raw(template: TemplateStringsArray, ...substitutions: any[]): string;
}
+14 -14
View File
@@ -16,37 +16,37 @@ interface GeneratorFunction {
*/
readonly length: number;
/**
* Returns the name of the function.
*/
* Returns the name of the function.
*/
readonly name: string;
/**
* A reference to the prototype.
*/
* A reference to the prototype.
*/
readonly prototype: Generator;
}
interface GeneratorFunctionConstructor {
/**
* Creates a new Generator function.
* @param args A list of arguments the function accepts.
*/
* Creates a new Generator function.
* @param args A list of arguments the function accepts.
*/
new (...args: string[]): GeneratorFunction;
/**
* Creates a new Generator function.
* @param args A list of arguments the function accepts.
*/
* Creates a new Generator function.
* @param args A list of arguments the function accepts.
*/
(...args: string[]): GeneratorFunction;
/**
* The length of the arguments.
*/
readonly length: number;
/**
* Returns the name of the function.
*/
* Returns the name of the function.
*/
readonly name: string;
/**
* A reference to the prototype.
*/
* A reference to the prototype.
*/
readonly prototype: GeneratorFunction;
}
declare var GeneratorFunction: GeneratorFunctionConstructor;
+149 -149
View File
@@ -2,9 +2,9 @@
interface SymbolConstructor {
/**
* A method that returns the default iterator for an object. Called by the semantics of the
* for-of statement.
*/
* A method that returns the default iterator for an object. Called by the semantics of the
* for-of statement.
*/
readonly iterator: symbol;
}
@@ -32,36 +32,36 @@ interface Array<T> {
[Symbol.iterator](): IterableIterator<T>;
/**
* Returns an array of key, value pairs for every entry in the array
*/
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, T]>;
/**
* Returns an list of keys in the array
*/
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
* Returns an list of values in the array
*/
* Returns an list of values in the array
*/
values(): IterableIterator<T>;
}
interface ArrayConstructor {
/**
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
from<T, U>(iterable: Iterable<T>, mapfn: (this: undefined, v: T, k: number) => U): Array<U>;
from<T, U>(iterable: Iterable<T>, mapfn: (this: undefined, v: T, k: number) => U, thisArg: undefined): Array<U>;
from<Z, T, U>(iterable: Iterable<T>, mapfn: (this: Z, v: T, k: number) => U, thisArg: Z): Array<U>;
/**
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
*/
* Creates an array from an iterable object.
* @param iterable An iterable object to convert to an array.
*/
from<T>(iterable: Iterable<T>): Array<T>;
}
@@ -70,18 +70,18 @@ interface ReadonlyArray<T> {
[Symbol.iterator](): IterableIterator<T>;
/**
* Returns an array of key, value pairs for every entry in the array
*/
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, T]>;
/**
* Returns an list of keys in the array
*/
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
* Returns an list of values in the array
*/
* Returns an list of values in the array
*/
values(): IterableIterator<T>;
}
@@ -154,22 +154,22 @@ interface String {
}
/**
* A typed array of 8-bit integer values. The contents are initialized to 0. If the requested
* number of bytes could not be allocated an exception is raised.
*/
* A typed array of 8-bit integer values. The contents are initialized to 0. If the requested
* number of bytes could not be allocated an exception is raised.
*/
interface Int8Array {
[Symbol.iterator](): IterableIterator<number>;
/**
* Returns an array of key, value pairs for every entry in the array
*/
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
* Returns an list of keys in the array
*/
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
* Returns an list of values in the array
*/
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
}
@@ -177,11 +177,11 @@ interface Int8ArrayConstructor {
new (elements: Iterable<number>): Int8Array;
/**
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number): Int8Array;
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number, thisArg: undefined): Int8Array;
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Int8Array;
@@ -190,22 +190,22 @@ interface Int8ArrayConstructor {
}
/**
* A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
* A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
interface Uint8Array {
[Symbol.iterator](): IterableIterator<number>;
/**
* Returns an array of key, value pairs for every entry in the array
*/
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
* Returns an list of keys in the array
*/
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
* Returns an list of values in the array
*/
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
}
@@ -213,11 +213,11 @@ interface Uint8ArrayConstructor {
new (elements: Iterable<number>): Uint8Array;
/**
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number): Uint8Array;
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number, thisArg: undefined): Uint8Array;
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Uint8Array;
@@ -226,24 +226,24 @@ interface Uint8ArrayConstructor {
}
/**
* A typed array of 8-bit unsigned integer (clamped) values. The contents are initialized to 0.
* If the requested number of bytes could not be allocated an exception is raised.
*/
* A typed array of 8-bit unsigned integer (clamped) values. The contents are initialized to 0.
* If the requested number of bytes could not be allocated an exception is raised.
*/
interface Uint8ClampedArray {
[Symbol.iterator](): IterableIterator<number>;
/**
* Returns an array of key, value pairs for every entry in the array
*/
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
* Returns an list of keys in the array
*/
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
* Returns an list of values in the array
*/
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
}
@@ -252,11 +252,11 @@ interface Uint8ClampedArrayConstructor {
/**
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number): Uint8ClampedArray;
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number, thisArg: undefined): Uint8ClampedArray;
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Uint8ClampedArray;
@@ -265,24 +265,24 @@ interface Uint8ClampedArrayConstructor {
}
/**
* A typed array of 16-bit signed integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
* A typed array of 16-bit signed integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
interface Int16Array {
[Symbol.iterator](): IterableIterator<number>;
/**
* Returns an array of key, value pairs for every entry in the array
*/
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
* Returns an list of keys in the array
*/
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
* Returns an list of values in the array
*/
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
}
@@ -290,11 +290,11 @@ interface Int16ArrayConstructor {
new (elements: Iterable<number>): Int16Array;
/**
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number): Int16Array;
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number, thisArg: undefined): Int16Array;
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Int16Array;
@@ -303,22 +303,22 @@ interface Int16ArrayConstructor {
}
/**
* A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
* A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
interface Uint16Array {
[Symbol.iterator](): IterableIterator<number>;
/**
* Returns an array of key, value pairs for every entry in the array
*/
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
* Returns an list of keys in the array
*/
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
* Returns an list of values in the array
*/
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
}
@@ -326,11 +326,11 @@ interface Uint16ArrayConstructor {
new (elements: Iterable<number>): Uint16Array;
/**
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number): Uint16Array;
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number, thisArg: undefined): Uint16Array;
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Uint16Array;
@@ -339,22 +339,22 @@ interface Uint16ArrayConstructor {
}
/**
* A typed array of 32-bit signed integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
* A typed array of 32-bit signed integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
interface Int32Array {
[Symbol.iterator](): IterableIterator<number>;
/**
* Returns an array of key, value pairs for every entry in the array
*/
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
* Returns an list of keys in the array
*/
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
* Returns an list of values in the array
*/
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
}
@@ -362,11 +362,11 @@ interface Int32ArrayConstructor {
new (elements: Iterable<number>): Int32Array;
/**
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number): Int32Array;
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number, thisArg: undefined): Int32Array;
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Int32Array;
@@ -375,22 +375,22 @@ interface Int32ArrayConstructor {
}
/**
* A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
* A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
interface Uint32Array {
[Symbol.iterator](): IterableIterator<number>;
/**
* Returns an array of key, value pairs for every entry in the array
*/
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
* Returns an list of keys in the array
*/
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
* Returns an list of values in the array
*/
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
}
@@ -398,11 +398,11 @@ interface Uint32ArrayConstructor {
new (elements: Iterable<number>): Uint32Array;
/**
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number): Uint32Array;
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number, thisArg: undefined): Uint32Array;
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Uint32Array;
@@ -411,22 +411,22 @@ interface Uint32ArrayConstructor {
}
/**
* A typed array of 32-bit float values. The contents are initialized to 0. If the requested number
* of bytes could not be allocated an exception is raised.
*/
* A typed array of 32-bit float values. The contents are initialized to 0. If the requested number
* of bytes could not be allocated an exception is raised.
*/
interface Float32Array {
[Symbol.iterator](): IterableIterator<number>;
/**
* Returns an array of key, value pairs for every entry in the array
*/
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
* Returns an list of keys in the array
*/
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
* Returns an list of values in the array
*/
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
}
@@ -434,11 +434,11 @@ interface Float32ArrayConstructor {
new (elements: Iterable<number>): Float32Array;
/**
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number): Float32Array;
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number, thisArg: undefined): Float32Array;
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Float32Array;
@@ -447,22 +447,22 @@ interface Float32ArrayConstructor {
}
/**
* A typed array of 64-bit float values. The contents are initialized to 0. If the requested
* number of bytes could not be allocated an exception is raised.
*/
* A typed array of 64-bit float values. The contents are initialized to 0. If the requested
* number of bytes could not be allocated an exception is raised.
*/
interface Float64Array {
[Symbol.iterator](): IterableIterator<number>;
/**
* Returns an array of key, value pairs for every entry in the array
*/
* Returns an array of key, value pairs for every entry in the array
*/
entries(): IterableIterator<[number, number]>;
/**
* Returns an list of keys in the array
*/
* Returns an list of keys in the array
*/
keys(): IterableIterator<number>;
/**
* Returns an list of values in the array
*/
* Returns an list of values in the array
*/
values(): IterableIterator<number>;
}
@@ -470,11 +470,11 @@ interface Float64ArrayConstructor {
new (elements: Iterable<number>): Float64Array;
/**
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
* Creates an array from an array-like or iterable object.
* @param arrayLike An array-like or iterable object to convert to an array.
* @param mapfn A mapping function to call on every element of the array.
* @param thisArg Value of 'this' used to invoke the mapfn.
*/
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number): Float64Array;
from(arrayLike: Iterable<number>, mapfn: (this: undefined, v: number, k: number) => number, thisArg: undefined): Float64Array;
from<Z>(arrayLike: Iterable<number>, mapfn: (this: Z, v: number, k: number) => number, thisArg: Z): Float64Array;
+6 -6
View File
@@ -1,7 +1,7 @@
interface PromiseConstructor {
/**
* A reference to the prototype.
*/
* A reference to the prototype.
*/
readonly prototype: Promise<any>;
/**
@@ -187,10 +187,10 @@ interface PromiseConstructor {
reject<T>(reason: any): Promise<T>;
/**
* Creates a new resolved promise for the provided value.
* @param value A promise.
* @returns A promise whose internal state matches the provided promise.
*/
* Creates a new resolved promise for the provided value.
* @param value A promise.
* @returns A promise whose internal state matches the provided promise.
*/
resolve<T>(value: T | PromiseLike<T>): Promise<T>;
/**
+13 -13
View File
@@ -8,28 +8,28 @@ interface Symbol {
interface SymbolConstructor {
/**
* A reference to the prototype.
*/
* A reference to the prototype.
*/
readonly prototype: Symbol;
/**
* Returns a new unique Symbol value.
* @param description Description of the new Symbol object.
*/
* Returns a new unique Symbol value.
* @param description Description of the new Symbol object.
*/
(description?: string | number): symbol;
/**
* Returns a Symbol object from the global symbol registry matching the given key if found.
* Otherwise, returns a new symbol with this key.
* @param key key to search for.
*/
* Returns a Symbol object from the global symbol registry matching the given key if found.
* Otherwise, returns a new symbol with this key.
* @param key key to search for.
*/
for(key: string): symbol;
/**
* Returns a key from the global symbol registry matching the given Symbol if found.
* Otherwise, returns a undefined.
* @param sym Symbol to find the key for.
*/
* Returns a key from the global symbol registry matching the given Symbol if found.
* Otherwise, returns a undefined.
* @param sym Symbol to find the key for.
*/
keyFor(sym: symbol): string | undefined;
}
+112 -112
View File
@@ -2,63 +2,63 @@
interface SymbolConstructor {
/**
* A method that determines if a constructor object recognizes an object as one of the
* constructors instances. Called by the semantics of the instanceof operator.
*/
* A method that determines if a constructor object recognizes an object as one of the
* constructors instances. Called by the semantics of the instanceof operator.
*/
readonly hasInstance: symbol;
/**
* A Boolean value that if true indicates that an object should flatten to its array elements
* by Array.prototype.concat.
*/
* A Boolean value that if true indicates that an object should flatten to its array elements
* by Array.prototype.concat.
*/
readonly isConcatSpreadable: symbol;
/**
* A regular expression method that matches the regular expression against a string. Called
* by the String.prototype.match method.
*/
* A regular expression method that matches the regular expression against a string. Called
* by the String.prototype.match method.
*/
readonly match: symbol;
/**
* A regular expression method that replaces matched substrings of a string. Called by the
* String.prototype.replace method.
*/
* A regular expression method that replaces matched substrings of a string. Called by the
* String.prototype.replace method.
*/
readonly replace: symbol;
/**
* A regular expression method that returns the index within a string that matches the
* regular expression. Called by the String.prototype.search method.
*/
* A regular expression method that returns the index within a string that matches the
* regular expression. Called by the String.prototype.search method.
*/
readonly search: symbol;
/**
* A function valued property that is the constructor function that is used to create
* derived objects.
*/
* A function valued property that is the constructor function that is used to create
* derived objects.
*/
readonly species: symbol;
/**
* A regular expression method that splits a string at the indices that match the regular
* expression. Called by the String.prototype.split method.
*/
* A regular expression method that splits a string at the indices that match the regular
* expression. Called by the String.prototype.split method.
*/
readonly split: symbol;
/**
* A method that converts an object to a corresponding primitive value.
* Called by the ToPrimitive abstract operation.
*/
* A method that converts an object to a corresponding primitive value.
* Called by the ToPrimitive abstract operation.
*/
readonly toPrimitive: symbol;
/**
* A String value that is used in the creation of the default string description of an object.
* Called by the built-in method Object.prototype.toString.
*/
* A String value that is used in the creation of the default string description of an object.
* Called by the built-in method Object.prototype.toString.
*/
readonly toStringTag: symbol;
/**
* An Object whose own property names are property names that are excluded from the 'with'
* environment bindings of the associated objects.
*/
* An Object whose own property names are property names that are excluded from the 'with'
* environment bindings of the associated objects.
*/
readonly unscopables: symbol;
}
@@ -154,50 +154,50 @@ interface PromiseConstructor {
}
interface RegExp {
/**
* Matches a string with this regular expression, and returns an array containing the results of
* that search.
* @param string A string to search within.
*/
/**
* Matches a string with this regular expression, and returns an array containing the results of
* that search.
* @param string A string to search within.
*/
[Symbol.match](string: string): RegExpMatchArray | null;
/**
* Replaces text in a string, using this regular expression.
* @param string A String object or string literal whose contents matching against
* this regular expression will be replaced
* @param replaceValue A String object or string literal containing the text to replace for every
* successful match of this regular expression.
*/
* Replaces text in a string, using this regular expression.
* @param string A String object or string literal whose contents matching against
* this regular expression will be replaced
* @param replaceValue A String object or string literal containing the text to replace for every
* successful match of this regular expression.
*/
[Symbol.replace](string: string, replaceValue: string): string;
/**
* Replaces text in a string, using this regular expression.
* @param string A String object or string literal whose contents matching against
* this regular expression will be replaced
* @param replacer A function that returns the replacement text.
*/
* Replaces text in a string, using this regular expression.
* @param string A String object or string literal whose contents matching against
* this regular expression will be replaced
* @param replacer A function that returns the replacement text.
*/
[Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string;
/**
* Finds the position beginning first substring match in a regular expression search
* using this regular expression.
*
* @param string The string to search within.
*/
* Finds the position beginning first substring match in a regular expression search
* using this regular expression.
*
* @param string The string to search within.
*/
[Symbol.search](string: string): number;
/**
* Returns an array of substrings that were delimited by strings in the original input that
* match against this regular expression.
*
* If the regular expression contains capturing parentheses, then each time this
* regular expression matches, the results (including any undefined results) of the
* capturing parentheses are spliced.
*
* @param string string value to split
* @param limit if not undefined, the output array is truncated so that it contains no more
* than 'limit' elements.
*/
* Returns an array of substrings that were delimited by strings in the original input that
* match against this regular expression.
*
* If the regular expression contains capturing parentheses, then each time this
* regular expression matches, the results (including any undefined results) of the
* capturing parentheses are spliced.
*
* @param string string value to split
* @param limit if not undefined, the output array is truncated so that it contains no more
* than 'limit' elements.
*/
[Symbol.split](string: string, limit?: number): string[];
}
@@ -207,45 +207,45 @@ interface RegExpConstructor {
interface String {
/**
* Matches a string an object that supports being matched against, and returns an array containing the results of that search.
* @param matcher An object that supports being matched against.
*/
* Matches a string an object that supports being matched against, and returns an array containing the results of that search.
* @param matcher An object that supports being matched against.
*/
match(matcher: { [Symbol.match](string: string): RegExpMatchArray | null; }): RegExpMatchArray | null;
/**
* Replaces text in a string, using an object that supports replacement within a string.
* @param searchValue A object can search for and replace matches within a string.
* @param replaceValue A string containing the text to replace for every successful match of searchValue in this string.
*/
* Replaces text in a string, using an object that supports replacement within a string.
* @param searchValue A object can search for and replace matches within a string.
* @param replaceValue A string containing the text to replace for every successful match of searchValue in this string.
*/
replace(searchValue: { [Symbol.replace](string: string, replaceValue: string): string; }, replaceValue: string): string;
/**
* Replaces text in a string, using an object that supports replacement within a string.
* @param searchValue A object can search for and replace matches within a string.
* @param replacer A function that returns the replacement text.
*/
* Replaces text in a string, using an object that supports replacement within a string.
* @param searchValue A object can search for and replace matches within a string.
* @param replacer A function that returns the replacement text.
*/
replace(searchValue: { [Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string; }, replacer: (substring: string, ...args: any[]) => string): string;
/**
* Finds the first substring match in a regular expression search.
* @param searcher An object which supports searching within a string.
*/
* Finds the first substring match in a regular expression search.
* @param searcher An object which supports searching within a string.
*/
search(searcher: { [Symbol.search](string: string): number; }): number;
/**
* Split a string into substrings using the specified separator and return them as an array.
* @param splitter An object that can split a string.
* @param limit A value used to limit the number of elements returned in the array.
*/
* Split a string into substrings using the specified separator and return them as an array.
* @param splitter An object that can split a string.
* @param limit A value used to limit the number of elements returned in the array.
*/
split(splitter: { [Symbol.split](string: string, limit?: number): string[]; }, limit?: number): string[];
}
/**
* Represents a raw buffer of binary data, which is used to store data for the
* different typed arrays. ArrayBuffers cannot be read from or written to directly,
* but can be passed to a typed array or DataView Object to interpret the raw
* buffer as needed.
*/
* Represents a raw buffer of binary data, which is used to store data for the
* different typed arrays. ArrayBuffers cannot be read from or written to directly,
* but can be passed to a typed array or DataView Object to interpret the raw
* buffer as needed.
*/
interface ArrayBuffer {
readonly [Symbol.toStringTag]: "ArrayBuffer";
}
@@ -255,73 +255,73 @@ interface DataView {
}
/**
* A typed array of 8-bit integer values. The contents are initialized to 0. If the requested
* number of bytes could not be allocated an exception is raised.
*/
* A typed array of 8-bit integer values. The contents are initialized to 0. If the requested
* number of bytes could not be allocated an exception is raised.
*/
interface Int8Array {
readonly [Symbol.toStringTag]: "Int8Array";
}
/**
* A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
* A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
interface Uint8Array {
readonly [Symbol.toStringTag]: "UInt8Array";
}
/**
* A typed array of 8-bit unsigned integer (clamped) values. The contents are initialized to 0.
* If the requested number of bytes could not be allocated an exception is raised.
*/
* A typed array of 8-bit unsigned integer (clamped) values. The contents are initialized to 0.
* If the requested number of bytes could not be allocated an exception is raised.
*/
interface Uint8ClampedArray {
readonly [Symbol.toStringTag]: "Uint8ClampedArray";
}
/**
* A typed array of 16-bit signed integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
* A typed array of 16-bit signed integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
interface Int16Array {
readonly [Symbol.toStringTag]: "Int16Array";
}
/**
* A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
* A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
interface Uint16Array {
readonly [Symbol.toStringTag]: "Uint16Array";
}
/**
* A typed array of 32-bit signed integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
* A typed array of 32-bit signed integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
interface Int32Array {
readonly [Symbol.toStringTag]: "Int32Array";
}
/**
* A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
* A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the
* requested number of bytes could not be allocated an exception is raised.
*/
interface Uint32Array {
readonly [Symbol.toStringTag]: "Uint32Array";
}
/**
* A typed array of 32-bit float values. The contents are initialized to 0. If the requested number
* of bytes could not be allocated an exception is raised.
*/
* A typed array of 32-bit float values. The contents are initialized to 0. If the requested number
* of bytes could not be allocated an exception is raised.
*/
interface Float32Array {
readonly [Symbol.toStringTag]: "Float32Array";
}
/**
* A typed array of 64-bit float values. The contents are initialized to 0. If the requested
* number of bytes could not be allocated an exception is raised.
*/
* A typed array of 64-bit float values. The contents are initialized to 0. If the requested
* number of bytes could not be allocated an exception is raised.
*/
interface Float64Array {
readonly [Symbol.toStringTag]: "Float64Array";
}
+44 -44
View File
@@ -1,98 +1,98 @@
interface Array<T> {
/**
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
includes(searchElement: T, fromIndex?: number): boolean;
}
interface ReadonlyArray<T> {
/**
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
includes(searchElement: T, fromIndex?: number): boolean;
}
interface Int8Array {
/**
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
includes(searchElement: number, fromIndex?: number): boolean;
}
interface Uint8Array {
/**
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
includes(searchElement: number, fromIndex?: number): boolean;
}
interface Uint8ClampedArray {
/**
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
includes(searchElement: number, fromIndex?: number): boolean;
}
interface Int16Array {
/**
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
includes(searchElement: number, fromIndex?: number): boolean;
}
interface Uint16Array {
/**
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
includes(searchElement: number, fromIndex?: number): boolean;
}
interface Int32Array {
/**
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
includes(searchElement: number, fromIndex?: number): boolean;
}
interface Uint32Array {
/**
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
includes(searchElement: number, fromIndex?: number): boolean;
}
interface Float32Array {
/**
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
includes(searchElement: number, fromIndex?: number): boolean;
}
interface Float64Array {
/**
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
* Determines whether an array includes a certain element, returning true or false as appropriate.
* @param searchElement The element to search for.
* @param fromIndex The position in this array at which to begin searching for searchElement.
*/
includes(searchElement: number, fromIndex?: number): boolean;
}
+12 -12
View File
@@ -1,25 +1,25 @@
interface ObjectConstructor {
/**
* Returns an array of values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
* Returns an array of values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
values<T>(o: { [s: string]: T }): T[];
/**
* Returns an array of values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
* Returns an array of values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
values(o: any): any[];
/**
* Returns an array of key/values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
* Returns an array of key/values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
entries<T>(o: { [s: string]: T }): [string, T][];
/**
* Returns an array of key/values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
* Returns an array of key/values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
entries(o: any): [string, any][];
}
+4 -4
View File
@@ -3,8 +3,8 @@
interface SharedArrayBuffer {
/**
* Read-only. The length of the ArrayBuffer (in bytes).
*/
* Read-only. The length of the ArrayBuffer (in bytes).
*/
readonly byteLength: number;
/*
@@ -12,8 +12,8 @@ interface SharedArrayBuffer {
*/
length: number;
/**
* Returns a section of an SharedArrayBuffer.
*/
* Returns a section of an SharedArrayBuffer.
*/
slice(begin: number, end?: number): SharedArrayBuffer;
readonly [Symbol.species]: SharedArrayBuffer;
readonly [Symbol.toStringTag]: "SharedArrayBuffer";
+20 -20
View File
@@ -1,27 +1,27 @@
interface String {
/**
* Pads the current string with a given string (possibly repeated) so that the resulting string reaches a given length.
* The padding is applied from the start (left) of the current string.
*
* @param maxLength The length of the resulting string once the current string has been padded.
* If this parameter is smaller than the current string's length, the current string will be returned as it is.
*
* @param fillString The string to pad the current string with.
* If this string is too long, it will be truncated and the left-most part will be applied.
* The default value for this parameter is " " (U+0020).
*/
* Pads the current string with a given string (possibly repeated) so that the resulting string reaches a given length.
* The padding is applied from the start (left) of the current string.
*
* @param maxLength The length of the resulting string once the current string has been padded.
* If this parameter is smaller than the current string's length, the current string will be returned as it is.
*
* @param fillString The string to pad the current string with.
* If this string is too long, it will be truncated and the left-most part will be applied.
* The default value for this parameter is " " (U+0020).
*/
padStart(maxLength: number, fillString?: string): string;
/**
* Pads the current string with a given string (possibly repeated) so that the resulting string reaches a given length.
* The padding is applied from the end (right) of the current string.
*
* @param maxLength The length of the resulting string once the current string has been padded.
* If this parameter is smaller than the current string's length, the current string will be returned as it is.
*
* @param fillString The string to pad the current string with.
* If this string is too long, it will be truncated and the left-most part will be applied.
* The default value for this parameter is " " (U+0020).
*/
* Pads the current string with a given string (possibly repeated) so that the resulting string reaches a given length.
* The padding is applied from the end (right) of the current string.
*
* @param maxLength The length of the resulting string once the current string has been padded.
* If this parameter is smaller than the current string's length, the current string will be returned as it is.
*
* @param fillString The string to pad the current string with.
* If this string is too long, it will be truncated and the left-most part will be applied.
* The default value for this parameter is " " (U+0020).
*/
padEnd(maxLength: number, fillString?: string): string;
}
+3 -3
View File
@@ -99,9 +99,9 @@ interface TextStreamReader extends TextStreamBase {
declare var WScript: {
/**
* Outputs text to either a message box (under WScript.exe) or the command console window followed by
* a newline (under CScript.exe).
*/
* Outputs text to either a message box (under WScript.exe) or the command console window followed by
* a newline (under CScript.exe).
*/
Echo(s: any): void;
/**
+1 -1
View File
@@ -191,7 +191,7 @@ namespace ts.server {
const l = lf.scriptInfo.fileName;
const r = rf.scriptInfo.fileName;
return (l < r ? -1 : (l > r ? 1 : 0));
};
}
static addToReferenceList(array: ModuleBuilderFileInfo[], fileInfo: ModuleBuilderFileInfo) {
if (array.length === 0) {
+2 -1
View File
@@ -178,7 +178,8 @@ namespace ts.server {
kindModifiers: response.body.kindModifiers,
textSpan: ts.createTextSpanFromBounds(start, end),
displayParts: [{ kind: "text", text: response.body.displayString }],
documentation: [{ kind: "text", text: response.body.documentation }]
documentation: [{ kind: "text", text: response.body.documentation }],
tags: response.body.tags
};
}
+170 -21
View File
@@ -35,6 +35,10 @@ namespace ts.server {
(event: ProjectServiceEvent): void;
}
export interface SafeList {
[name: string]: { match: RegExp, exclude?: Array<Array<string | number>>, types?: string[] };
}
function prepareConvertersForEnumLikeCompilerOptions(commandLineOptions: CommandLineOption[]): Map<Map<number>> {
const map: Map<Map<number>> = createMap<Map<number>>();
for (const option of commandLineOptions) {
@@ -57,6 +61,55 @@ namespace ts.server {
"smart": IndentStyle.Smart
});
/**
* How to understand this block:
* * The 'match' property is a regexp that matches a filename.
* * If 'match' is successful, then:
* * All files from 'exclude' are removed from the project. See below.
* * All 'types' are included in ATA
* * What the heck is 'exclude' ?
* * An array of an array of strings and numbers
* * Each array is:
* * An array of strings and numbers
* * The strings are literals
* * The numbers refer to capture group indices from the 'match' regexp
* * Remember that '1' is the first group
* * These are concatenated together to form a new regexp
* * Filenames matching these regexps are excluded from the project
* This default value is tested in tsserverProjectSystem.ts; add tests there
* if you are changing this so that you can be sure your regexp works!
*/
const defaultTypeSafeList: SafeList = {
"jquery": {
// jquery files can have names like "jquery-1.10.2.min.js" (or "jquery.intellisense.js")
"match": /jquery(-(\.?\d+)+)?(\.intellisense)?(\.min)?\.js$/i,
"types": ["jquery"]
},
"WinJS": {
// e.g. c:/temp/UWApp1/lib/winjs-4.0.1/js/base.js
"match": /^(.*\/winjs-[.\d]+)\/js\/base\.js$/i, // If the winjs/base.js file is found..
"exclude": [["^", 1, "/.*"]], // ..then exclude all files under the winjs folder
"types": ["winjs"] // And fetch the @types package for WinJS
},
"Kendo": {
// e.g. /Kendo3/wwwroot/lib/kendo/kendo.all.min.js
"match": /^(.*\/kendo)\/kendo\.all\.min\.js$/i,
"exclude": [["^", 1, "/.*"]],
"types": ["kendo-ui"]
},
"Office Nuget": {
// e.g. /scripts/Office/1/excel-15.debug.js
"match": /^(.*\/office\/1)\/excel-\d+\.debug\.js$/i, // Office NuGet package is installed under a "1/office" folder
"exclude": [["^", 1, "/.*"]], // Exclude that whole folder if the file indicated above is found in it
"types": ["office"] // @types package to fetch instead
},
"Minified files": {
// e.g. /whatever/blah.min.js
"match": /^(.+\.min\.js)$/i,
"exclude": [["^", 1, "$"]]
}
};
export function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings {
if (typeof protocolOptions.indentStyle === "string") {
protocolOptions.indentStyle = indentStyle.get(protocolOptions.indentStyle.toLowerCase());
@@ -179,12 +232,12 @@ namespace ts.server {
class DirectoryWatchers {
/**
* a path to directory watcher map that detects added tsconfig files
**/
*/
private readonly directoryWatchersForTsconfig: Map<FileWatcher> = createMap<FileWatcher>();
/**
* count of how many projects are using the directory watcher.
* If the number becomes 0 for a watcher, then we should close it.
**/
*/
private readonly directoryWatchersRefCount: Map<number> = createMap<number>();
constructor(private readonly projectService: ProjectService) {
@@ -241,11 +294,11 @@ namespace ts.server {
readonly externalProjects: ExternalProject[] = [];
/**
* projects built from openFileRoots
**/
*/
readonly inferredProjects: InferredProject[] = [];
/**
* projects specified by a tsconfig.json file
**/
*/
readonly configuredProjects: ConfiguredProject[] = [];
/**
* list of open files
@@ -259,6 +312,7 @@ namespace ts.server {
private readonly throttledOperations: ThrottledOperations;
private readonly hostConfiguration: HostConfiguration;
private static safelist: SafeList = defaultTypeSafeList;
private changedFiles: ScriptInfo[];
@@ -271,7 +325,8 @@ namespace ts.server {
public readonly cancellationToken: HostCancellationToken,
public readonly useSingleInferredProject: boolean,
readonly typingsInstaller: ITypingsInstaller = nullTypingsInstaller,
private readonly eventHandler?: ProjectServiceEventHandler) {
private readonly eventHandler?: ProjectServiceEventHandler,
public readonly throttleWaitMilliseconds?: number) {
Debug.assert(!!host.createHash, "'ServerHost.createHash' is required for ProjectService");
@@ -283,8 +338,6 @@ namespace ts.server {
this.typingsCache = new TypingsCache(this.typingsInstaller);
// ts.disableIncrementalParsing = true;
this.hostConfiguration = {
formatCodeOptions: getDefaultFormatCodeSettings(this.host),
hostInfo: "Unknown host",
@@ -613,18 +666,23 @@ namespace ts.server {
// when creation inferred project for some file has added other open files into this project (i.e. as referenced files)
// we definitely don't want to delete the project that was just created
for (const f of this.openFiles) {
if (f.containingProjects.length === 0) {
if (f.containingProjects.length === 0 || !inferredProject.containsScriptInfo(f)) {
// this is orphaned file that we have not processed yet - skip it
continue;
}
const defaultProject = f.getDefaultProject();
if (isRootFileInInferredProject(info) && defaultProject !== inferredProject && inferredProject.containsScriptInfo(f)) {
// open file used to be root in inferred project,
// this inferred project is different from the one we've just created for current file
// and new inferred project references this open file.
// We should delete old inferred project and attach open file to the new one
this.removeProject(defaultProject);
f.attachToProject(inferredProject);
for (const fContainingProject of f.containingProjects) {
if (fContainingProject.projectKind === ProjectKind.Inferred &&
fContainingProject.isRoot(f) &&
fContainingProject !== inferredProject) {
// open file used to be root in inferred project,
// this inferred project is different from the one we've just created for current file
// and new inferred project references this open file.
// We should delete old inferred project and attach open file to the new one
this.removeProject(fContainingProject);
f.attachToProject(inferredProject);
}
}
}
}
@@ -636,9 +694,9 @@ namespace ts.server {
}
/**
* Remove this file from the set of open, non-configured files.
* @param info The file that has been closed or newly configured
*/
* Remove this file from the set of open, non-configured files.
* @param info The file that has been closed or newly configured
*/
private closeOpenFile(info: ScriptInfo): void {
// Closing file should trigger re-reading the file content from disk. This is
// because the user may chose to discard the buffer content before saving
@@ -830,7 +888,7 @@ namespace ts.server {
getDirectoryPath(configFilename),
/*existingOptions*/ {},
configFilename,
/*resolutionStack*/ [],
/*resolutionStack*/[],
this.hostConfiguration.extraFileExtensions);
if (parsedCommandLine.errors.length) {
@@ -1061,7 +1119,7 @@ namespace ts.server {
const { success, projectOptions, configFileErrors } = this.convertConfigFileContentToProjectOptions(project.getConfigFilePath());
if (!success) {
// reset project settings to default
this.updateNonInferredProject(project, [], fileNamePropertyReader, {}, {}, /*compileOnSave*/false, configFileErrors);
this.updateNonInferredProject(project, [], fileNamePropertyReader, {}, {}, /*compileOnSave*/ false, configFileErrors);
return configFileErrors;
}
@@ -1398,6 +1456,94 @@ namespace ts.server {
this.refreshInferredProjects();
}
/** Makes a filename safe to insert in a RegExp */
private static filenameEscapeRegexp = /[-\/\\^$*+?.()|[\]{}]/g;
private static escapeFilenameForRegex(filename: string) {
return filename.replace(this.filenameEscapeRegexp, "\\$&");
}
resetSafeList(): void {
ProjectService.safelist = defaultTypeSafeList;
}
loadSafeList(fileName: string): void {
const raw: SafeList = JSON.parse(this.host.readFile(fileName, "utf-8"));
// Parse the regexps
for (const k of Object.keys(raw)) {
raw[k].match = new RegExp(raw[k].match as {} as string, "i");
}
// raw is now fixed and ready
ProjectService.safelist = raw;
}
applySafeList(proj: protocol.ExternalProject): void {
const { rootFiles, typeAcquisition } = proj;
const types = (typeAcquisition && typeAcquisition.include) || [];
const excludeRules: string[] = [];
const normalizedNames = rootFiles.map(f => normalizeSlashes(f.fileName));
for (const name of Object.keys(ProjectService.safelist)) {
const rule = ProjectService.safelist[name];
for (const root of normalizedNames) {
if (rule.match.test(root)) {
this.logger.info(`Excluding files based on rule ${name}`);
// If the file matches, collect its types packages and exclude rules
if (rule.types) {
for (const type of rule.types) {
if (types.indexOf(type) < 0) {
types.push(type);
}
}
}
if (rule.exclude) {
for (const exclude of rule.exclude) {
const processedRule = root.replace(rule.match, (...groups: Array<string>) => {
return exclude.map(groupNumberOrString => {
// RegExp group numbers are 1-based, but the first element in groups
// is actually the original string, so it all works out in the end.
if (typeof groupNumberOrString === "number") {
if (typeof groups[groupNumberOrString] !== "string") {
// Specification was wrong - exclude nothing!
this.logger.info(`Incorrect RegExp specification in safelist rule ${name} - not enough groups`);
// * can't appear in a filename; escape it because it's feeding into a RegExp
return "\\*";
}
return ProjectService.escapeFilenameForRegex(groups[groupNumberOrString]);
}
return groupNumberOrString;
}).join("");
});
if (excludeRules.indexOf(processedRule) === -1) {
excludeRules.push(processedRule);
}
}
}
else {
// If not rules listed, add the default rule to exclude the matched file
const escaped = ProjectService.escapeFilenameForRegex(root);
if (excludeRules.indexOf(escaped) < 0) {
excludeRules.push(escaped);
}
}
}
}
// Copy back this field into the project if needed
if (types.length > 0) {
proj.typeAcquisition = proj.typeAcquisition || {};
proj.typeAcquisition.include = types;
}
}
const excludeRegexes = excludeRules.map(e => new RegExp(e, "i"));
proj.rootFiles = proj.rootFiles.filter((_file, index) => !excludeRegexes.some(re => re.test(normalizedNames[index])));
}
openExternalProject(proj: protocol.ExternalProject, suppressRefreshOfInferredProjects = false): void {
// typingOptions has been deprecated and is only supported for backward compatibility
// purposes. It should be removed in future releases - use typeAcquisition instead.
@@ -1405,6 +1551,9 @@ namespace ts.server {
const typeAcquisition = convertEnableAutoDiscoveryToEnable(proj.typingOptions);
proj.typeAcquisition = typeAcquisition;
}
this.applySafeList(proj);
let tsConfigFiles: NormalizedPath[];
const rootFiles: protocol.ExternalFile[] = [];
for (const file of proj.rootFiles) {
+1
View File
@@ -16,6 +16,7 @@ namespace ts.server {
readonly realpath?: (path: string) => string;
constructor(private readonly host: ServerHost, private readonly project: Project, private readonly cancellationToken: HostCancellationToken) {
this.cancellationToken = new ThrottledCancellationToken(cancellationToken, project.projectService.throttleWaitMilliseconds);
this.getCanonicalFileName = ts.createGetCanonicalFileName(this.host.useCaseSensitiveFileNames);
if (host.trace) {
+480 -465
View File
File diff suppressed because it is too large Load Diff
+19 -3
View File
@@ -261,10 +261,26 @@ namespace ts.server {
}
getDefaultProject() {
if (this.containingProjects.length === 0) {
return Errors.ThrowNoProject();
switch (this.containingProjects.length) {
case 0:
return Errors.ThrowNoProject();
case 1:
return this.containingProjects[0];
default:
// if this file belongs to multiple projects, the first configured project should be
// the default project; if no configured projects, the first external project should
// be the default project; otherwise the first inferred project should be the default.
let firstExternalProject;
for (const project of this.containingProjects) {
if (project.projectKind === ProjectKind.Configured) {
return project;
}
else if (project.projectKind === ProjectKind.External && !firstExternalProject) {
firstExternalProject = project;
}
}
return firstExternalProject || this.containingProjects[0];
}
return this.containingProjects[0];
}
registerFileUpdate(): void {
+13 -6
View File
@@ -1,8 +1,6 @@
/// <reference types="node" />
/// <reference path="shared.ts" />
/// <reference path="session.ts" />
// used in fs.writeSync
/* tslint:disable:no-null-keyword */
namespace ts.server {
@@ -196,7 +194,8 @@ namespace ts.server {
}
if (this.fd >= 0) {
const buf = new Buffer(s);
fs.writeSync(this.fd, buf, 0, buf.length, null);
// tslint:disable-next-line no-null-keyword
fs.writeSync(this.fd, buf, 0, buf.length, /*position*/ null);
}
if (this.traceToConsole) {
console.warn(s);
@@ -219,6 +218,7 @@ namespace ts.server {
host: ServerHost,
eventPort: number,
readonly globalTypingsCacheLocation: string,
readonly typingSafeListLocation: string,
private newLine: string) {
this.throttledOperations = new ThrottledOperations(host);
if (eventPort) {
@@ -260,6 +260,9 @@ namespace ts.server {
if (this.logger.loggingEnabled() && this.logger.getLogFileName()) {
args.push(Arguments.LogFile, combinePaths(getDirectoryPath(normalizeSlashes(this.logger.getLogFileName())), `ti-${process.pid}.log`));
}
if (this.typingSafeListLocation) {
args.push(Arguments.TypingSafeListLocation, this.typingSafeListLocation);
}
const execArgv: string[] = [];
{
for (const arg of process.execArgv) {
@@ -378,11 +381,12 @@ namespace ts.server {
useSingleInferredProject: boolean,
disableAutomaticTypingAcquisition: boolean,
globalTypingsCacheLocation: string,
typingSafeListLocation: string,
telemetryEnabled: boolean,
logger: server.Logger) {
const typingsInstaller = disableAutomaticTypingAcquisition
? undefined
: new NodeTypingsInstaller(telemetryEnabled, logger, host, installerEventPort, globalTypingsCacheLocation, host.newLine);
: new NodeTypingsInstaller(telemetryEnabled, logger, host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, host.newLine);
super(
host,
@@ -697,7 +701,7 @@ namespace ts.server {
}
sys.require = (initialDir: string, moduleName: string): RequireResult => {
const result = nodeModuleNameResolverWorker(moduleName, initialDir + "/program.ts", { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, sys, undefined, /*jsOnly*/ true);
const result = nodeModuleNameResolverWorker(moduleName, initialDir + "/program.ts", { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, sys, /*cache*/ undefined, /*jsOnly*/ true);
try {
return { module: require(result.resolvedModule.resolvedFileName), error: undefined };
}
@@ -713,7 +717,7 @@ namespace ts.server {
}
catch (e) {
cancellationToken = nullCancellationToken;
};
}
let eventPort: number;
{
@@ -729,6 +733,8 @@ namespace ts.server {
validateLocaleAndSetLanguage(localeStr, sys);
}
const typingSafeListLocation = findArgument("--typingSafeListLocation");
const useSingleInferredProject = hasArgument("--useSingleInferredProject");
const disableAutomaticTypingAcquisition = hasArgument("--disableAutomaticTypingAcquisition");
const telemetryEnabled = hasArgument(Arguments.EnableTelemetry);
@@ -741,6 +747,7 @@ namespace ts.server {
useSingleInferredProject,
disableAutomaticTypingAcquisition,
getGlobalTypingsCacheLocation(),
typingSafeListLocation,
telemetryEnabled,
logger);
process.on("uncaughtException", function (err: Error) {
+30 -16
View File
@@ -31,7 +31,8 @@ namespace ts.server {
}
else {
// For configured projects, require that skipLibCheck be set also
return project.getCompilerOptions().skipLibCheck && project.isJsOnlyProject();
const options = project.getCompilerOptions();
return options.skipLibCheck && !options.checkJs && project.isJsOnlyProject();
}
}
@@ -218,7 +219,7 @@ namespace ts.server {
getCurrentRequestId(): number;
sendRequestCompletedEvent(requestId: number): void;
getServerHost(): ServerHost;
isCancellationRequested(): boolean;
isCancellationRequested(): boolean;
executeWithRequestId(requestId: number, action: () => void): void;
logError(error: Error, message: string): void;
}
@@ -299,7 +300,7 @@ namespace ts.server {
}
}
private setTimerHandle(timerHandle: any) {;
private setTimerHandle(timerHandle: any) {
if (this.timerHandle !== undefined) {
this.operationHost.getServerHost().clearTimeout(this.timerHandle);
}
@@ -337,7 +338,8 @@ namespace ts.server {
private hrtime: (start?: number[]) => number[],
protected logger: Logger,
protected readonly canUseEvents: boolean,
eventHandler?: ProjectServiceEventHandler) {
eventHandler?: ProjectServiceEventHandler,
private readonly throttleWaitMilliseconds?: number) {
this.eventHander = canUseEvents
? eventHandler || (event => this.defaultEventHandler(event))
@@ -352,7 +354,7 @@ namespace ts.server {
isCancellationRequested: () => cancellationToken.isCancellationRequested()
};
this.errorCheck = new MultistepOperation(multistepOperationHost);
this.projectService = new ProjectService(host, logger, cancellationToken, useSingleInferredProject, typingsInstaller, this.eventHander);
this.projectService = new ProjectService(host, logger, cancellationToken, useSingleInferredProject, typingsInstaller, this.eventHander, this.throttleWaitMilliseconds);
this.gcTimer = new GcTimer(host, /*delay*/ 7000, logger);
}
@@ -756,6 +758,17 @@ namespace ts.server {
return projects;
}
private getDefaultProject(args: protocol.FileRequestArgs) {
if (args.projectFileName) {
const project = this.getProject(args.projectFileName);
if (project) {
return project;
}
}
const info = this.projectService.getScriptInfo(args.file);
return info.getDefaultProject();
}
private getRenameLocations(args: protocol.RenameRequestArgs, simplifiedResult: boolean): protocol.RenameResponseBody | RenameLocation[] {
const file = toNormalizedPath(args.file);
const info = this.projectService.getScriptInfoForNormalizedPath(file);
@@ -763,7 +776,7 @@ namespace ts.server {
const projects = this.getProjects(args);
if (simplifiedResult) {
const defaultProject = projects[0];
const defaultProject = this.getDefaultProject(args);
// The rename info should be the same for every project
const renameInfo = defaultProject.getLanguageService().getRenameInfo(file, position);
if (!renameInfo) {
@@ -862,7 +875,7 @@ namespace ts.server {
const file = toNormalizedPath(args.file);
const projects = this.getProjects(args);
const defaultProject = projects[0];
const defaultProject = this.getDefaultProject(args);
const scriptInfo = defaultProject.getScriptInfoForNormalizedPath(file);
const position = this.getPosition(args, scriptInfo);
if (simplifiedResult) {
@@ -913,9 +926,8 @@ namespace ts.server {
return combineProjectOutput(
projects,
project => project.getLanguageService().findReferences(file, position),
undefined,
// TODO: fixme
undefined
/*comparer*/ undefined,
/*areEqual (TODO: fixme)*/ undefined
);
}
@@ -1018,6 +1030,7 @@ namespace ts.server {
if (simplifiedResult) {
const displayString = ts.displayPartsToString(quickInfo.displayParts);
const docString = ts.displayPartsToString(quickInfo.documentation);
return {
kind: quickInfo.kind,
kindModifiers: quickInfo.kindModifiers,
@@ -1025,6 +1038,7 @@ namespace ts.server {
end: scriptInfo.positionToLineOffset(ts.textSpanEnd(quickInfo.textSpan)),
displayString: displayString,
documentation: docString,
tags: quickInfo.tags || []
};
}
else {
@@ -1540,17 +1554,17 @@ namespace ts.server {
[CommandNames.OpenExternalProject]: (request: protocol.OpenExternalProjectRequest) => {
this.projectService.openExternalProject(request.arguments, /*suppressRefreshOfInferredProjects*/ false);
// TODO: report errors
return this.requiredResponse(true);
return this.requiredResponse(/*response*/ true);
},
[CommandNames.OpenExternalProjects]: (request: protocol.OpenExternalProjectsRequest) => {
this.projectService.openExternalProjects(request.arguments.projects);
// TODO: report errors
return this.requiredResponse(true);
return this.requiredResponse(/*response*/ true);
},
[CommandNames.CloseExternalProject]: (request: protocol.CloseExternalProjectRequest) => {
this.projectService.closeExternalProject(request.arguments.projectFileName);
// TODO: report errors
return this.requiredResponse(true);
return this.requiredResponse(/*response*/ true);
},
[CommandNames.SynchronizeProjectList]: (request: protocol.SynchronizeProjectListRequest) => {
const result = this.projectService.synchronizeProjectList(request.arguments.knownProjects);
@@ -1574,7 +1588,7 @@ namespace ts.server {
this.projectService.applyChangesInOpenFiles(request.arguments.openFiles, request.arguments.changedFiles, request.arguments.closedFiles);
this.changeSeq++;
// TODO: report errors
return this.requiredResponse(true);
return this.requiredResponse(/*response*/ true);
},
[CommandNames.Exit]: () => {
this.exit();
@@ -1685,7 +1699,7 @@ namespace ts.server {
},
[CommandNames.Cleanup]: () => {
this.cleanup();
return this.requiredResponse(true);
return this.requiredResponse(/*response*/ true);
},
[CommandNames.SemanticDiagnosticsSync]: (request: protocol.SemanticDiagnosticsSyncRequest) => {
return this.requiredResponse(this.getSemanticDiagnosticsSync(request.arguments));
@@ -1759,7 +1773,7 @@ namespace ts.server {
},
[CommandNames.CompilerOptionsForInferredProjects]: (request: protocol.SetCompilerOptionsForInferredProjectsRequest) => {
this.setCompilerOptionsForInferredProjects(request.arguments);
return this.requiredResponse(true);
return this.requiredResponse(/*response*/ true);
},
[CommandNames.ProjectInfo]: (request: protocol.ProjectInfoRequest) => {
return this.requiredResponse(this.getProjectInfo(request.arguments));
+1
View File
@@ -11,6 +11,7 @@ namespace ts.server {
export const GlobalCacheLocation = "--globalTypingsCacheLocation";
export const LogFile = "--logFile";
export const EnableTelemetry = "--enableTelemetry";
export const TypingSafeListLocation = "--typingSafeListLocation";
}
export function hasArgument(argumentName: string) {
@@ -76,11 +76,11 @@ namespace ts.server.typingsInstaller {
private delayedInitializationError: InitializationFailedResponse;
constructor(globalTypingsCacheLocation: string, throttleLimit: number, log: Log) {
constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, throttleLimit: number, log: Log) {
super(
sys,
globalTypingsCacheLocation,
toPath("typingSafeList.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
typingSafeListLocation ? toPath(typingSafeListLocation, "", createGetCanonicalFileName(sys.useCaseSensitiveFileNames)) : toPath("typingSafeList.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
throttleLimit,
log);
if (this.log.isEnabled()) {
@@ -164,6 +164,7 @@ namespace ts.server.typingsInstaller {
const logFilePath = findArgument(server.Arguments.LogFile);
const globalTypingsCacheLocation = findArgument(server.Arguments.GlobalCacheLocation);
const typingSafeListLocation = findArgument(server.Arguments.TypingSafeListLocation);
const log = new FileLog(logFilePath);
if (log.isEnabled()) {
@@ -177,6 +178,6 @@ namespace ts.server.typingsInstaller {
}
process.exit(0);
});
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, /*throttleLimit*/5, log);
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, typingSafeListLocation, /*throttleLimit*/5, log);
installer.listen();
}
+2 -2
View File
@@ -166,11 +166,11 @@ namespace ts.server {
export interface ProjectOptions {
/**
* true if config file explicitly listed files
**/
*/
configHasFilesProperty?: boolean;
/**
* these fields can be present in the project file
**/
*/
files?: string[];
wildcardDirectories?: Map<WatchDirectoryFlags>;
compilerOptions?: CompilerOptions;
@@ -0,0 +1,70 @@
/* @internal */
namespace ts.codefix {
registerCodeFix({
errorCodes: getApplicableDiagnosticCodes(),
getCodeActions: getDisableJsDiagnosticsCodeActions
});
function getApplicableDiagnosticCodes(): number[] {
const allDiagnostcs = <MapLike<DiagnosticMessage>>Diagnostics;
return Object.keys(allDiagnostcs)
.filter(d => allDiagnostcs[d] && allDiagnostcs[d].category === DiagnosticCategory.Error)
.map(d => allDiagnostcs[d].code);
}
function getIgnoreCommentLocationForLocation(sourceFile: SourceFile, position: number, newLineCharacter: string) {
const { line } = getLineAndCharacterOfPosition(sourceFile, position);
const lineStartPosition = getStartPositionOfLine(line, sourceFile);
const startPosition = getFirstNonSpaceCharacterPosition(sourceFile.text, lineStartPosition);
// First try to see if we can put the '// @ts-ignore' on the previous line.
// We need to make sure that we are not in the middle of a string literal or a comment.
// We also want to check if the previous line holds a comment for a node on the next line
// if so, we do not want to separate the node from its comment if we can.
if (!isInComment(sourceFile, startPosition) && !isInString(sourceFile, startPosition) && !isInTemplateString(sourceFile, startPosition)) {
const token = getTouchingToken(sourceFile, startPosition);
const tokenLeadingCommnets = getLeadingCommentRangesOfNode(token, sourceFile);
if (!tokenLeadingCommnets || !tokenLeadingCommnets.length || tokenLeadingCommnets[0].pos >= startPosition) {
return {
span: { start: startPosition, length: 0 },
newText: `// @ts-ignore${newLineCharacter}`
};
}
}
// If all fails, add an extra new line immediatlly before the error span.
return {
span: { start: position, length: 0 },
newText: `${position === startPosition ? "" : newLineCharacter}// @ts-ignore${newLineCharacter}`
};
}
function getDisableJsDiagnosticsCodeActions(context: CodeFixContext): CodeAction[] | undefined {
const { sourceFile, program, newLineCharacter, span } = context;
if (!isInJavaScriptFile(sourceFile) || !isCheckJsEnabledForFile(sourceFile, program.getCompilerOptions())) {
return undefined;
}
return [{
description: getLocaleSpecificMessage(Diagnostics.Ignore_this_error_message),
changes: [{
fileName: sourceFile.fileName,
textChanges: [getIgnoreCommentLocationForLocation(sourceFile, span.start, newLineCharacter)]
}]
},
{
description: getLocaleSpecificMessage(Diagnostics.Disable_checking_for_this_file),
changes: [{
fileName: sourceFile.fileName,
textChanges: [{
span: {
start: sourceFile.checkJsDirective ? sourceFile.checkJsDirective.pos : 0,
length: sourceFile.checkJsDirective ? sourceFile.checkJsDirective.end - sourceFile.checkJsDirective.pos : 0
},
newText: `// @ts-nocheck${newLineCharacter}`
}]
}]
}];
}
}
+98 -45
View File
@@ -18,68 +18,121 @@ namespace ts.codefix {
return undefined;
}
const classDeclaration = getContainingClass(token);
if (!classDeclaration) {
if (!isPropertyAccessExpression(token.parent) || token.parent.expression.kind !== SyntaxKind.ThisKeyword) {
return undefined;
}
if (!(token.parent && token.parent.kind === SyntaxKind.PropertyAccessExpression)) {
const classMemberDeclaration = getThisContainer(token, /*includeArrowFunctions*/ false);
if (!isClassElement(classMemberDeclaration)) {
return undefined;
}
if ((token.parent as PropertyAccessExpression).expression.kind !== SyntaxKind.ThisKeyword) {
const classDeclaration = <ClassLikeDeclaration>classMemberDeclaration.parent;
if (!classDeclaration || !isClassLike(classDeclaration)) {
return undefined;
}
let typeNode: TypeNode;
const isStatic = hasModifier(classMemberDeclaration, ModifierFlags.Static);
if (token.parent.parent.kind === SyntaxKind.BinaryExpression) {
const binaryExpression = token.parent.parent as BinaryExpression;
return isInJavaScriptFile(sourceFile) ? getActionsForAddMissingMemberInJavaScriptFile() : getActionsForAddMissingMemberInTypeScriptFile();
const checker = context.program.getTypeChecker();
const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(binaryExpression.right)));
typeNode = checker.typeToTypeNode(widenedType, classDeclaration) || typeNode;
function getActionsForAddMissingMemberInJavaScriptFile(): CodeAction[] | undefined {
const memberName = token.getText();
if (isStatic) {
if (classDeclaration.kind === SyntaxKind.ClassExpression) {
return undefined;
}
const className = classDeclaration.name.getText();
return [{
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Initialize_static_property_0), [memberName]),
changes: [{
fileName: sourceFile.fileName,
textChanges: [{
span: { start: classDeclaration.getEnd(), length: 0 },
newText: `${context.newLineCharacter}${className}.${memberName} = undefined;${context.newLineCharacter}`
}]
}]
}];
}
else {
const classConstructor = getFirstConstructorWithBody(classDeclaration);
if (!classConstructor) {
return undefined;
}
return [{
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Initialize_property_0_in_the_constructor), [memberName]),
changes: [{
fileName: sourceFile.fileName,
textChanges: [{
span: { start: classConstructor.body.getEnd() - 1, length: 0 },
newText: `this.${memberName} = undefined;${context.newLineCharacter}`
}]
}]
}];
}
}
typeNode = typeNode ? typeNode : createKeywordTypeNode(SyntaxKind.AnyKeyword);
function getActionsForAddMissingMemberInTypeScriptFile(): CodeAction[] | undefined {
let typeNode: TypeNode;
const openBrace = getOpenBraceOfClassLike(classDeclaration, sourceFile);
if (token.parent.parent.kind === SyntaxKind.BinaryExpression) {
const binaryExpression = token.parent.parent as BinaryExpression;
const property = createProperty(
/*decorators*/undefined,
/*modifiers*/ undefined,
token.getText(sourceFile),
/*questionToken*/ undefined,
typeNode,
/*initializer*/ undefined);
const propertyChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
propertyChangeTracker.insertNodeAfter(sourceFile, openBrace, property, { suffix: context.newLineCharacter });
const checker = context.program.getTypeChecker();
const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(binaryExpression.right)));
typeNode = checker.typeToTypeNode(widenedType, classDeclaration);
}
const stringTypeNode = createKeywordTypeNode(SyntaxKind.StringKeyword);
const indexingParameter = createParameter(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
"x",
/*questionToken*/ undefined,
stringTypeNode,
/*initializer*/ undefined);
const indexSignature = createIndexSignatureDeclaration(
/*decorators*/undefined,
/*modifiers*/ undefined,
[indexingParameter],
typeNode);
typeNode = typeNode || createKeywordTypeNode(SyntaxKind.AnyKeyword);
const indexSignatureChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
indexSignatureChangeTracker.insertNodeAfter(sourceFile, openBrace, indexSignature, { suffix: context.newLineCharacter });
const openBrace = getOpenBraceOfClassLike(classDeclaration, sourceFile);
return [{
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_declaration_for_missing_property_0), [token.getText()]),
changes: propertyChangeTracker.getChanges()
},
{
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_missing_property_0), [token.getText()]),
changes: indexSignatureChangeTracker.getChanges()
}];
const property = createProperty(
/*decorators*/undefined,
/*modifiers*/ isStatic ? [createToken(SyntaxKind.StaticKeyword)] : undefined,
token.getText(sourceFile),
/*questionToken*/ undefined,
typeNode,
/*initializer*/ undefined);
const propertyChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
propertyChangeTracker.insertNodeAfter(sourceFile, openBrace, property, { suffix: context.newLineCharacter });
const actions = [{
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_declaration_for_missing_property_0), [token.getText()]),
changes: propertyChangeTracker.getChanges()
}];
if (!isStatic) {
const stringTypeNode = createKeywordTypeNode(SyntaxKind.StringKeyword);
const indexingParameter = createParameter(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
"x",
/*questionToken*/ undefined,
stringTypeNode,
/*initializer*/ undefined);
const indexSignature = createIndexSignatureDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
[indexingParameter],
typeNode);
const indexSignatureChangeTracker = textChanges.ChangeTracker.fromCodeFixContext(context);
indexSignatureChangeTracker.insertNodeAfter(sourceFile, openBrace, indexSignature, { suffix: context.newLineCharacter });
actions.push({
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_missing_property_0), [token.getText()]),
changes: indexSignatureChangeTracker.getChanges()
});
}
return actions;
}
}
}
+1
View File
@@ -7,4 +7,5 @@
/// <reference path="fixForgottenThisPropertyAccess.ts" />
/// <reference path='unusedIdentifierFixes.ts' />
/// <reference path='importFixes.ts' />
/// <reference path='disableJsDiagnostics.ts' />
/// <reference path='helpers.ts' />
+4 -4
View File
@@ -146,7 +146,7 @@ namespace ts.codefix {
/** This is *a* signature with the maximal number of arguments,
* such that if there is a "maximal" signature without rest arguments,
* this is one of them.
*/
*/
let maxArgsSignature = signatures[0];
let minArgumentCount = signatures[0].minArgumentCount;
let someSigHasRestParameter = false;
@@ -194,7 +194,7 @@ namespace ts.codefix {
modifiers,
name,
optional,
/*typeParameters*/undefined,
/*typeParameters*/ undefined,
parameters,
/*returnType*/ undefined);
}
@@ -217,9 +217,9 @@ namespace ts.codefix {
[createThrow(
createNew(
createIdentifier("Error"),
/*typeArguments*/undefined,
/*typeArguments*/ undefined,
[createLiteral("Method not implemented.")]))],
/*multiline*/true);
/*multiline*/ true);
}
function createVisibilityModifier(flags: ModifierFlags) {
+2 -2
View File
@@ -543,12 +543,12 @@ namespace ts.codefix {
}
function getRelativePathIfInDirectory(path: string, directoryPath: string) {
const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, false);
const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
return isRootedDiskPath(relativePath) || startsWith(relativePath, "..") ? undefined : relativePath;
}
function getRelativePath(path: string, directoryPath: string) {
const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, false);
const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
return moduleHasNonRelativeName(relativePath) ? "./" + relativePath : relativePath;
}
}
@@ -118,7 +118,7 @@ namespace ts.codefix {
const nextToken = getTokenAtPosition(sourceFile, importClause.name.end);
if (nextToken && nextToken.kind === SyntaxKind.CommaToken) {
// shift first non-whitespace position after comma to the start position of the node
return deleteRange({ pos: start, end: skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/true) });
return deleteRange({ pos: start, end: skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/ true) });
}
else {
return deleteNode(importClause.name);
+8 -6
View File
@@ -173,7 +173,7 @@ namespace ts.Completions {
// a['/*completion position*/']
return getStringLiteralCompletionEntriesFromElementAccess(node.parent, typeChecker, compilerOptions.target, log);
}
else if (node.parent.kind === SyntaxKind.ImportDeclaration || isExpressionOfExternalModuleImportEqualsDeclaration(node) || isRequireCall(node.parent, false)) {
else if (node.parent.kind === SyntaxKind.ImportDeclaration || isExpressionOfExternalModuleImportEqualsDeclaration(node) || isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false)) {
// Get all known external module names or complete a path to a module
// i.e. import * as ns from "/*completion position*/";
// import x = require("/*completion position*/");
@@ -211,7 +211,7 @@ namespace ts.Completions {
const type = typeChecker.getContextualType((<ObjectLiteralExpression>element.parent));
const entries: CompletionEntry[] = [];
if (type) {
getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, element, /*performCharacterChecks*/false, typeChecker, target, log);
getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, element, /*performCharacterChecks*/ false, typeChecker, target, log);
if (entries.length) {
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries };
}
@@ -239,7 +239,7 @@ namespace ts.Completions {
const type = typeChecker.getTypeAtLocation(node.expression);
const entries: CompletionEntry[] = [];
if (type) {
getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/false, typeChecker, target, log);
getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/ false, typeChecker, target, log);
if (entries.length) {
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries };
}
@@ -293,13 +293,14 @@ namespace ts.Completions {
const symbol = forEach(symbols, s => getCompletionEntryDisplayNameForSymbol(typeChecker, s, compilerOptions.target, /*performCharacterChecks*/ false, location) === entryName ? s : undefined);
if (symbol) {
const { displayParts, documentation, symbolKind } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, location, location, SemanticMeaning.All);
const { displayParts, documentation, symbolKind, tags } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, location, location, SemanticMeaning.All);
return {
name: entryName,
kindModifiers: SymbolDisplay.getSymbolModifiers(symbol),
kind: symbolKind,
displayParts,
documentation
documentation,
tags
};
}
}
@@ -312,7 +313,8 @@ namespace ts.Completions {
kind: ScriptElementKind.keyword,
kindModifiers: ScriptElementKindModifier.none,
displayParts: [displayPart(entryName, SymbolDisplayPartKind.keyword)],
documentation: undefined
documentation: undefined,
tags: undefined
};
}
+47 -47
View File
@@ -1,34 +1,34 @@
namespace ts {
/**
* The document registry represents a store of SourceFile objects that can be shared between
* multiple LanguageService instances. A LanguageService instance holds on the SourceFile (AST)
* of files in the context.
* SourceFile objects account for most of the memory usage by the language service. Sharing
* the same DocumentRegistry instance between different instances of LanguageService allow
* for more efficient memory utilization since all projects will share at least the library
* file (lib.d.ts).
*
* A more advanced use of the document registry is to serialize sourceFile objects to disk
* and re-hydrate them when needed.
*
* To create a default DocumentRegistry, use createDocumentRegistry to create one, and pass it
* to all subsequent createLanguageService calls.
*/
* The document registry represents a store of SourceFile objects that can be shared between
* multiple LanguageService instances. A LanguageService instance holds on the SourceFile (AST)
* of files in the context.
* SourceFile objects account for most of the memory usage by the language service. Sharing
* the same DocumentRegistry instance between different instances of LanguageService allow
* for more efficient memory utilization since all projects will share at least the library
* file (lib.d.ts).
*
* A more advanced use of the document registry is to serialize sourceFile objects to disk
* and re-hydrate them when needed.
*
* To create a default DocumentRegistry, use createDocumentRegistry to create one, and pass it
* to all subsequent createLanguageService calls.
*/
export interface DocumentRegistry {
/**
* Request a stored SourceFile with a given fileName and compilationSettings.
* The first call to acquire will call createLanguageServiceSourceFile to generate
* the SourceFile if was not found in the registry.
*
* @param fileName The name of the file requested
* @param compilationSettings Some compilation settings like target affects the
* shape of a the resulting SourceFile. This allows the DocumentRegistry to store
* multiple copies of the same file for different compilation settings.
* @parm scriptSnapshot Text of the file. Only used if the file was not found
* in the registry and a new one was created.
* @parm version Current version of the file. Only used if the file was not found
* in the registry and a new one was created.
*/
* Request a stored SourceFile with a given fileName and compilationSettings.
* The first call to acquire will call createLanguageServiceSourceFile to generate
* the SourceFile if was not found in the registry.
*
* @param fileName The name of the file requested
* @param compilationSettings Some compilation settings like target affects the
* shape of a the resulting SourceFile. This allows the DocumentRegistry to store
* multiple copies of the same file for different compilation settings.
* @parm scriptSnapshot Text of the file. Only used if the file was not found
* in the registry and a new one was created.
* @parm version Current version of the file. Only used if the file was not found
* in the registry and a new one was created.
*/
acquireDocument(
fileName: string,
compilationSettings: CompilerOptions,
@@ -46,17 +46,17 @@ namespace ts {
scriptKind?: ScriptKind): SourceFile;
/**
* Request an updated version of an already existing SourceFile with a given fileName
* and compilationSettings. The update will in-turn call updateLanguageServiceSourceFile
* to get an updated SourceFile.
*
* @param fileName The name of the file requested
* @param compilationSettings Some compilation settings like target affects the
* shape of a the resulting SourceFile. This allows the DocumentRegistry to store
* multiple copies of the same file for different compilation settings.
* @param scriptSnapshot Text of the file.
* @param version Current version of the file.
*/
* Request an updated version of an already existing SourceFile with a given fileName
* and compilationSettings. The update will in-turn call updateLanguageServiceSourceFile
* to get an updated SourceFile.
*
* @param fileName The name of the file requested
* @param compilationSettings Some compilation settings like target affects the
* shape of a the resulting SourceFile. This allows the DocumentRegistry to store
* multiple copies of the same file for different compilation settings.
* @param scriptSnapshot Text of the file.
* @param version Current version of the file.
*/
updateDocument(
fileName: string,
compilationSettings: CompilerOptions,
@@ -75,14 +75,14 @@ namespace ts {
getKeyForCompilationSettings(settings: CompilerOptions): DocumentRegistryBucketKey;
/**
* Informs the DocumentRegistry that a file is not needed any longer.
*
* Note: It is not allowed to call release on a SourceFile that was not acquired from
* this registry originally.
*
* @param fileName The name of the file to be released
* @param compilationSettings The compilation settings used to acquire the file
*/
* Informs the DocumentRegistry that a file is not needed any longer.
*
* Note: It is not allowed to call release on a SourceFile that was not acquired from
* this registry originally.
*
* @param fileName The name of the file to be released
* @param compilationSettings The compilation settings used to acquire the file
*/
releaseDocument(fileName: string, compilationSettings: CompilerOptions): void;
releaseDocumentWithKey(path: Path, key: DocumentRegistryBucketKey): void;
@@ -214,7 +214,7 @@ namespace ts {
}
function releaseDocumentWithKey(path: Path, key: DocumentRegistryBucketKey): void {
const bucket = getBucketForCompilationSettings(key, /*createIfMissing*/false);
const bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ false);
Debug.assert(bucket !== undefined);
const entry = bucket.get(path);
+5 -5
View File
@@ -187,7 +187,7 @@ namespace ts.FindAllReferences {
return { symbol };
}
if (ts.isUntypedOrShorthandAmbientModuleSymbol(aliasedSymbol)) {
if (ts.isShorthandAmbientModuleSymbol(aliasedSymbol)) {
return { symbol, shorthandModuleSymbol: aliasedSymbol };
}
@@ -496,9 +496,9 @@ namespace ts.FindAllReferences {
}
/** Search within node "container" for references for a search value, where the search value is defined as a
* tuple of(searchSymbol, searchText, searchLocation, and searchMeaning).
* searchLocation: a node where the search value
*/
* tuple of(searchSymbol, searchText, searchLocation, and searchMeaning).
* searchLocation: a node where the search value
*/
function getReferencesInNode<T extends DocumentSpan>(container: Node,
searchSymbol: Symbol,
searchText: string,
@@ -701,7 +701,7 @@ namespace ts.FindAllReferences {
}
});
}
};
}
return result;
}
+36 -36
View File
@@ -34,31 +34,31 @@ namespace ts.formatting {
getIndentationForToken(tokenLine: number, tokenKind: SyntaxKind, container: Node): number;
getIndentationForComment(owningToken: SyntaxKind, tokenIndentation: number, container: Node): number;
/**
* Indentation for open and close tokens of the node if it is block or another node that needs special indentation
* ... {
* .........<child>
* ....}
* ____ - indentation
* ____ - delta
**/
* Indentation for open and close tokens of the node if it is block or another node that needs special indentation
* ... {
* .........<child>
* ....}
* ____ - indentation
* ____ - delta
*/
getIndentation(): number;
/**
* Prefered relative indentation for child nodes.
* Delta is used to carry the indentation info
* foo(bar({
* $
* }))
* Both 'foo', 'bar' introduce new indentation with delta = 4, but total indentation in $ is not 8.
* foo: { indentation: 0, delta: 4 }
* bar: { indentation: foo.indentation + foo.delta = 4, delta: 4} however 'foo' and 'bar' are on the same line
* so bar inherits indentation from foo and bar.delta will be 4
*
*/
* Prefered relative indentation for child nodes.
* Delta is used to carry the indentation info
* foo(bar({
* $
* }))
* Both 'foo', 'bar' introduce new indentation with delta = 4, but total indentation in $ is not 8.
* foo: { indentation: 0, delta: 4 }
* bar: { indentation: foo.indentation + foo.delta = 4, delta: 4} however 'foo' and 'bar' are on the same line
* so bar inherits indentation from foo and bar.delta will be 4
*
*/
getDelta(child: TextRangeWithKind): number;
/**
* Formatter calls this function when rule adds or deletes new lines from the text
* so indentation scope can adjust values of indentation and delta.
*/
* Formatter calls this function when rule adds or deletes new lines from the text
* so indentation scope can adjust values of indentation and delta.
*/
recomputeIndentation(lineAddedByFormatting: boolean): void;
}
@@ -205,9 +205,9 @@ namespace ts.formatting {
}
/** formatting is not applied to ranges that contain parse errors.
* This function will return a predicate that for a given text range will tell
* if there are any parse errors that overlap with the range.
*/
* This function will return a predicate that for a given text range will tell
* if there are any parse errors that overlap with the range.
*/
function prepareRangeContainsErrorFunction(errors: Diagnostic[], originalRange: TextRange): (r: TextRange) => boolean {
if (!errors.length) {
return rangeHasNoErrors;
@@ -254,10 +254,10 @@ namespace ts.formatting {
}
/**
* Start of the original range might fall inside the comment - scanner will not yield appropriate results
* This function will look for token that is located before the start of target range
* and return its end as start position for the scanner.
*/
* Start of the original range might fall inside the comment - scanner will not yield appropriate results
* This function will look for token that is located before the start of target range
* and return its end as start position for the scanner.
*/
function getScanStartPosition(enclosingNode: Node, originalRange: TextRange, sourceFile: SourceFile): number {
const start = enclosingNode.getStart(sourceFile);
if (start === originalRange.pos && enclosingNode.end === originalRange.end) {
@@ -388,7 +388,7 @@ namespace ts.formatting {
if (!formattingScanner.isOnToken()) {
const leadingTrivia = formattingScanner.getCurrentLeadingTrivia();
if (leadingTrivia) {
processTrivia(leadingTrivia, enclosingNode, enclosingNode, undefined);
processTrivia(leadingTrivia, enclosingNode, enclosingNode, /*dynamicIndentation*/ undefined);
trimTrailingWhitespacesForRemainingRange();
}
}
@@ -400,12 +400,12 @@ namespace ts.formatting {
// local functions
/** Tries to compute the indentation for a list element.
* If list element is not in range then
* function will pick its actual indentation
* so it can be pushed downstream as inherited indentation.
* If list element is in the range - its indentation will be equal
* to inherited indentation from its predecessors.
*/
* If list element is not in range then
* function will pick its actual indentation
* so it can be pushed downstream as inherited indentation.
* If list element is in the range - its indentation will be equal
* to inherited indentation from its predecessors.
*/
function tryComputeIndentationForListItem(startPos: number,
endPos: number,
parentStartLine: number,
@@ -567,7 +567,7 @@ namespace ts.formatting {
function getEffectiveDelta(delta: number, child: TextRangeWithKind) {
// Delta value should be zero when the node explicitly prevents indentation of the child node
return SmartIndenter.nodeWillIndentChild(node, child, true) ? delta : 0;
return SmartIndenter.nodeWillIndentChild(node, child, /*indentByDefault*/ true) ? delta : 0;
}
}
+2 -2
View File
@@ -297,8 +297,8 @@ namespace ts.formatting {
// Insert a space after { and before } in single-line contexts, but remove space from empty object literals {}.
this.SpaceAfterOpenBrace = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsBraceWrappedContext), RuleAction.Space));
this.SpaceBeforeCloseBrace = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsBraceWrappedContext), RuleAction.Space));
this.NoSpaceAfterOpenBrace = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsBraceWrappedContext), RuleAction.Delete));
this.NoSpaceBeforeCloseBrace = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsBraceWrappedContext), RuleAction.Delete));
this.NoSpaceAfterOpenBrace = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
this.NoSpaceBeforeCloseBrace = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
this.NoSpaceBetweenEmptyBraceBrackets = new Rule(RuleDescriptor.create1(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsObjectContext), RuleAction.Delete));
// Insert new line after { and before } in multi-line contexts.
+1 -1
View File
@@ -18,7 +18,7 @@ namespace ts.GoToImplementation {
else {
// Perform "Find all References" and retrieve only those that are implementations
const referencedSymbols = FindAllReferences.getReferencedSymbolsForNode(context,
node, sourceFiles, /*findInStrings*/false, /*findInComments*/false, /*isForRename*/false, /*implementations*/true);
node, sourceFiles, /*findInStrings*/ false, /*findInComments*/ false, /*isForRename*/ false, /*implementations*/ true);
const result = flatMap(referencedSymbols, symbol => symbol.references);
return result && result.length > 0 ? result : undefined;
+22
View File
@@ -70,6 +70,28 @@ namespace ts.JsDoc {
return documentationComment;
}
export function getJsDocTagsFromDeclarations(declarations: Declaration[]) {
// Only collect doc comments from duplicate declarations once.
const tags: JSDocTagInfo[] = [];
forEachUnique(declarations, declaration => {
const jsDocs = getJSDocs(declaration);
if (!jsDocs) {
return;
}
for (const doc of jsDocs) {
const tagsForDoc = (doc as JSDoc).tags;
if (tagsForDoc) {
tags.push(...tagsForDoc.filter(tag => tag.kind === SyntaxKind.JSDocTag).map(jsDocTag => {
return {
name: jsDocTag.tagName.text,
text: jsDocTag.comment
}; }));
}
}
});
return tags;
}
/**
* Iterates through 'array' by index and performs the callback on each element of array until the callback
* returns a truthy value, then returns that value.
+16 -10
View File
@@ -13,7 +13,7 @@ namespace ts.JsTyping {
fileExists: (fileName: string) => boolean;
readFile: (path: string, encoding?: string) => string;
readDirectory: (rootDir: string, extensions: string[], excludes: string[], includes: string[], depth?: number) => string[];
};
}
interface PackageJson {
_requiredBy?: string[];
@@ -23,7 +23,7 @@ namespace ts.JsTyping {
optionalDependencies?: MapLike<string>;
peerDependencies?: MapLike<string>;
typings?: string;
};
}
// A map of loose file names to library names
// that we are confident require typings
@@ -99,8 +99,11 @@ namespace ts.JsTyping {
const bowerJsonPath = combinePaths(searchDir, "bower.json");
getTypingNamesFromJson(bowerJsonPath, filesToWatch);
const bowerComponentsPath = combinePaths(searchDir, "bower_components");
getTypingNamesFromPackagesFolder(bowerComponentsPath);
const nodeModulesPath = combinePaths(searchDir, "node_modules");
getTypingNamesFromNodeModuleFolder(nodeModulesPath);
getTypingNamesFromPackagesFolder(nodeModulesPath);
}
getTypingNamesFromSourceFileNames(fileNames);
@@ -199,20 +202,23 @@ namespace ts.JsTyping {
}
/**
* Infer typing names from node_module folder
* @param nodeModulesPath is the path to the "node_modules" folder
* Infer typing names from packages folder (ex: node_module, bower_components)
* @param packagesFolderPath is the path to the packages folder
*/
function getTypingNamesFromNodeModuleFolder(nodeModulesPath: string) {
function getTypingNamesFromPackagesFolder(packagesFolderPath: string) {
filesToWatch.push(packagesFolderPath);
// Todo: add support for ModuleResolutionHost too
if (!host.directoryExists(nodeModulesPath)) {
if (!host.directoryExists(packagesFolderPath)) {
return;
}
const typingNames: string[] = [];
const fileNames = host.readDirectory(nodeModulesPath, [".json"], /*excludes*/ undefined, /*includes*/ undefined, /*depth*/ 2);
const fileNames = host.readDirectory(packagesFolderPath, [".json"], /*excludes*/ undefined, /*includes*/ undefined, /*depth*/ 2);
for (const fileName of fileNames) {
const normalizedFileName = normalizePath(fileName);
if (getBaseFileName(normalizedFileName) !== "package.json") {
const baseFileName = getBaseFileName(normalizedFileName);
if (baseFileName !== "package.json" && baseFileName !== "bower.json") {
continue;
}
const result = readConfigFile(normalizedFileName, (path: string) => host.readFile(path));
@@ -224,7 +230,7 @@ namespace ts.JsTyping {
// npm 3's package.json contains a "_requiredBy" field
// we should include all the top level module names for npm 2, and only module names whose
// "_requiredBy" field starts with "#" or equals "/" for npm 3.
if (packageJson._requiredBy &&
if (baseFileName === "package.json" && packageJson._requiredBy &&
filter(packageJson._requiredBy, (r: string) => r[0] === "#" || r === "/").length === 0) {
continue;
}
+55 -35
View File
@@ -2,6 +2,36 @@
/* @internal */
namespace ts.NavigationBar {
/**
* Matches all whitespace characters in a string. Eg:
*
* "app.
*
* onactivated"
*
* matches because of the newline, whereas
*
* "app.onactivated"
*
* does not match.
*/
const whiteSpaceRegex = /\s+/g;
// Keep sourceFile handy so we don't have to search for it every time we need to call `getText`.
let curCancellationToken: CancellationToken;
let curSourceFile: SourceFile;
/**
* For performance, we keep navigation bar parents on a stack rather than passing them through each recursion.
* `parent` is the current parent and is *not* stored in parentsStack.
* `startNode` sets a new parent and `endNode` returns to the previous parent.
*/
let parentsStack: NavigationBarNode[] = [];
let parent: NavigationBarNode;
// NavigationBarItem requires an array, but will not mutate it, so just give it this for performance.
let emptyChildItemArray: NavigationBarItem[] = [];
/**
* Represents a navigation bar item and its children.
* The returned NavigationBarItem is more complicated and doesn't include 'parent', so we use these to do work before converting.
@@ -14,22 +44,36 @@ namespace ts.NavigationBar {
indent: number; // # of parents
}
export function getNavigationBarItems(sourceFile: SourceFile): NavigationBarItem[] {
export function getNavigationBarItems(sourceFile: SourceFile, cancellationToken: CancellationToken): NavigationBarItem[] {
curCancellationToken = cancellationToken;
curSourceFile = sourceFile;
const result = map(topLevelItems(rootNavigationBarNode(sourceFile)), convertToTopLevelItem);
curSourceFile = undefined;
return result;
try {
return map(topLevelItems(rootNavigationBarNode(sourceFile)), convertToTopLevelItem);
}
finally {
reset();
}
}
export function getNavigationTree(sourceFile: SourceFile): NavigationTree {
export function getNavigationTree(sourceFile: SourceFile, cancellationToken: CancellationToken): NavigationTree {
curCancellationToken = cancellationToken;
curSourceFile = sourceFile;
const result = convertToTree(rootNavigationBarNode(sourceFile));
try {
return convertToTree(rootNavigationBarNode(sourceFile));
}
finally {
reset();
}
}
function reset() {
curSourceFile = undefined;
return result;
curCancellationToken = undefined;
parentsStack = [];
parent = undefined;
emptyChildItemArray = [];
}
// Keep sourceFile handy so we don't have to search for it every time we need to call `getText`.
let curSourceFile: SourceFile;
function nodeText(node: Node): string {
return node.getText(curSourceFile);
}
@@ -47,14 +91,6 @@ namespace ts.NavigationBar {
}
}
/*
For performance, we keep navigation bar parents on a stack rather than passing them through each recursion.
`parent` is the current parent and is *not* stored in parentsStack.
`startNode` sets a new parent and `endNode` returns to the previous parent.
*/
const parentsStack: NavigationBarNode[] = [];
let parent: NavigationBarNode;
function rootNavigationBarNode(sourceFile: SourceFile): NavigationBarNode {
Debug.assert(!parentsStack.length);
const root: NavigationBarNode = { node: sourceFile, additionalNodes: undefined, parent: undefined, children: undefined, indent: 0 };
@@ -111,6 +147,8 @@ namespace ts.NavigationBar {
/** Look for navigation bar items in node's subtree, adding them to the current `parent`. */
function addChildrenRecursively(node: Node): void {
curCancellationToken.throwIfCancellationRequested();
if (!node || isToken(node)) {
return;
}
@@ -487,9 +525,6 @@ namespace ts.NavigationBar {
}
}
// NavigationBarItem requires an array, but will not mutate it, so just give it this for performance.
const emptyChildItemArray: NavigationBarItem[] = [];
function convertToTree(n: NavigationBarNode): NavigationTree {
return {
text: getItemName(n.node),
@@ -610,19 +645,4 @@ namespace ts.NavigationBar {
function isFunctionOrClassExpression(node: Node): boolean {
return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction || node.kind === SyntaxKind.ClassExpression;
}
/**
* Matches all whitespace characters in a string. Eg:
*
* "app.
*
* onactivated"
*
* matches because of the newline, whereas
*
* "app.onactivated"
*
* does not match.
*/
const whiteSpaceRegex = /\s+/g;
}
+3 -1
View File
@@ -1,6 +1,6 @@
/* @internal */
namespace ts.OutliningElementsCollector {
export function collectElements(sourceFile: SourceFile): OutliningSpan[] {
export function collectElements(sourceFile: SourceFile, cancellationToken: CancellationToken): OutliningSpan[] {
const elements: OutliningSpan[] = [];
const collapseText = "...";
@@ -38,6 +38,7 @@ namespace ts.OutliningElementsCollector {
let singleLineCommentCount = 0;
for (const currentComment of comments) {
cancellationToken.throwIfCancellationRequested();
// For single line comments, combine consecutive ones (2 or more) into
// a single span from the start of the first till the end of the last
@@ -84,6 +85,7 @@ namespace ts.OutliningElementsCollector {
let depth = 0;
const maxDepth = 20;
function walk(n: Node): void {
cancellationToken.throwIfCancellationRequested();
if (depth > maxDepth) {
return;
}
+7 -7
View File
@@ -12,11 +12,11 @@ namespace ts.Completions.PathCompletions {
const extensions = getSupportedExtensions(compilerOptions);
if (compilerOptions.rootDirs) {
entries = getCompletionEntriesForDirectoryFragmentWithRootDirs(
compilerOptions.rootDirs, literalValue, scriptDirectory, extensions, /*includeExtensions*/false, span, compilerOptions, host, scriptPath);
compilerOptions.rootDirs, literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, span, compilerOptions, host, scriptPath);
}
else {
entries = getCompletionEntriesForDirectoryFragment(
literalValue, scriptDirectory, extensions, /*includeExtensions*/false, span, host, scriptPath);
literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, span, host, scriptPath);
}
}
else {
@@ -94,7 +94,7 @@ namespace ts.Completions.PathCompletions {
if (tryDirectoryExists(host, baseDirectory)) {
// Enumerate the available files if possible
const files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/undefined, /*include*/["./*"]);
const files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/ undefined, /*include*/ ["./*"]);
if (files) {
/**
@@ -153,7 +153,7 @@ namespace ts.Completions.PathCompletions {
const fileExtensions = getSupportedExtensions(compilerOptions);
const projectDir = compilerOptions.project || host.getCurrentDirectory();
const absolute = isRootedDiskPath(baseUrl) ? baseUrl : combinePaths(projectDir, baseUrl);
result = getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/false, span, host);
result = getCompletionEntriesForDirectoryFragment(fragment, normalizePath(absolute), fileExtensions, /*includeExtensions*/ false, span, host);
if (paths) {
for (const path in paths) {
@@ -214,7 +214,7 @@ namespace ts.Completions.PathCompletions {
// doesn't support. For now, this is safer but slower
const includeGlob = normalizedSuffix ? "**/*" : "./*";
const matches = tryReadDirectory(host, baseDirectory, fileExtensions, undefined, [includeGlob]);
const matches = tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]);
if (matches) {
const result: string[] = [];
@@ -267,7 +267,7 @@ namespace ts.Completions.PathCompletions {
nonRelativeModules.push(visibleModule.moduleName);
}
else if (startsWith(visibleModule.moduleName, moduleNameFragment)) {
const nestedFiles = tryReadDirectory(host, visibleModule.moduleDir, supportedTypeScriptExtensions, /*exclude*/undefined, /*include*/["./*"]);
const nestedFiles = tryReadDirectory(host, visibleModule.moduleDir, supportedTypeScriptExtensions, /*exclude*/ undefined, /*include*/ ["./*"]);
if (nestedFiles) {
for (let f of nestedFiles) {
f = normalizePath(f);
@@ -327,7 +327,7 @@ namespace ts.Completions.PathCompletions {
if (kind === "path") {
// Give completions for a relative path
const span: TextSpan = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length);
completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/true, span, host, sourceFile.path);
completionInfo.entries = getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, getSupportedExtensions(compilerOptions), /*includeExtensions*/ true, span, host, sourceFile.path);
}
else {
// Give completions based on the typings available
+69 -12
View File
@@ -302,6 +302,10 @@ namespace ts {
// symbol has no doc comment, then the empty string will be returned.
documentationComment: SymbolDisplayPart[];
// Undefined is used to indicate the value has not been computed. If, after computing, the
// symbol has no JSDoc tags, then the empty array will be returned.
tags: JSDocTagInfo[];
constructor(flags: SymbolFlags, name: string) {
this.flags = flags;
this.name = name;
@@ -326,6 +330,14 @@ namespace ts {
return this.documentationComment;
}
getJsDocTags(): JSDocTagInfo[] {
if (this.tags === undefined) {
this.tags = JsDoc.getJsDocTagsFromDeclarations(this.declarations);
}
return this.tags;
}
}
class TokenObject<TKind extends SyntaxKind> extends TokenOrIdentifierObject implements Token<TKind> {
@@ -415,6 +427,10 @@ namespace ts {
// symbol has no doc comment, then the empty string will be returned.
documentationComment: SymbolDisplayPart[];
// Undefined is used to indicate the value has not been computed. If, after computing, the
// symbol has no doc comment, then the empty array will be returned.
jsDocTags: JSDocTagInfo[];
constructor(checker: TypeChecker) {
this.checker = checker;
}
@@ -438,6 +454,14 @@ namespace ts {
return this.documentationComment;
}
getJsDocTags(): JSDocTagInfo[] {
if (this.jsDocTags === undefined) {
this.jsDocTags = this.declaration ? JsDoc.getJsDocTagsFromDeclarations([this.declaration]) : [];
}
return this.jsDocTags;
}
}
class SourceFileObject extends NodeObject implements SourceFile {
@@ -482,6 +506,7 @@ namespace ts {
public moduleAugmentations: LiteralExpression[];
private namedDeclarations: Map<Declaration[]>;
public ambientModuleNames: string[];
public checkJsDirective: CheckJsDirective | undefined;
constructor(kind: SyntaxKind, pos: number, end: number) {
super(kind, pos, end);
@@ -982,6 +1007,36 @@ namespace ts {
}
}
/* @internal */
/** A cancellation that throttles calls to the host */
export class ThrottledCancellationToken implements CancellationToken {
// Store when we last tried to cancel. Checking cancellation can be expensive (as we have
// to marshall over to the host layer). So we only bother actually checking once enough
// time has passed.
private lastCancellationCheckTime = 0;
constructor(private hostCancellationToken: HostCancellationToken, private readonly throttleWaitMilliseconds = 20) {
}
public isCancellationRequested(): boolean {
const time = timestamp();
const duration = Math.abs(time - this.lastCancellationCheckTime);
if (duration >= this.throttleWaitMilliseconds) {
// Check no more than once every throttle wait milliseconds
this.lastCancellationCheckTime = time;
return this.hostCancellationToken.isCancellationRequested();
}
return false;
}
public throwIfCancellationRequested(): void {
if (this.isCancellationRequested()) {
throw new OperationCanceledException();
}
}
}
export function createLanguageService(host: LanguageServiceHost,
documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory())): LanguageService {
@@ -1330,7 +1385,8 @@ namespace ts {
kindModifiers: ScriptElementKindModifier.none,
textSpan: createTextSpan(node.getStart(), node.getWidth()),
displayParts: typeToDisplayParts(typeChecker, type, getContainerNode(node)),
documentation: type.symbol ? type.symbol.getDocumentationComment() : undefined
documentation: type.symbol ? type.symbol.getDocumentationComment() : undefined,
tags: type.symbol ? type.symbol.getJsDocTags() : undefined
};
}
}
@@ -1344,7 +1400,8 @@ namespace ts {
kindModifiers: SymbolDisplay.getSymbolModifiers(symbol),
textSpan: createTextSpan(node.getStart(), node.getWidth()),
displayParts: displayPartsDocumentationsAndKind.displayParts,
documentation: displayPartsDocumentationsAndKind.documentation
documentation: displayPartsDocumentationsAndKind.documentation,
tags: displayPartsDocumentationsAndKind.tags
};
}
@@ -1416,17 +1473,17 @@ namespace ts {
}
function findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] {
const referencedSymbols = findReferencedSymbols(fileName, position, findInStrings, findInComments, /*isForRename*/true);
const referencedSymbols = findReferencedSymbols(fileName, position, findInStrings, findInComments, /*isForRename*/ true);
return FindAllReferences.convertReferences(referencedSymbols);
}
function getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[] {
const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false, /*isForRename*/false);
const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false, /*isForRename*/ false);
return FindAllReferences.convertReferences(referencedSymbols);
}
function findReferences(fileName: string, position: number): ReferencedSymbol[] {
const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false, /*isForRename*/false);
const referencedSymbols = findReferencedSymbols(fileName, position, /*findInStrings*/ false, /*findInComments*/ false, /*isForRename*/ false);
// Only include referenced symbols that have a valid definition.
return filter(referencedSymbols, rs => !!rs.definition);
}
@@ -1553,11 +1610,11 @@ namespace ts {
}
function getNavigationBarItems(fileName: string): NavigationBarItem[] {
return NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName));
return NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken);
}
function getNavigationTree(fileName: string): NavigationTree {
return NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName));
return NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken);
}
function isTsOrTsxFile(fileName: string): boolean {
@@ -1596,7 +1653,7 @@ namespace ts {
function getOutliningSpans(fileName: string): OutliningSpan[] {
// doesn't use compiler - no need to synchronize with host
const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
return OutliningElementsCollector.collectElements(sourceFile);
return OutliningElementsCollector.collectElements(sourceFile, cancellationToken);
}
function getBraceMatchingAtPosition(fileName: string, position: number) {
@@ -2075,10 +2132,10 @@ namespace ts {
declare const __dirname: string;
/**
* Get the path of the default library files (lib.d.ts) as distributed with the typescript
* node package.
* The functionality is not supported if the ts module is consumed outside of a node module.
*/
* Get the path of the default library files (lib.d.ts) as distributed with the typescript
* node package.
* The functionality is not supported if the ts module is consumed outside of a node module.
*/
export function getDefaultLibFilePath(options: CompilerOptions): string {
// Check __dirname is defined and that we are on a node.js system.
if (typeof __dirname !== "undefined") {
+2 -25
View File
@@ -49,7 +49,7 @@ namespace ts {
error(s: string): void;
}
/** Public interface of the host of a language service shim instance.*/
/** Public interface of the host of a language service shim instance. */
export interface LanguageServiceShimHost extends Logger {
getCompilationSettings(): string;
@@ -469,29 +469,6 @@ namespace ts {
}
}
/** A cancellation that throttles calls to the host */
class ThrottledCancellationToken implements HostCancellationToken {
// Store when we last tried to cancel. Checking cancellation can be expensive (as we have
// to marshall over to the host layer). So we only bother actually checking once enough
// time has passed.
private lastCancellationCheckTime = 0;
constructor(private hostCancellationToken: HostCancellationToken) {
}
public isCancellationRequested(): boolean {
const time = timestamp();
const duration = Math.abs(time - this.lastCancellationCheckTime);
if (duration > 10) {
// Check no more than once every 10 ms.
this.lastCancellationCheckTime = time;
return this.hostCancellationToken.isCancellationRequested();
}
return false;
}
}
export class CoreServicesShimHostAdapter implements ParseConfigHost, ModuleResolutionHost {
public directoryExists: (directoryName: string) => boolean;
@@ -1249,7 +1226,7 @@ namespace ts {
// Here we expose the TypeScript services as an external module
// so that it may be consumed easily like a node module.
declare var module: any;
declare const module: any;
if (typeof module !== "undefined" && module.exports) {
module.exports = ts;
}
+2 -1
View File
@@ -606,7 +606,8 @@ namespace ts.SignatureHelp {
suffixDisplayParts,
separatorDisplayParts: [punctuationPart(SyntaxKind.CommaToken), spacePart()],
parameters: signatureHelpParameters,
documentation: candidateSignature.getDocumentationComment()
documentation: candidateSignature.getDocumentationComment(),
tags: candidateSignature.getJsDocTags()
};
});
+5 -1
View File
@@ -93,6 +93,7 @@ namespace ts.SymbolDisplay {
const displayParts: SymbolDisplayPart[] = [];
let documentation: SymbolDisplayPart[];
let tags: JSDocTagInfo[];
const symbolFlags = symbol.flags;
let symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location);
let hasAddedSymbolInfo: boolean;
@@ -418,6 +419,7 @@ namespace ts.SymbolDisplay {
if (!documentation) {
documentation = symbol.getDocumentationComment();
tags = symbol.getJsDocTags();
if (documentation.length === 0 && symbol.flags & SymbolFlags.Property) {
// For some special property access expressions like `exports.foo = foo` or `module.exports.foo = foo`
// there documentation comments might be attached to the right hand side symbol of their declarations.
@@ -434,6 +436,7 @@ namespace ts.SymbolDisplay {
}
documentation = rhsSymbol.getDocumentationComment();
tags = rhsSymbol.getJsDocTags();
if (documentation.length > 0) {
break;
}
@@ -442,7 +445,7 @@ namespace ts.SymbolDisplay {
}
}
return { displayParts, documentation, symbolKind };
return { displayParts, documentation, symbolKind, tags };
function addNewLineIfDisplayPartsExist() {
if (displayParts.length) {
@@ -500,6 +503,7 @@ namespace ts.SymbolDisplay {
displayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
}
documentation = signature.getDocumentationComment();
tags = signature.getJsDocTags();
}
function writeTypeParametersOfSymbol(symbol: Symbol, enclosingDeclaration: Node) {
+1 -1
View File
@@ -421,7 +421,7 @@ namespace ts.textChanges {
let changesInFile = changesPerFile.get(c.sourceFile.path);
if (!changesInFile) {
changesPerFile.set(c.sourceFile.path, changesInFile = []);
};
}
changesInFile.push(c);
}
// convert changes
+2 -1
View File
@@ -91,6 +91,7 @@
"codefixes/fixes.ts",
"codefixes/helpers.ts",
"codefixes/importFixes.ts",
"codefixes/unusedIdentifierFixes.ts"
"codefixes/unusedIdentifierFixes.ts",
"codefixes/disableJsDiagnostics.ts"
]
}
+18 -8
View File
@@ -27,6 +27,7 @@ namespace ts {
getName(): string;
getDeclarations(): Declaration[];
getDocumentationComment(): SymbolDisplayPart[];
getJsDocTags(): JSDocTagInfo[];
}
export interface Type {
@@ -49,6 +50,7 @@ namespace ts {
getParameters(): Symbol[];
getReturnType(): Type;
getDocumentationComment(): SymbolDisplayPart[];
getJsDocTags(): JSDocTagInfo[];
}
export interface SourceFile {
@@ -519,12 +521,18 @@ namespace ts {
kind: string; // A ScriptElementKind
}
export interface JSDocTagInfo {
name: string;
text?: string;
}
export interface QuickInfo {
kind: string;
kindModifiers: string;
textSpan: TextSpan;
displayParts: SymbolDisplayPart[];
documentation: SymbolDisplayPart[];
tags: JSDocTagInfo[];
}
export interface RenameInfo {
@@ -558,6 +566,7 @@ namespace ts {
separatorDisplayParts: SymbolDisplayPart[];
parameters: SignatureHelpParameter[];
documentation: SymbolDisplayPart[];
tags: JSDocTagInfo[];
}
/**
@@ -588,10 +597,10 @@ namespace ts {
kindModifiers: string; // see ScriptElementKindModifier, comma separated
sortText: string;
/**
* An optional span that indicates the text to be replaced by this completion item. It will be
* set if the required span differs from the one generated by the default replacement behavior and should
* be used in that case
*/
* An optional span that indicates the text to be replaced by this completion item. It will be
* set if the required span differs from the one generated by the default replacement behavior and should
* be used in that case
*/
replacementSpan?: TextSpan;
}
@@ -601,6 +610,7 @@ namespace ts {
kindModifiers: string; // see ScriptElementKindModifier, comma separated
displayParts: SymbolDisplayPart[];
documentation: SymbolDisplayPart[];
tags: JSDocTagInfo[];
}
export interface OutliningSpan {
@@ -614,9 +624,9 @@ namespace ts {
bannerText: string;
/**
* Whether or not this region should be automatically collapsed when
* the 'Collapse to Definitions' command is invoked.
*/
* Whether or not this region should be automatically collapsed when
* the 'Collapse to Definitions' command is invoked.
*/
autoCollapse: boolean;
}
@@ -788,7 +798,7 @@ namespace ts {
/**
* <JsxTagName attribute1 attribute2={0} />
**/
*/
export const jsxAttribute = "JSX attribute";
}
+15 -8
View File
@@ -705,13 +705,13 @@ namespace ts {
}
/**
* The token on the left of the position is the token that strictly includes the position
* or sits to the left of the cursor if it is on a boundary. For example
*
* fo|o -> will return foo
* foo <comment> |bar -> will return foo
*
*/
* The token on the left of the position is the token that strictly includes the position
* or sits to the left of the cursor if it is on a boundary. For example
*
* fo|o -> will return foo
* foo <comment> |bar -> will return foo
*
*/
export function findTokenOnLeftOfPosition(file: SourceFile, position: number): Node {
// Ideally, getTokenAtPosition should return a token. However, it is currently
// broken, so we do a check to make sure the result was indeed a token.
@@ -1334,7 +1334,7 @@ namespace ts {
name.charCodeAt(0) === name.charCodeAt(length - 1) &&
(name.charCodeAt(0) === CharacterCodes.doubleQuote || name.charCodeAt(0) === CharacterCodes.singleQuote)) {
return name.substring(1, length - 1);
};
}
return name;
}
@@ -1380,6 +1380,13 @@ namespace ts {
};
}
export function getFirstNonSpaceCharacterPosition(text: string, position: number) {
while (isWhiteSpace(text.charCodeAt(position))) {
position += 1;
}
return position;
}
export function getOpenBrace(constructor: ConstructorDeclaration, sourceFile: SourceFile) {
// First token is the open curly, this is where we want to put the 'super' call.
return constructor.body.getFirstToken(sourceFile);
@@ -1,5 +1,4 @@
//// [APISample_compile.ts]
/*
* Note: This test is a public API sample. The sample sources can be found
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-minimal-compiler
@@ -35,12 +34,12 @@ compile(process.argv.slice(2), {
});
//// [APISample_compile.js]
"use strict";
/*
* Note: This test is a public API sample. The sample sources can be found
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-minimal-compiler
* Please log a "breaking change" issue for any API breaking change affecting this issue
*/
"use strict";
exports.__esModule = true;
var ts = require("typescript");
function compile(fileNames, options) {
@@ -1,5 +1,4 @@
//// [APISample_linter.ts]
/*
* Note: This test is a public API sample. The sample sources can be found
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#traversing-the-ast-with-a-little-linter
@@ -65,12 +64,12 @@ fileNames.forEach(fileName => {
});
//// [APISample_linter.js]
"use strict";
/*
* Note: This test is a public API sample. The sample sources can be found
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#traversing-the-ast-with-a-little-linter
* Please log a "breaking change" issue for any API breaking change affecting this issue
*/
"use strict";
exports.__esModule = true;
var ts = require("typescript");
function delint(sourceFile) {
@@ -1,5 +1,4 @@
//// [APISample_parseConfig.ts]
/*
* Note: This test is a public API sample. The sample sources can be found
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-minimal-compiler
@@ -37,12 +36,12 @@ export function createProgram(rootFiles: string[], compilerOptionsJson: string):
}
//// [APISample_parseConfig.js]
"use strict";
/*
* Note: This test is a public API sample. The sample sources can be found
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-minimal-compiler
* Please log a "breaking change" issue for any API breaking change affecting this issue
*/
"use strict";
exports.__esModule = true;
var ts = require("typescript");
function printError(error) {
@@ -1,5 +1,4 @@
//// [APISample_transform.ts]
/*
* Note: This test is a public API sample. The sample sources can be found
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-simple-transform-function
@@ -17,12 +16,12 @@ let result = ts.transpile(source, { module: ts.ModuleKind.CommonJS });
console.log(JSON.stringify(result));
//// [APISample_transform.js]
"use strict";
/*
* Note: This test is a public API sample. The sample sources can be found
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-simple-transform-function
* Please log a "breaking change" issue for any API breaking change affecting this issue
*/
"use strict";
exports.__esModule = true;
var ts = require("typescript");
var source = "let x: string = 'string'";
@@ -1,5 +1,4 @@
//// [APISample_watcher.ts]
/*
* Note: This test is a public API sample. The sample sources can be found
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#incremental-build-support-using-the-language-services
@@ -110,12 +109,12 @@ const currentDirectoryFiles = fs.readdirSync(process.cwd()).
watch(currentDirectoryFiles, { module: ts.ModuleKind.CommonJS });
//// [APISample_watcher.js]
"use strict";
/*
* Note: This test is a public API sample. The sample sources can be found
at: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#incremental-build-support-using-the-language-services
* Please log a "breaking change" issue for any API breaking change affecting this issue
*/
"use strict";
exports.__esModule = true;
var ts = require("typescript");
function watch(rootFileNames, options) {
@@ -1,8 +1,7 @@
tests/cases/compiler/DeclarationErrorsNoEmitOnError.ts(4,8): error TS4033: Property 'f' of exported interface has or is using private name 'T'.
tests/cases/compiler/DeclarationErrorsNoEmitOnError.ts(3,8): error TS4033: Property 'f' of exported interface has or is using private name 'T'.
==== tests/cases/compiler/DeclarationErrorsNoEmitOnError.ts (1 errors) ====
type T = { x : number }
export interface I {
f: T;

Some files were not shown because too many files have changed in this diff Show More